projects_finder.rb 1.7 KB
Newer Older
1
class ProjectsFinder
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
  # Returns all projects, optionally including group projects a user has access
  # to.
  #
  # ## Examples
  #
  # Retrieving all public projects:
  #
  #     ProjectsFinder.new.execute
  #
  # Retrieving all public/internal projects and those the given user has access
  # to:
  #
  #     ProjectsFinder.new.execute(some_user)
  #
  # Retrieving all public/internal projects as well as the group's projects the
  # user has access to:
  #
  #     ProjectsFinder.new.execute(some_user, group: some_group)
  #
  # Returns an ActiveRecord::Relation.
  def execute(current_user = nil, options = {})
23 24 25
    group = options[:group]

    if group
26
      base, extra = group_projects(current_user, group)
27
    else
28 29 30 31 32 33 34 35 36
      base, extra = all_projects(current_user)
    end

    if base and extra
      union = Gitlab::SQL::Union.new([base.select(:id), extra.select(:id)])

      Project.where("projects.id IN (#{union.to_sql})")
    else
      base
37 38 39 40 41 42 43
    end
  end

  private

  def group_projects(current_user, group)
    if current_user
44 45 46 47
      [
        group_projects_for_user(current_user, group),
        group.projects.public_and_internal_only
      ]
48
    else
49
      [group.projects.public_only]
50 51 52
    end
  end

53 54
  def all_projects(current_user)
    if current_user
55
      [current_user.authorized_projects, public_and_internal_projects]
56
    else
57
      [Project.public_only]
58
    end
59
  end
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75

  def group_projects_for_user(current_user, group)
    if group.users.include?(current_user)
      group.projects
    else
      group.projects.visible_to_user(current_user)
    end
  end

  def public_projects
    Project.unscoped.public_only
  end

  def public_and_internal_projects
    Project.unscoped.public_and_internal_only
  end
76
end