Closed4

Redmineのチケット編集時にステータスの一覧に表示されるステータスはどのように決まるか

前田剛前田剛

チケット編集画面でステータス一覧のドロップダウンを表示している箇所。 @allowed_statuses を見ている。

app/views/issues/_attributes.html.erb:

  <%= f.select :status_id, (@allowed_statuses.collect {|p| [p.name, p.id]}), {:required => true},
                :onchange => "updateIssueFrom('#{escape_javascript(update_issue_form_path(@project, @issue))}', this)" %>
前田剛前田剛

@allowed_statuses には Issue#new_statuses_allowed_to の結果がセットされている。

IssuesController#show:

        @allowed_statuses = @issue.new_statuses_allowed_to(User.current)
前田剛前田剛

app/models/issue.rb:

  def new_statuses_allowed_to(user=User.current, include_default=false)
    initial_status = nil
    if new_record?
      # nop
    elsif tracker_id_changed?
      if Tracker.where(:id => tracker_id_was, :default_status_id => status_id_was).any?
        initial_status = default_status
      elsif tracker.issue_status_ids.include?(status_id_was)
        initial_status = IssueStatus.find_by_id(status_id_was)
      else
        initial_status = default_status
      end
    else
      initial_status = status_was
    end

    initial_assigned_to_id = assigned_to_id_changed? ? assigned_to_id_was : assigned_to_id
    assignee_transitions_allowed = initial_assigned_to_id.present? &&
      (user.id == initial_assigned_to_id || user.group_ids.include?(initial_assigned_to_id))

    statuses = []
    statuses += IssueStatus.new_statuses_allowed(
      initial_status,
      user.admin ? Role.all.to_a : user.roles_for_project(project),
      tracker,
      author == user,
      assignee_transitions_allowed
    )
    statuses << initial_status unless statuses.empty?
    statuses << default_status if include_default || (new_record? && statuses.empty?)

    statuses = statuses.compact.uniq.sort
    unless closable?
      # cannot close a blocked issue or a parent with open subtasks
      statuses.reject!(&:is_closed?)
    end
    unless reopenable?
      # cannot reopen a subtask of a closed parent
      statuses.select!(&:is_closed?)
    end
    statuses
  end
前田剛前田剛

もしシステム管理者権限有りのユーザーであれば、Redmine上の全ロール(Role.all.to_a)でプロジェクトに参加していると見なされる。そのユーザーのプロジェクトにおけるロールで許可されていない遷移も表示されることになるので、意図しないステータス遷移ができてしまう場合がある。

    statuses += IssueStatus.new_statuses_allowed(
      initial_status,
      user.admin ? Role.all.to_a : user.roles_for_project(project),
      tracker,
      author == user,
      assignee_transitions_allowed
    )
このスクラップは2021/02/05にクローズされました