diff options
Diffstat (limited to 'app/services/users')
-rw-r--r-- | app/services/users/activity_service.rb | 4 | ||||
-rw-r--r-- | app/services/users/authorized_build_service.rb | 18 | ||||
-rw-r--r-- | app/services/users/authorized_create_service.rb | 14 | ||||
-rw-r--r-- | app/services/users/build_service.rb | 187 | ||||
-rw-r--r-- | app/services/users/create_service.rb | 9 | ||||
-rw-r--r-- | app/services/users/refresh_authorized_projects_service.rb | 9 | ||||
-rw-r--r-- | app/services/users/registrations_build_service.rb | 7 | ||||
-rw-r--r-- | app/services/users/update_assigned_open_issue_count_service.rb | 33 |
8 files changed, 154 insertions, 127 deletions
diff --git a/app/services/users/activity_service.rb b/app/services/users/activity_service.rb index c89a286cc8b..20594bec28d 100644 --- a/app/services/users/activity_service.rb +++ b/app/services/users/activity_service.rb @@ -17,7 +17,7 @@ module Users def execute return unless @user - record_activity + ::Gitlab::Database::LoadBalancing::Session.without_sticky_writes { record_activity } end private @@ -37,5 +37,3 @@ module Users end end end - -Users::ActivityService.prepend_mod diff --git a/app/services/users/authorized_build_service.rb b/app/services/users/authorized_build_service.rb new file mode 100644 index 00000000000..eb2386198d3 --- /dev/null +++ b/app/services/users/authorized_build_service.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module Users + class AuthorizedBuildService < BuildService + extend ::Gitlab::Utils::Override + + private + + override :validate_access! + def validate_access! + # no-op + end + + def signup_params + super + [:skip_confirmation] + end + end +end diff --git a/app/services/users/authorized_create_service.rb b/app/services/users/authorized_create_service.rb new file mode 100644 index 00000000000..b6109f0c191 --- /dev/null +++ b/app/services/users/authorized_create_service.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Users + class AuthorizedCreateService < CreateService + extend ::Gitlab::Utils::Override + + private + + override :build_class + def build_class + Users::AuthorizedBuildService + end + end +end diff --git a/app/services/users/build_service.rb b/app/services/users/build_service.rb index 649cf281ab0..ddb20a835e1 100644 --- a/app/services/users/build_service.rb +++ b/app/services/users/build_service.rb @@ -5,7 +5,6 @@ module Users delegate :user_default_internal_regex_enabled?, :user_default_internal_regex_instance, to: :'Gitlab::CurrentSettings.current_application_settings' - attr_reader :identity_params def initialize(current_user, params = {}) @current_user = current_user @@ -13,46 +12,128 @@ module Users @identity_params = params.slice(*identity_attributes) end - def execute(skip_authorization: false) - @skip_authorization = skip_authorization + def execute + build_user + build_identity + update_canonical_email - raise Gitlab::Access::AccessDeniedError unless skip_authorization || can_create_user? + user + end - user_params = build_user_params - user = User.new(user_params) + private - if current_user&.admin? - @reset_token = user.generate_reset_token if params[:reset_password] + attr_reader :identity_params, :user_params, :user - if user_params[:force_random_password] - random_password = User.random_password - user.password = user.password_confirmation = random_password - end + def identity_attributes + [:extern_uid, :provider] + end + + def build_user + if admin? + admin_build_user + else + standard_build_user end + end - build_identity(user) + def admin? + return false unless current_user - Users::UpdateCanonicalEmailService.new(user: user).execute + current_user.admin? + end - user + def admin_build_user + build_user_params_for_admin + init_user + password_reset end - private + def standard_build_user + # current_user non admin or nil + validate_access! + build_user_params_for_non_admin + init_user + end - attr_reader :skip_authorization + def build_user_params_for_admin + @user_params = params.slice(*admin_create_params) + @user_params.merge!(force_random_password: true, password_expires_at: nil) if params[:reset_password] + end - def identity_attributes - [:extern_uid, :provider] + def init_user + assign_common_user_params + + @user = User.new(user_params) + end + + def assign_common_user_params + @user_params[:created_by_id] = current_user&.id + @user_params[:external] = user_external? if set_external_param? + + @user_params.delete(:user_type) unless project_bot? + end + + def set_external_param? + user_default_internal_regex_enabled? && !user_params.key?(:external) + end + + def user_external? + user_default_internal_regex_instance.match(params[:email]).nil? + end + + def project_bot? + user_params[:user_type]&.to_sym == :project_bot + end + + def password_reset + @reset_token = user.generate_reset_token if params[:reset_password] + + if user_params[:force_random_password] + random_password = User.random_password + @user.password = user.password_confirmation = random_password + end + end + + def validate_access! + return if can_create_user? + + raise Gitlab::Access::AccessDeniedError + end + + def can_create_user? + current_user.nil? && Gitlab::CurrentSettings.allow_signup? + end + + def build_user_params_for_non_admin + @user_params = params.slice(*signup_params) + @user_params[:skip_confirmation] = skip_user_confirmation_email_from_setting if assign_skip_confirmation_from_settings? + @user_params[:name] = fallback_name if use_fallback_name? + end + + def assign_skip_confirmation_from_settings? + user_params[:skip_confirmation].nil? end - def build_identity(user) + def skip_user_confirmation_email_from_setting + !Gitlab::CurrentSettings.send_user_confirmation_email + end + + def use_fallback_name? + user_params[:name].blank? && fallback_name.present? + end + + def fallback_name + "#{user_params[:first_name]} #{user_params[:last_name]}" + end + + def build_identity return if identity_params.empty? user.identities.build(identity_params) end - def can_create_user? - (current_user.nil? && Gitlab::CurrentSettings.allow_signup?) || current_user&.admin? + def update_canonical_email + Users::UpdateCanonicalEmailService.new(user: user).execute end # Allowed params for creating a user (admins only) @@ -96,69 +177,15 @@ module Users def signup_params [ :email, - :password_automatically_set, :name, - :first_name, - :last_name, :password, + :password_automatically_set, :username, - :user_type + :user_type, + :first_name, + :last_name ] end - - def build_user_params - if current_user&.admin? - user_params = params.slice(*admin_create_params) - - if params[:reset_password] - user_params.merge!(force_random_password: true, password_expires_at: nil) - end - else - allowed_signup_params = signup_params - allowed_signup_params << :skip_confirmation if allow_caller_to_request_skip_confirmation? - - user_params = params.slice(*allowed_signup_params) - if assign_skip_confirmation_from_settings?(user_params) - user_params[:skip_confirmation] = skip_user_confirmation_email_from_setting - end - - fallback_name = "#{user_params[:first_name]} #{user_params[:last_name]}" - - if user_params[:name].blank? && fallback_name.present? - user_params = user_params.merge(name: fallback_name) - end - end - - user_params[:created_by_id] = current_user&.id - - if user_default_internal_regex_enabled? && !user_params.key?(:external) - user_params[:external] = user_external? - end - - user_params.delete(:user_type) unless project_bot?(user_params[:user_type]) - - user_params - end - - def allow_caller_to_request_skip_confirmation? - skip_authorization - end - - def assign_skip_confirmation_from_settings?(user_params) - user_params[:skip_confirmation].nil? - end - - def skip_user_confirmation_email_from_setting - !Gitlab::CurrentSettings.send_user_confirmation_email - end - - def user_external? - user_default_internal_regex_instance.match(params[:email]).nil? - end - - def project_bot?(user_type) - user_type&.to_sym == :project_bot - end end end diff --git a/app/services/users/create_service.rb b/app/services/users/create_service.rb index 757ebd783ee..591d88b275e 100644 --- a/app/services/users/create_service.rb +++ b/app/services/users/create_service.rb @@ -9,8 +9,8 @@ module Users @params = params.dup end - def execute(skip_authorization: false) - user = Users::BuildService.new(current_user, params).execute(skip_authorization: skip_authorization) + def execute + user = build_class.new(current_user, params).execute reset_token = user.generate_reset_token if user.recently_sent_password_reset? after_create_hook(user, reset_token) if user.save @@ -23,6 +23,11 @@ module Users def after_create_hook(user, reset_token) notify_new_user(user, reset_token) end + + def build_class + # overridden by inheriting classes + Users::BuildService + end end end diff --git a/app/services/users/refresh_authorized_projects_service.rb b/app/services/users/refresh_authorized_projects_service.rb index d28ff45bfdf..1850fa9747d 100644 --- a/app/services/users/refresh_authorized_projects_service.rb +++ b/app/services/users/refresh_authorized_projects_service.rb @@ -24,11 +24,6 @@ module Users @source = source @incorrect_auth_found_callback = incorrect_auth_found_callback @missing_auth_found_callback = missing_auth_found_callback - - # We need an up to date User object that has access to all relations that - # may have been created earlier. The only way to ensure this is to reload - # the User object. - user.reset end def execute @@ -43,6 +38,10 @@ module Users end begin + # We need an up to date User object that has access to all relations that + # may have been created earlier. The only way to ensure this is to reload + # the User object. + user.reset execute_without_lease ensure Gitlab::ExclusiveLease.cancel(lease_key, uuid) diff --git a/app/services/users/registrations_build_service.rb b/app/services/users/registrations_build_service.rb index 9d7bf0a7e18..2d367e7b185 100644 --- a/app/services/users/registrations_build_service.rb +++ b/app/services/users/registrations_build_service.rb @@ -6,13 +6,12 @@ module Users private - override :allow_caller_to_request_skip_confirmation? - def allow_caller_to_request_skip_confirmation? - true + def signup_params + super + [:skip_confirmation] end override :assign_skip_confirmation_from_settings? - def assign_skip_confirmation_from_settings?(user_params) + def assign_skip_confirmation_from_settings? user_params[:skip_confirmation].blank? end end diff --git a/app/services/users/update_assigned_open_issue_count_service.rb b/app/services/users/update_assigned_open_issue_count_service.rb deleted file mode 100644 index 2ed05853b2f..00000000000 --- a/app/services/users/update_assigned_open_issue_count_service.rb +++ /dev/null @@ -1,33 +0,0 @@ -# frozen_string_literal: true - -module Users - # Service class for calculating and caching the number of assigned open issues for a user. - class UpdateAssignedOpenIssueCountService - attr_accessor :target_user - - def initialize(target_user:) - @target_user = target_user - - raise ArgumentError, "Please provide a target user" unless target_user.is_a?(User) - end - - def execute - value = calculate_count - Rails.cache.write(cache_key, value, expires_in: User::COUNT_CACHE_VALIDITY_PERIOD) - - ServiceResponse.success(payload: { count: value }) - rescue StandardError => e - ServiceResponse.error(message: e.message) - end - - private - - def cache_key - ['users', target_user.id, 'assigned_open_issues_count'] - end - - def calculate_count - IssuesFinder.new(target_user, assignee_id: target_user.id, state: 'opened', non_archived: true).execute.count - end - end -end |