summaryrefslogtreecommitdiff
path: root/app/finders/groups/accepting_group_transfers_finder.rb
blob: c95318d0098163af64540328ea5d43613f5b7560 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# frozen_string_literal: true

module Groups
  class AcceptingGroupTransfersFinder < Base
    include Gitlab::Utils::StrongMemoize

    def initialize(current_user, group_to_be_transferred, params = {})
      @current_user = current_user
      @group_to_be_transferred = group_to_be_transferred
      @params = params
    end

    def execute
      return Group.none unless can_transfer_group?

      items = find_all_groups
      items = by_search(items)

      sort(items)
    end

    private

    attr_reader :current_user, :group_to_be_transferred, :params

    def find_groups
      GroupsFinder.new( # rubocop: disable CodeReuse/Finder
        current_user,
        min_access_level: Gitlab::Access::OWNER,
        exclude_group_ids: exclude_groups
      ).execute.without_order
    end

    def find_all_groups
      ::Namespace.from_union(
        [
          find_groups,
          groups_originating_from_group_shares_with_owner_access
        ]
      )
    end

    def groups_originating_from_group_shares_with_owner_access
      GroupGroupLink
        .with_owner_access
        .groups_accessible_via(
          current_user.owned_groups.select(:id)
        ).id_not_in(exclude_groups)
    end

    def exclude_groups
      strong_memoize(:exclude_groups) do
        exclude_groups = group_to_be_transferred.self_and_descendants.pluck_primary_key
        exclude_groups << group_to_be_transferred.parent_id if group_to_be_transferred.parent_id

        exclude_groups
      end
    end

    def can_transfer_group?
      Ability.allowed?(current_user, :admin_group, group_to_be_transferred)
    end
  end
end