Class: Members::CreatorService

Inherits:
Object
  • Object
show all
Defined in:
app/services/members/creator_service.rb

Overview

This class serves as more of an app-wide way we add/create members All roads to add members should take this path.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(invitee:, builder: StandardMemberBuilder, **args) ⇒ CreatorService

Returns a new instance of CreatorService.



134
135
136
137
138
139
# File 'app/services/members/creator_service.rb', line 134

def initialize(invitee:, builder: StandardMemberBuilder, **args)
  @invitee = invitee
  @builder = builder
  @args = args
  @access_level = self.class.parsed_access_level(args[:access_level])
end

Class Method Details

.access_levelsObject



12
13
14
# File 'app/services/members/creator_service.rb', line 12

def access_levels
  Gitlab::Access.sym_options_with_owner
end

.add_member(source, invitee, access_level, **args) ⇒ Object



74
75
76
# File 'app/services/members/creator_service.rb', line 74

def add_member(source, invitee, access_level, **args)
  add_members(source, [invitee], access_level, **args).first
end

.add_members(sources, invitees, access_level, **args) ⇒ Object

Add members to sources with passed access option

access can be an integer representing a access code or symbol like :maintainer representing role

Ex.

add_members(
  sources,
  user_ids,
  Member::MAINTAINER
)

add_members(
  sources,
  user_ids,
  :maintainer
)

Project::ActiveRecord_Relation] - Can’t be an array of source ids because we don’t know the type of source.

Parameters:

  • sources (Group, Project, Array<Group>, Array<Project>, Group::ActiveRecord_Relation, )

    ources [Group, Project, Array<Group>, Array<Project>, Group::ActiveRecord_Relation,



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
65
66
67
68
69
70
71
72
# File 'app/services/members/creator_service.rb', line 37

def add_members(sources, invitees, access_level, **args)
  return [] unless invitees.present?

  sources = Array.wrap(sources) if sources.is_a?(ApplicationRecord) # For single source

  Gitlab::Database::QueryAnalyzers::PreventCrossDatabaseModification.temporary_ignore_tables_in_transaction(
    %w[users user_preferences user_details emails identities], url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/424276'
  ) do
    Member.transaction do
      sources.flat_map do |source|
        # If this user is attempting to manage Owner members and doesn't have permission, do not allow
        current_user = args[:current_user]
        next [] if managing_owners?(current_user, access_level) && cannot_manage_owners?(source, current_user)

        emails, users, existing_members = parse_users_list(source, invitees)

        common_arguments = {
          source: source,
          access_level: access_level,
          existing_members: existing_members,
          tasks_to_be_done: args[:tasks_to_be_done] || []
        }.merge(parsed_args(args))

        members = emails.map do |email|
          new(invitee: email, builder: InviteMemberBuilder, **common_arguments).execute
        end

        members += users.map do |user|
          new(invitee: user, **common_arguments).execute
        end

        members
      end
    end
  end
end

.parsed_access_level(access_level) ⇒ Object



8
9
10
# File 'app/services/members/creator_service.rb', line 8

def parsed_access_level(access_level)
  access_levels.fetch(access_level) { access_level.to_i }
end

Instance Method Details

#executeObject



143
144
145
146
147
148
149
# File 'app/services/members/creator_service.rb', line 143

def execute
  find_or_build_member
  commit_member
  after_commit_tasks

  member
end