summaryrefslogtreecommitdiff
path: root/app/services/members/create_service.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/services/members/create_service.rb')
-rw-r--r--app/services/members/create_service.rb111
1 files changed, 71 insertions, 40 deletions
diff --git a/app/services/members/create_service.rb b/app/services/members/create_service.rb
index cffccda1a44..953cf7f5bf6 100644
--- a/app/services/members/create_service.rb
+++ b/app/services/members/create_service.rb
@@ -2,67 +2,98 @@
module Members
class CreateService < Members::BaseService
- include Gitlab::Utils::StrongMemoize
+ BlankInvitesError = Class.new(StandardError)
+ TooManyInvitesError = Class.new(StandardError)
- DEFAULT_LIMIT = 100
+ DEFAULT_INVITE_LIMIT = 100
- def execute(source)
- return error(s_('AddMember|No users specified.')) if user_ids.blank?
+ def initialize(*args)
+ super
- return error(s_("AddMember|Too many users specified (limit is %{user_limit})") % { user_limit: user_limit }) if
- user_limit && user_ids.size > user_limit
+ @errors = []
+ @invites = invites_from_params&.split(',')&.uniq&.flatten
+ @source = params[:source]
+ end
+
+ def execute
+ validate_invites!
+
+ add_members
+ enqueue_onboarding_progress_action
+ result
+ rescue BlankInvitesError, TooManyInvitesError => e
+ error(e.message)
+ end
+
+ private
+
+ attr_reader :source, :errors, :invites, :member_created_namespace_id
+
+ def invites_from_params
+ params[:user_ids]
+ end
+
+ def validate_invites!
+ raise BlankInvitesError, blank_invites_message if invites.blank?
+
+ return unless user_limit && invites.size > user_limit
+
+ raise TooManyInvitesError,
+ format(s_("AddMember|Too many users specified (limit is %{user_limit})"), user_limit: user_limit)
+ end
+
+ def blank_invites_message
+ s_('AddMember|No users specified.')
+ end
+ def add_members
members = source.add_users(
- user_ids,
+ invites,
params[:access_level],
expires_at: params[:expires_at],
current_user: current_user
)
- errors = []
-
- members.each do |member|
- if member.invalid?
- current_error =
- # Invited users may not have an associated user
- if member.user.present?
- "#{member.user.username}: "
- else
- ""
- end
-
- current_error += member.errors.full_messages.to_sentence
- errors << current_error
- else
- after_execute(member: member)
- end
- end
-
- enqueue_onboarding_progress_action(source) if members.size > errors.size
-
- return success unless errors.any?
+ members.each { |member| process_result(member) }
+ end
- error(errors.to_sentence)
+ def process_result(member)
+ if member.invalid?
+ add_error_for_member(member)
+ else
+ after_execute(member: member)
+ @member_created_namespace_id ||= member.namespace_id
+ end
end
- private
+ def add_error_for_member(member)
+ prefix = "#{member.user.username}: " if member.user.present?
- def user_ids
- strong_memoize(:user_ids) do
- ids = params[:user_ids] || ''
- ids.split(',').uniq.flatten
- end
+ errors << "#{prefix}#{member.errors.full_messages.to_sentence}"
end
def user_limit
- limit = params.fetch(:limit, DEFAULT_LIMIT)
+ limit = params.fetch(:limit, DEFAULT_INVITE_LIMIT)
limit && limit < 0 ? nil : limit
end
- def enqueue_onboarding_progress_action(source)
- namespace_id = source.is_a?(Project) ? source.namespace_id : source.id
- Namespaces::OnboardingUserAddedWorker.perform_async(namespace_id)
+ def enqueue_onboarding_progress_action
+ return unless member_created_namespace_id
+
+ Namespaces::OnboardingUserAddedWorker.perform_async(member_created_namespace_id)
+ end
+
+ def result
+ if errors.any?
+ error(formatted_errors)
+ else
+ success
+ end
+ end
+
+ def formatted_errors
+ errors.to_sentence
end
end
end