Merge branch '30349-create-users-build-service' into 'master'
Implement Users::BuildService Closes #30349 See merge request !10675
This commit is contained in:
commit
819b715357
7 changed files with 175 additions and 159 deletions
|
@ -60,7 +60,7 @@ class RegistrationsController < Devise::RegistrationsController
|
|||
end
|
||||
|
||||
def resource
|
||||
@resource ||= Users::CreateService.new(current_user, sign_up_params).build
|
||||
@resource ||= Users::BuildService.new(current_user, sign_up_params).execute
|
||||
end
|
||||
|
||||
def devise_mapping
|
||||
|
|
100
app/services/users/build_service.rb
Normal file
100
app/services/users/build_service.rb
Normal file
|
@ -0,0 +1,100 @@
|
|||
module Users
|
||||
# Service for building a new user.
|
||||
class BuildService < BaseService
|
||||
def initialize(current_user, params = {})
|
||||
@current_user = current_user
|
||||
@params = params.dup
|
||||
end
|
||||
|
||||
def execute
|
||||
raise Gitlab::Access::AccessDeniedError unless can_create_user?
|
||||
|
||||
user = User.new(build_user_params)
|
||||
|
||||
if current_user&.admin?
|
||||
if params[:reset_password]
|
||||
user.generate_reset_token
|
||||
params[:force_random_password] = true
|
||||
end
|
||||
|
||||
if params[:force_random_password]
|
||||
random_password = Devise.friendly_token.first(Devise.password_length.min)
|
||||
user.password = user.password_confirmation = random_password
|
||||
end
|
||||
end
|
||||
|
||||
identity_attrs = params.slice(:extern_uid, :provider)
|
||||
|
||||
if identity_attrs.any?
|
||||
user.identities.build(identity_attrs)
|
||||
end
|
||||
|
||||
user
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def can_create_user?
|
||||
(current_user.nil? && current_application_settings.signup_enabled?) || current_user&.admin?
|
||||
end
|
||||
|
||||
# Allowed params for creating a user (admins only)
|
||||
def admin_create_params
|
||||
[
|
||||
:access_level,
|
||||
:admin,
|
||||
:avatar,
|
||||
:bio,
|
||||
:can_create_group,
|
||||
:color_scheme_id,
|
||||
:email,
|
||||
:external,
|
||||
:force_random_password,
|
||||
:hide_no_password,
|
||||
:hide_no_ssh_key,
|
||||
:key_id,
|
||||
:linkedin,
|
||||
:name,
|
||||
:password,
|
||||
:password_automatically_set,
|
||||
:password_expires_at,
|
||||
:projects_limit,
|
||||
:remember_me,
|
||||
:skip_confirmation,
|
||||
:skype,
|
||||
:theme_id,
|
||||
:twitter,
|
||||
:username,
|
||||
:website_url
|
||||
]
|
||||
end
|
||||
|
||||
# Allowed params for user signup
|
||||
def signup_params
|
||||
[
|
||||
:email,
|
||||
:email_confirmation,
|
||||
:password_automatically_set,
|
||||
:name,
|
||||
:password,
|
||||
:username
|
||||
]
|
||||
end
|
||||
|
||||
def build_user_params
|
||||
if current_user&.admin?
|
||||
user_params = params.slice(*admin_create_params)
|
||||
user_params[:created_by_id] = current_user&.id
|
||||
|
||||
if params[:reset_password]
|
||||
user_params.merge!(force_random_password: true, password_expires_at: nil)
|
||||
end
|
||||
else
|
||||
user_params = params.slice(*signup_params)
|
||||
user_params[:skip_confirmation] = !current_application_settings.send_user_confirmation_email
|
||||
end
|
||||
|
||||
user_params
|
||||
end
|
||||
end
|
||||
end
|
|
@ -6,34 +6,10 @@ module Users
|
|||
@params = params.dup
|
||||
end
|
||||
|
||||
def build
|
||||
raise Gitlab::Access::AccessDeniedError unless can_create_user?
|
||||
|
||||
user = User.new(build_user_params)
|
||||
|
||||
if current_user&.admin?
|
||||
if params[:reset_password]
|
||||
@reset_token = user.generate_reset_token
|
||||
params[:force_random_password] = true
|
||||
end
|
||||
|
||||
if params[:force_random_password]
|
||||
random_password = Devise.friendly_token.first(Devise.password_length.min)
|
||||
user.password = user.password_confirmation = random_password
|
||||
end
|
||||
end
|
||||
|
||||
identity_attrs = params.slice(:extern_uid, :provider)
|
||||
|
||||
if identity_attrs.any?
|
||||
user.identities.build(identity_attrs)
|
||||
end
|
||||
|
||||
user
|
||||
end
|
||||
|
||||
def execute
|
||||
user = build
|
||||
user = Users::BuildService.new(current_user, params).execute
|
||||
|
||||
@reset_token = user.generate_reset_token if user.recently_sent_password_reset?
|
||||
|
||||
if user.save
|
||||
log_info("User \"#{user.name}\" (#{user.email}) was created")
|
||||
|
@ -43,70 +19,5 @@ module Users
|
|||
|
||||
user
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def can_create_user?
|
||||
(current_user.nil? && current_application_settings.signup_enabled?) || current_user&.admin?
|
||||
end
|
||||
|
||||
# Allowed params for creating a user (admins only)
|
||||
def admin_create_params
|
||||
[
|
||||
:access_level,
|
||||
:admin,
|
||||
:avatar,
|
||||
:bio,
|
||||
:can_create_group,
|
||||
:color_scheme_id,
|
||||
:email,
|
||||
:external,
|
||||
:force_random_password,
|
||||
:password_automatically_set,
|
||||
:hide_no_password,
|
||||
:hide_no_ssh_key,
|
||||
:key_id,
|
||||
:linkedin,
|
||||
:name,
|
||||
:password,
|
||||
:password_expires_at,
|
||||
:projects_limit,
|
||||
:remember_me,
|
||||
:skip_confirmation,
|
||||
:skype,
|
||||
:theme_id,
|
||||
:twitter,
|
||||
:username,
|
||||
:website_url
|
||||
]
|
||||
end
|
||||
|
||||
# Allowed params for user signup
|
||||
def signup_params
|
||||
[
|
||||
:email,
|
||||
:email_confirmation,
|
||||
:password_automatically_set,
|
||||
:name,
|
||||
:password,
|
||||
:username
|
||||
]
|
||||
end
|
||||
|
||||
def build_user_params
|
||||
if current_user&.admin?
|
||||
user_params = params.slice(*admin_create_params)
|
||||
user_params[:created_by_id] = current_user&.id
|
||||
|
||||
if params[:reset_password]
|
||||
user_params.merge!(force_random_password: true, password_expires_at: nil)
|
||||
end
|
||||
else
|
||||
user_params = params.slice(*signup_params)
|
||||
user_params[:skip_confirmation] = !current_application_settings.send_user_confirmation_email
|
||||
end
|
||||
|
||||
user_params
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Implement Users::BuildService
|
||||
merge_request: 30349
|
||||
author: George Andrinopoulos
|
|
@ -148,7 +148,7 @@ module Gitlab
|
|||
|
||||
def build_new_user
|
||||
user_params = user_attributes.merge(extern_uid: auth_hash.uid, provider: auth_hash.provider, skip_confirmation: true)
|
||||
Users::CreateService.new(nil, user_params).build
|
||||
Users::BuildService.new(nil, user_params).execute
|
||||
end
|
||||
|
||||
def user_attributes
|
||||
|
|
55
spec/services/users/build_service_spec.rb
Normal file
55
spec/services/users/build_service_spec.rb
Normal file
|
@ -0,0 +1,55 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Users::BuildService, services: true do
|
||||
describe '#execute' do
|
||||
let(:params) do
|
||||
{ name: 'John Doe', username: 'jduser', email: 'jd@example.com', password: 'mydummypass' }
|
||||
end
|
||||
|
||||
context 'with an admin user' do
|
||||
let(:admin_user) { create(:admin) }
|
||||
let(:service) { described_class.new(admin_user, params) }
|
||||
|
||||
it 'returns a valid user' do
|
||||
expect(service.execute).to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
context 'with non admin user' do
|
||||
let(:user) { create(:user) }
|
||||
let(:service) { described_class.new(user, params) }
|
||||
|
||||
it 'raises AccessDeniedError exception' do
|
||||
expect { service.execute }.to raise_error Gitlab::Access::AccessDeniedError
|
||||
end
|
||||
end
|
||||
|
||||
context 'with nil user' do
|
||||
let(:service) { described_class.new(nil, params) }
|
||||
|
||||
it 'returns a valid user' do
|
||||
expect(service.execute).to be_valid
|
||||
end
|
||||
|
||||
context 'when "send_user_confirmation_email" application setting is true' do
|
||||
before do
|
||||
stub_application_setting(send_user_confirmation_email: true, signup_enabled?: true)
|
||||
end
|
||||
|
||||
it 'does not confirm the user' do
|
||||
expect(service.execute).not_to be_confirmed
|
||||
end
|
||||
end
|
||||
|
||||
context 'when "send_user_confirmation_email" application setting is false' do
|
||||
before do
|
||||
stub_application_setting(send_user_confirmation_email: false, signup_enabled?: true)
|
||||
end
|
||||
|
||||
it 'confirms the user' do
|
||||
expect(service.execute).to be_confirmed
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,38 +1,6 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Users::CreateService, services: true do
|
||||
describe '#build' do
|
||||
let(:params) do
|
||||
{ name: 'John Doe', username: 'jduser', email: 'jd@example.com', password: 'mydummypass' }
|
||||
end
|
||||
|
||||
context 'with an admin user' do
|
||||
let(:admin_user) { create(:admin) }
|
||||
let(:service) { described_class.new(admin_user, params) }
|
||||
|
||||
it 'returns a valid user' do
|
||||
expect(service.build).to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
context 'with non admin user' do
|
||||
let(:user) { create(:user) }
|
||||
let(:service) { described_class.new(user, params) }
|
||||
|
||||
it 'raises AccessDeniedError exception' do
|
||||
expect { service.build }.to raise_error Gitlab::Access::AccessDeniedError
|
||||
end
|
||||
end
|
||||
|
||||
context 'with nil user' do
|
||||
let(:service) { described_class.new(nil, params) }
|
||||
|
||||
it 'returns a valid user' do
|
||||
expect(service.build).to be_valid
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#execute' do
|
||||
let(:admin_user) { create(:admin) }
|
||||
|
||||
|
@ -185,40 +153,18 @@ describe Users::CreateService, services: true do
|
|||
end
|
||||
let(:service) { described_class.new(nil, params) }
|
||||
|
||||
context 'when "send_user_confirmation_email" application setting is true' do
|
||||
before do
|
||||
current_application_settings = double(:current_application_settings, send_user_confirmation_email: true, signup_enabled?: true)
|
||||
allow(service).to receive(:current_application_settings).and_return(current_application_settings)
|
||||
end
|
||||
it 'persists the given attributes' do
|
||||
user = service.execute
|
||||
user.reload
|
||||
|
||||
it 'does not confirm the user' do
|
||||
expect(service.execute).not_to be_confirmed
|
||||
end
|
||||
end
|
||||
|
||||
context 'when "send_user_confirmation_email" application setting is false' do
|
||||
before do
|
||||
current_application_settings = double(:current_application_settings, send_user_confirmation_email: false, signup_enabled?: true)
|
||||
allow(service).to receive(:current_application_settings).and_return(current_application_settings)
|
||||
end
|
||||
|
||||
it 'confirms the user' do
|
||||
expect(service.execute).to be_confirmed
|
||||
end
|
||||
|
||||
it 'persists the given attributes' do
|
||||
user = service.execute
|
||||
user.reload
|
||||
|
||||
expect(user).to have_attributes(
|
||||
name: params[:name],
|
||||
username: params[:username],
|
||||
email: params[:email],
|
||||
password: params[:password],
|
||||
created_by_id: nil,
|
||||
admin: false
|
||||
)
|
||||
end
|
||||
expect(user).to have_attributes(
|
||||
name: params[:name],
|
||||
username: params[:username],
|
||||
email: params[:email],
|
||||
password: params[:password],
|
||||
created_by_id: nil,
|
||||
admin: false
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue