diff options
author | Sean McGivern <sean@mcgivern.me.uk> | 2017-06-26 14:42:44 +0300 |
---|---|---|
committer | Sean McGivern <sean@mcgivern.me.uk> | 2017-06-26 14:42:44 +0300 |
commit | bff82b784bac7af8cf3a3d8b49fa10ebd1ef67f0 (patch) | |
tree | 2b294a4f5f947843ea6afdb8f31338e2901f5e8f /app | |
parent | 739a03a825e5c04c7566bc3bb26314b049e403ec (diff) | |
parent | 4d70c479107fc502668a83fc369159062d8efbb8 (diff) |
Merge branch 'feature/add-new-services' into 'master'
Add additional user and email services
See merge request !12125
Diffstat (limited to 'app')
-rw-r--r-- | app/controllers/admin/users_controller.rb | 39 | ||||
-rw-r--r-- | app/controllers/profiles/avatars_controller.rb | 3 | ||||
-rw-r--r-- | app/controllers/profiles/emails_controller.rb | 7 | ||||
-rw-r--r-- | app/controllers/profiles/notifications_controller.rb | 4 | ||||
-rw-r--r-- | app/controllers/profiles/passwords_controller.rb | 22 | ||||
-rw-r--r-- | app/controllers/profiles/preferences_controller.rb | 4 | ||||
-rw-r--r-- | app/controllers/profiles/two_factor_auths_controller.rb | 13 | ||||
-rw-r--r-- | app/controllers/profiles_controller.rb | 41 | ||||
-rw-r--r-- | app/controllers/sessions_controller.rb | 7 | ||||
-rw-r--r-- | app/models/user.rb | 13 | ||||
-rw-r--r-- | app/services/emails/base_service.rb | 8 | ||||
-rw-r--r-- | app/services/emails/create_service.rb | 7 | ||||
-rw-r--r-- | app/services/emails/destroy_service.rb | 17 | ||||
-rw-r--r-- | app/services/users/build_service.rb | 1 | ||||
-rw-r--r-- | app/services/users/create_service.rb | 1 | ||||
-rw-r--r-- | app/services/users/update_service.rb | 34 |
16 files changed, 156 insertions, 65 deletions
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index b09eef17c23..fa1bc72560e 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -54,7 +54,7 @@ class Admin::UsersController < Admin::ApplicationController end def block - if user.block + if update_user { |user| user.block } redirect_back_or_admin_user(notice: "Successfully blocked") else redirect_back_or_admin_user(alert: "Error occurred. User was not blocked") @@ -64,7 +64,7 @@ class Admin::UsersController < Admin::ApplicationController def unblock if user.ldap_blocked? redirect_back_or_admin_user(alert: "This user cannot be unlocked manually from GitLab") - elsif user.activate + elsif update_user { |user| user.activate } redirect_back_or_admin_user(notice: "Successfully unblocked") else redirect_back_or_admin_user(alert: "Error occurred. User was not unblocked") @@ -72,7 +72,7 @@ class Admin::UsersController < Admin::ApplicationController end def unlock - if user.unlock_access! + if update_user { |user| user.unlock_access! } redirect_back_or_admin_user(alert: "Successfully unlocked") else redirect_back_or_admin_user(alert: "Error occurred. User was not unlocked") @@ -80,7 +80,7 @@ class Admin::UsersController < Admin::ApplicationController end def confirm - if user.confirm + if update_user { |user| user.confirm } redirect_back_or_admin_user(notice: "Successfully confirmed") else redirect_back_or_admin_user(alert: "Error occurred. User was not confirmed") @@ -88,7 +88,8 @@ class Admin::UsersController < Admin::ApplicationController end def disable_two_factor - user.disable_two_factor! + update_user { |user| user.disable_two_factor! } + redirect_to admin_user_path(user), notice: 'Two-factor Authentication has been disabled for this user' end @@ -124,15 +125,18 @@ class Admin::UsersController < Admin::ApplicationController end respond_to do |format| - user.skip_reconfirmation! - if user.update_attributes(user_params_with_pass) + result = Users::UpdateService.new(user, user_params_with_pass).execute do |user| + user.skip_reconfirmation! + end + + if result[:status] == :success format.html { redirect_to [:admin, user], notice: 'User was successfully updated.' } format.json { head :ok } else # restore username to keep form action url. user.username = params[:id] format.html { render "edit" } - format.json { render json: user.errors, status: :unprocessable_entity } + format.json { render json: [result[:message]], status: result[:status] } end end end @@ -148,13 +152,16 @@ class Admin::UsersController < Admin::ApplicationController def remove_email email = user.emails.find(params[:email_id]) - email.destroy - - user.update_secondary_emails! + success = Emails::DestroyService.new(user, email: email.email).execute respond_to do |format| - format.html { redirect_back_or_admin_user(notice: "Successfully removed email.") } - format.js { head :ok } + if success + format.html { redirect_back_or_admin_user(notice: 'Successfully removed email.') } + format.json { head :ok } + else + format.html { redirect_back_or_admin_user(alert: 'There was an error removing the e-mail.') } + format.json { render json: 'There was an error removing the e-mail.', status: 400 } + end end end @@ -202,4 +209,10 @@ class Admin::UsersController < Admin::ApplicationController :website_url ] end + + def update_user(&block) + result = Users::UpdateService.new(user).execute(&block) + + result[:status] == :success + end end diff --git a/app/controllers/profiles/avatars_controller.rb b/app/controllers/profiles/avatars_controller.rb index 933e0f3bceb..408650aac54 100644 --- a/app/controllers/profiles/avatars_controller.rb +++ b/app/controllers/profiles/avatars_controller.rb @@ -1,9 +1,8 @@ class Profiles::AvatarsController < Profiles::ApplicationController def destroy @user = current_user - @user.remove_avatar! - @user.save + Users::UpdateService.new(@user).execute { |user| user.remove_avatar! } redirect_to profile_path, status: 302 end diff --git a/app/controllers/profiles/emails_controller.rb b/app/controllers/profiles/emails_controller.rb index 5655fb2ba0e..17b66df43e7 100644 --- a/app/controllers/profiles/emails_controller.rb +++ b/app/controllers/profiles/emails_controller.rb @@ -5,9 +5,9 @@ class Profiles::EmailsController < Profiles::ApplicationController end def create - @email = current_user.emails.new(email_params) + @email = Emails::CreateService.new(current_user, email_params).execute - if @email.save + if @email.errors.blank? NotificationService.new.new_email(@email) else flash[:alert] = @email.errors.full_messages.first @@ -18,9 +18,8 @@ class Profiles::EmailsController < Profiles::ApplicationController def destroy @email = current_user.emails.find(params[:id]) - @email.destroy - current_user.update_secondary_emails! + Emails::DestroyService.new(current_user, email: @email.email).execute respond_to do |format| format.html { redirect_to profile_emails_url, status: 302 } diff --git a/app/controllers/profiles/notifications_controller.rb b/app/controllers/profiles/notifications_controller.rb index a271e2dfc4b..960b7512602 100644 --- a/app/controllers/profiles/notifications_controller.rb +++ b/app/controllers/profiles/notifications_controller.rb @@ -7,7 +7,9 @@ class Profiles::NotificationsController < Profiles::ApplicationController end def update - if current_user.update_attributes(user_params) + result = Users::UpdateService.new(current_user, user_params).execute + + if result[:status] == :success flash[:notice] = "Notification settings saved" else flash[:alert] = "Failed to save new settings" diff --git a/app/controllers/profiles/passwords_controller.rb b/app/controllers/profiles/passwords_controller.rb index 6217ec5ecef..10145bae0d3 100644 --- a/app/controllers/profiles/passwords_controller.rb +++ b/app/controllers/profiles/passwords_controller.rb @@ -15,17 +15,17 @@ class Profiles::PasswordsController < Profiles::ApplicationController return end - new_password = user_params[:password] - new_password_confirmation = user_params[:password_confirmation] - - result = @user.update_attributes( - password: new_password, - password_confirmation: new_password_confirmation, + password_attributes = { + password: user_params[:password], + password_confirmation: user_params[:password_confirmation], password_automatically_set: false - ) + } + + result = Users::UpdateService.new(@user, password_attributes).execute + + if result[:status] == :success + Users::UpdateService.new(@user, password_expires_at: nil).execute - if result - @user.update_attributes(password_expires_at: nil) redirect_to root_path, notice: 'Password successfully changed' else render :new @@ -46,7 +46,9 @@ class Profiles::PasswordsController < Profiles::ApplicationController return end - if @user.update_attributes(password_attributes) + result = Users::UpdateService.new(@user, password_attributes).execute + + if result[:status] == :success flash[:notice] = "Password was successfully updated. Please login with it" redirect_to new_user_session_path else diff --git a/app/controllers/profiles/preferences_controller.rb b/app/controllers/profiles/preferences_controller.rb index 5414142e2df..1e557c47638 100644 --- a/app/controllers/profiles/preferences_controller.rb +++ b/app/controllers/profiles/preferences_controller.rb @@ -6,7 +6,9 @@ class Profiles::PreferencesController < Profiles::ApplicationController def update begin - if @user.update_attributes(preferences_params) + result = Users::UpdateService.new(user, preferences_params).execute + + if result[:status] == :success flash[:notice] = 'Preferences saved.' else flash[:alert] = 'Failed to save preferences.' diff --git a/app/controllers/profiles/two_factor_auths_controller.rb b/app/controllers/profiles/two_factor_auths_controller.rb index 313cdcd1c15..1a4f77639e7 100644 --- a/app/controllers/profiles/two_factor_auths_controller.rb +++ b/app/controllers/profiles/two_factor_auths_controller.rb @@ -10,7 +10,7 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController current_user.otp_grace_period_started_at = Time.current end - current_user.save! if current_user.changed? + Users::UpdateService.new(current_user).execute! if two_factor_authentication_required? && !current_user.two_factor_enabled? two_factor_authentication_reason( @@ -41,9 +41,9 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController def create if current_user.validate_and_consume_otp!(params[:pin_code]) - current_user.otp_required_for_login = true - @codes = current_user.generate_otp_backup_codes! - current_user.save! + Users::UpdateService.new(current_user, otp_required_for_login: true).execute! do |user| + @codes = user.generate_otp_backup_codes! + end render 'create' else @@ -70,8 +70,9 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController end def codes - @codes = current_user.generate_otp_backup_codes! - current_user.save! + Users::UpdateService.new(current_user).execute! do |user| + @codes = user.generate_otp_backup_codes! + end end def destroy diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb index f98a9e24de1..076076fd1b3 100644 --- a/app/controllers/profiles_controller.rb +++ b/app/controllers/profiles_controller.rb @@ -12,39 +12,47 @@ class ProfilesController < Profiles::ApplicationController user_params.except!(:email) if @user.external_email? respond_to do |format| - if @user.update_attributes(user_params) + result = Users::UpdateService.new(@user, user_params).execute + + if result[:status] == :success message = "Profile was successfully updated" + format.html { redirect_back_or_default(default: { action: 'show' }, options: { notice: message }) } format.json { render json: { message: message } } else - message = @user.errors.full_messages.uniq.join('. ') - format.html { redirect_back_or_default(default: { action: 'show' }, options: { alert: "Failed to update profile. #{message}" }) } - format.json { render json: { message: message }, status: :unprocessable_entity } + format.html { redirect_back_or_default(default: { action: 'show' }, options: { alert: result[:message] }) } + format.json { render json: result } end end end def reset_private_token - if current_user.reset_authentication_token! - flash[:notice] = "Private token was successfully reset" + Users::UpdateService.new(@user).execute! do |user| + user.reset_authentication_token! end + flash[:notice] = "Private token was successfully reset" + redirect_to profile_account_path end def reset_incoming_email_token - if current_user.reset_incoming_email_token! - flash[:notice] = "Incoming email token was successfully reset" + Users::UpdateService.new(@user).execute! do |user| + user.reset_incoming_email_token! end + flash[:notice] = "Incoming email token was successfully reset" + redirect_to profile_account_path end def reset_rss_token - if current_user.reset_rss_token! - flash[:notice] = "RSS token was successfully reset" + Users::UpdateService.new(@user).execute! do |user| + user.reset_rss_token! end + flash[:notice] = "RSS token was successfully reset" + redirect_to profile_account_path end @@ -55,12 +63,13 @@ class ProfilesController < Profiles::ApplicationController end def update_username - if @user.update_attributes(username: user_params[:username]) - options = { notice: "Username successfully changed" } - else - message = @user.errors.full_messages.uniq.join('. ') - options = { alert: "Username change failed - #{message}" } - end + result = Users::UpdateService.new(@user, username: user_params[:username]).execute + + options = if result[:status] == :success + { notice: "Username successfully changed" } + else + { alert: "Username change failed - #{result[:message]}" } + end redirect_back_or_default(default: { action: 'show' }, options: options) end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 0d8186dce02..f39441a281e 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -60,10 +60,11 @@ class SessionsController < Devise::SessionsController return unless user && user.require_password? - token = user.generate_reset_token - user.save + Users::UpdateService.new(user).execute do |user| + @token = user.generate_reset_token + end - redirect_to edit_user_password_path(reset_password_token: token), + redirect_to edit_user_password_path(reset_password_token: @token), notice: "Please create a password for your new account." end diff --git a/app/models/user.rb b/app/models/user.rb index 9971e43146a..650b64e7551 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -53,7 +53,7 @@ class User < ActiveRecord::Base lease = Gitlab::ExclusiveLease.new("user_update_tracked_fields:#{id}", timeout: 1.hour.to_i) return unless lease.try_obtain - save(validate: false) + Users::UpdateService.new(self).execute(validate: false) end attr_accessor :force_random_password @@ -494,10 +494,8 @@ class User < ActiveRecord::Base def update_emails_with_primary_email primary_email_record = emails.find_by(email: email) if primary_email_record - primary_email_record.destroy - emails.create(email: email_was) - - update_secondary_emails! + Emails::DestroyService.new(self, email: email).execute + Emails::CreateService.new(self, email: email_was).execute end end @@ -965,7 +963,7 @@ class User < ActiveRecord::Base if attempts_exceeded? lock_access! unless access_locked? else - save(validate: false) + Users::UpdateService.new(self).execute(validate: false) end end @@ -1129,7 +1127,8 @@ class User < ActiveRecord::Base email: email, &creation_block ) - user.save(validate: false) + + Users::UpdateService.new(user).execute(validate: false) user ensure Gitlab::ExclusiveLease.cancel(lease_key, uuid) diff --git a/app/services/emails/base_service.rb b/app/services/emails/base_service.rb new file mode 100644 index 00000000000..ace49889097 --- /dev/null +++ b/app/services/emails/base_service.rb @@ -0,0 +1,8 @@ +module Emails + class BaseService + def initialize(user, opts) + @user = user + @email = opts[:email] + end + end +end diff --git a/app/services/emails/create_service.rb b/app/services/emails/create_service.rb new file mode 100644 index 00000000000..b6491ee9804 --- /dev/null +++ b/app/services/emails/create_service.rb @@ -0,0 +1,7 @@ +module Emails + class CreateService < ::Emails::BaseService + def execute + @user.emails.create(email: @email) + end + end +end diff --git a/app/services/emails/destroy_service.rb b/app/services/emails/destroy_service.rb new file mode 100644 index 00000000000..d586b9dfe0c --- /dev/null +++ b/app/services/emails/destroy_service.rb @@ -0,0 +1,17 @@ +module Emails + class DestroyService < ::Emails::BaseService + def execute + Email.find_by_email!(@email).destroy && update_secondary_emails! + end + + private + + def update_secondary_emails! + result = ::Users::UpdateService.new(@user).execute do |user| + user.update_secondary_emails! + end + + result[:status] == 'success' + end + end +end diff --git a/app/services/users/build_service.rb b/app/services/users/build_service.rb index 363135ef09b..ff234a3440f 100644 --- a/app/services/users/build_service.rb +++ b/app/services/users/build_service.rb @@ -1,5 +1,4 @@ module Users - # Service for building a new user. class BuildService < BaseService def initialize(current_user, params = {}) @current_user = current_user diff --git a/app/services/users/create_service.rb b/app/services/users/create_service.rb index e22f7225ae2..74abc017cea 100644 --- a/app/services/users/create_service.rb +++ b/app/services/users/create_service.rb @@ -1,5 +1,4 @@ module Users - # Service for creating a new user. class CreateService < BaseService def initialize(current_user, params = {}) @current_user = current_user diff --git a/app/services/users/update_service.rb b/app/services/users/update_service.rb new file mode 100644 index 00000000000..dfbd6016c3f --- /dev/null +++ b/app/services/users/update_service.rb @@ -0,0 +1,34 @@ +module Users + class UpdateService < BaseService + def initialize(user, params = {}) + @user = user + @params = params.dup + end + + def execute(validate: true, &block) + yield(@user) if block_given? + + assign_attributes(&block) + + if @user.save(validate: validate) + success + else + error(@user.errors.full_messages.uniq.join('. ')) + end + end + + def execute!(*args, &block) + result = execute(*args, &block) + + raise ActiveRecord::RecordInvalid.new(@user) unless result[:status] == :success + + true + end + + private + + def assign_attributes(&block) + @user.assign_attributes(params) if params.any? + end + end +end |