diff options
Diffstat (limited to 'app/services/members/creator_service.rb')
-rw-r--r-- | app/services/members/creator_service.rb | 98 |
1 files changed, 41 insertions, 57 deletions
diff --git a/app/services/members/creator_service.rb b/app/services/members/creator_service.rb index 276093a00a9..f59a3ed77eb 100644 --- a/app/services/members/creator_service.rb +++ b/app/services/members/creator_service.rb @@ -13,9 +13,9 @@ module Members Gitlab::Access.sym_options_with_owner end - def add_users( # rubocop:disable Metrics/ParameterLists + def add_members( # rubocop:disable Metrics/ParameterLists source, - users, + invitees, access_level, current_user: nil, expires_at: nil, @@ -24,41 +24,49 @@ module Members ldap: nil, blocking_refresh: nil ) - return [] unless users.present? + return [] unless invitees.present? # If this user is attempting to manage Owner members and doesn't have permission, do not allow return [] if managing_owners?(current_user, access_level) && cannot_manage_owners?(source, current_user) - emails, users, existing_members = parse_users_list(source, users) + emails, users, existing_members = parse_users_list(source, invitees) Member.transaction do - (emails + users).map! do |user| - new(source, - user, - access_level, - existing_members: existing_members, - current_user: current_user, - expires_at: expires_at, - tasks_to_be_done: tasks_to_be_done, - tasks_project_id: tasks_project_id, - ldap: ldap, - blocking_refresh: blocking_refresh) - .execute + common_arguments = { + source: source, + access_level: access_level, + existing_members: existing_members, + current_user: current_user, + expires_at: expires_at, + tasks_to_be_done: tasks_to_be_done, + tasks_project_id: tasks_project_id, + ldap: ldap, + blocking_refresh: blocking_refresh + } + + 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 - def add_user( # rubocop:disable Metrics/ParameterLists + def add_member( # rubocop:disable Metrics/ParameterLists source, - user, + invitee, access_level, current_user: nil, expires_at: nil, ldap: nil, blocking_refresh: nil ) - add_users(source, - [user], + add_members(source, + [invitee], access_level, current_user: current_user, expires_at: expires_at, @@ -113,11 +121,11 @@ module Members end end - def initialize(source, user, access_level, **args) - @source = source - @user = user - @access_level = self.class.parsed_access_level(access_level) + def initialize(invitee:, builder: StandardMemberBuilder, **args) + @invitee = invitee + @builder = builder @args = args + @access_level = self.class.parsed_access_level(args[:access_level]) end private_class_method :new @@ -133,7 +141,7 @@ module Members private delegate :new_record?, to: :member - attr_reader :source, :user, :access_level, :member, :args + attr_reader :invitee, :access_level, :member, :args, :builder def assign_member_attributes member.attributes = member_attributes @@ -170,7 +178,7 @@ module Members # Populates the attributes of a member. # # This logic resides in a separate method so that EE can extend this logic, - # without having to patch the `add_user` method directly. + # without having to patch the `add_members` method directly. def member_attributes { created_by: member.created_by || current_user, @@ -182,14 +190,14 @@ module Members def commit_changes if member.request? approve_request - else + elsif member.changed? # Calling #save triggers callbacks even if there is no change on object. # This previously caused an incident due to the hard to predict # behaviour caused by the large number of callbacks. # See https://gitlab.com/gitlab-com/gl-infra/production/-/issues/6351 # and https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80920#note_911569038 # for details. - member.save if member.changed? + member.save end end @@ -241,43 +249,19 @@ module Members end def find_or_build_member - @user = parse_user_param - - @member = if user.is_a?(User) - find_or_initialize_member_by_user - else - source.members.build(invite_email: user) - end + @member = builder.new(source, invitee, existing_members).execute @member.blocking_refresh = args[:blocking_refresh] end - # This method is used to find users that have been entered into the "Add members" field. - # These can be the User objects directly, their IDs, their emails, or new emails to be invited. - def parse_user_param - case user - when User - user - when Integer - # might not return anything - this needs enhancement - User.find_by(id: user) # rubocop:todo CodeReuse/ActiveRecord - else - # must be an email or at least we'll consider it one - source.users_by_emails([user])[user] || user - end - end - - def find_or_initialize_member_by_user - # We have to use `members_and_requesters` here since the given `members` is modified in the models - # to act more like a scope(removing the requested_at members) and therefore ActiveRecord has issues with that - # on build and refreshing that relation. - existing_members[user.id] || source.members_and_requesters.build(user_id: user.id) # rubocop:disable CodeReuse/ActiveRecord - end - def ldap args[:ldap] || false end + def source + args[:source] + end + def existing_members args[:existing_members] || {} end |