summaryrefslogtreecommitdiff
path: root/app/services/members/projects/creator_service.rb
blob: f45132749f9812690312bfacf88b669650d7dbff (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
# frozen_string_literal: true

module Members
  module Projects
    class CreatorService < Members::CreatorService
      class << self
        def cannot_manage_owners?(source, current_user)
          !Ability.allowed?(current_user, :manage_owners, source)
        end
      end

      private

      def can_create_new_member?
        return false if assigning_project_member_with_owner_access_level? &&
          cannot_assign_owner_responsibilities_to_member_in_project?

        # This access check(`admin_project_member`) will write to safe request store cache for the user being added.
        # This means any operations inside the same request will need to purge that safe request
        # store cache if operations are needed to be done inside the same request that checks max member access again on
        # that user.
        current_user.can?(:admin_project_member, member.project) || adding_the_creator_as_owner_in_a_personal_project?
      end

      def can_update_existing_member?
        # rubocop:disable Layout/EmptyLineAfterGuardClause
        raise ::Gitlab::Access::AccessDeniedError if assigning_project_member_with_owner_access_level? &&
          cannot_assign_owner_responsibilities_to_member_in_project?
        # rubocop:enable Layout/EmptyLineAfterGuardClause

        current_user.can?(:update_project_member, member)
      end

      def adding_the_creator_as_owner_in_a_personal_project?
        # this condition is reached during testing setup a lot due to use of `.add_member`
        member.project.personal_namespace_holder?(member.user)
      end

      def assigning_project_member_with_owner_access_level?
        return true if member && member.owner?

        access_level == Gitlab::Access::OWNER
      end

      def cannot_assign_owner_responsibilities_to_member_in_project?
        member.is_a?(ProjectMember) && !current_user.can?(:manage_owners, member.source)
      end
    end
  end
end