2021-01-29 00:20:46 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
module Members
|
2021-04-29 21:17:54 +05:30
|
|
|
class InviteService < Members::CreateService
|
|
|
|
extend ::Gitlab::Utils::Override
|
2021-01-29 00:20:46 +05:30
|
|
|
|
2021-04-17 20:07:23 +05:30
|
|
|
def initialize(*args)
|
|
|
|
super
|
2021-01-29 00:20:46 +05:30
|
|
|
|
2022-06-21 17:19:12 +05:30
|
|
|
@invites += parsed_emails
|
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
@errors = {}
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
2021-04-29 21:17:54 +05:30
|
|
|
alias_method :formatted_errors, :errors
|
2021-01-29 00:20:46 +05:30
|
|
|
|
2022-06-21 17:19:12 +05:30
|
|
|
def parsed_emails
|
|
|
|
# can't put this in the initializer since `invites_from_params` is called in super class
|
|
|
|
# and needs it
|
|
|
|
@parsed_emails ||= (formatted_param(params[:email]) || [])
|
|
|
|
end
|
|
|
|
|
|
|
|
def formatted_param(parameter)
|
|
|
|
parameter&.split(',')&.uniq&.flatten
|
2021-01-29 00:20:46 +05:30
|
|
|
end
|
|
|
|
|
2021-11-11 11:23:49 +05:30
|
|
|
def validate_invitable!
|
2021-04-29 21:17:54 +05:30
|
|
|
super
|
2021-01-29 00:20:46 +05:30
|
|
|
|
2022-06-21 17:19:12 +05:30
|
|
|
return if params[:email].blank?
|
|
|
|
|
2022-08-13 15:12:31 +05:30
|
|
|
# we need the below due to add_member hitting Members::CreatorService.parse_users_list and ignoring invalid emails
|
|
|
|
# ideally we wouldn't need this, but we can't really change the add_members method
|
2022-06-21 17:19:12 +05:30
|
|
|
invalid_emails.each { |email| errors[email] = s_('AddMember|Invite email is invalid') }
|
|
|
|
end
|
|
|
|
|
|
|
|
def invalid_emails
|
|
|
|
parsed_emails.each_with_object([]) do |email, invalid|
|
|
|
|
next if Member.valid_email?(email)
|
2021-01-29 00:20:46 +05:30
|
|
|
|
2022-06-21 17:19:12 +05:30
|
|
|
invalid << email
|
|
|
|
@invites.delete(email)
|
|
|
|
end
|
2021-01-29 00:20:46 +05:30
|
|
|
end
|
|
|
|
|
2021-04-29 21:17:54 +05:30
|
|
|
override :blank_invites_message
|
|
|
|
def blank_invites_message
|
2022-06-21 17:19:12 +05:30
|
|
|
s_('AddMember|Invites cannot be blank')
|
2021-01-29 00:20:46 +05:30
|
|
|
end
|
|
|
|
|
2021-04-29 21:17:54 +05:30
|
|
|
override :add_error_for_member
|
2022-06-21 17:19:12 +05:30
|
|
|
def add_error_for_member(member, existing_errors)
|
|
|
|
errors[invited_object(member)] = all_member_errors(member, existing_errors).to_sentence
|
2021-01-29 00:20:46 +05:30
|
|
|
end
|
|
|
|
|
2022-06-21 17:19:12 +05:30
|
|
|
def invited_object(member)
|
|
|
|
return member.invite_email if member.invite_email
|
2021-12-11 22:18:48 +05:30
|
|
|
|
2022-06-21 17:19:12 +05:30
|
|
|
# There is a case where someone was invited by email, but the `user` record exists.
|
|
|
|
# The member record returned will not have an invite_email attribute defined since
|
|
|
|
# the CreatorService finds `user` record sometimes by email.
|
|
|
|
# At that point we lose the info of whether this invite was done by `user` or by email.
|
|
|
|
# Here we will give preference to check invites by user_id first.
|
|
|
|
# There is also a case where a user could be invited by their email and
|
|
|
|
# at the same time via the API in the same request.
|
|
|
|
# This would would mean the same user is invited as user_id and email.
|
|
|
|
# However, that isn't as likely from the UI at least since the token generator checks
|
|
|
|
# for that case and doesn't allow email being used if the user exists as a record already.
|
|
|
|
if member.user_id.to_s.in?(invites)
|
|
|
|
member.user.username
|
|
|
|
else
|
|
|
|
member.user.all_emails.detect { |email| email.in?(invites) }
|
|
|
|
end
|
2021-01-29 00:20:46 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|