Skip to content
Snippets Groups Projects
Commit b804db26 authored by James Lopez's avatar James Lopez
Browse files

refactor update user service not to do auth checks

parent e2e0b175
No related branches found
No related tags found
No related merge requests found
Showing
with 42 additions and 68 deletions
Loading
Loading
@@ -125,7 +125,7 @@ class Admin::UsersController < Admin::ApplicationController
end
 
respond_to do |format|
result = Users::UpdateService.new(current_user, user, user_params_with_pass).execute do |user|
result = Users::UpdateService.new(user, user_params_with_pass).execute do |user|
user.skip_reconfirmation!
end
 
Loading
Loading
@@ -211,7 +211,7 @@ class Admin::UsersController < Admin::ApplicationController
end
 
def update_user
result = Users::UpdateService.new(current_user, user).execute do |user|
result = Users::UpdateService.new(user).execute do |user|
yield(user)
end
 
Loading
Loading
Loading
Loading
@@ -2,7 +2,7 @@ class Profiles::AvatarsController < Profiles::ApplicationController
def destroy
@user = current_user
 
Users::UpdateService.new(@user, @user).execute { |user| user.remove_avatar! }
Users::UpdateService.new(@user).execute { |user| user.remove_avatar! }
 
redirect_to profile_path, status: 302
end
Loading
Loading
Loading
Loading
@@ -7,7 +7,7 @@ class Profiles::NotificationsController < Profiles::ApplicationController
end
 
def update
result = Users::UpdateService.new(current_user, current_user, user_params).execute
result = Users::UpdateService.new(current_user, user_params).execute
 
if result[:status] == :success
flash[:notice] = "Notification settings saved"
Loading
Loading
Loading
Loading
@@ -21,10 +21,10 @@ class Profiles::PasswordsController < Profiles::ApplicationController
password_automatically_set: false
}
 
result = Users::UpdateService.new(current_user, @user, password_attributes).execute
result = Users::UpdateService.new(@user, password_attributes).execute
 
if result[:status] == :success
Users::UpdateService.new(current_user, @user, password_expires_at: nil).execute
Users::UpdateService.new(@user, password_expires_at: nil).execute
 
redirect_to root_path, notice: 'Password successfully changed'
else
Loading
Loading
@@ -46,7 +46,7 @@ class Profiles::PasswordsController < Profiles::ApplicationController
return
end
 
result = Users::UpdateService.new(current_user, @user, password_attributes).execute
result = Users::UpdateService.new(@user, password_attributes).execute
 
if result[:status] == :success
flash[:notice] = "Password was successfully updated. Please login with it"
Loading
Loading
Loading
Loading
@@ -6,7 +6,7 @@ class Profiles::PreferencesController < Profiles::ApplicationController
 
def update
begin
result = Users::UpdateService.new(current_user, user, preferences_params).execute
result = Users::UpdateService.new(user, preferences_params).execute
 
if result[:status] == :success
flash[:notice] = 'Preferences saved.'
Loading
Loading
Loading
Loading
@@ -10,7 +10,7 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
current_user.otp_grace_period_started_at = Time.current
end
 
Users::UpdateService.new(current_user, current_user).execute!
Users::UpdateService.new(current_user).execute!
 
if two_factor_authentication_required? && !current_user.two_factor_enabled?
two_factor_authentication_reason(
Loading
Loading
@@ -41,7 +41,7 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
 
def create
if current_user.validate_and_consume_otp!(params[:pin_code])
Users::UpdateService.new(current_user, current_user, otp_required_for_login: true).execute! do |user|
Users::UpdateService.new(current_user, otp_required_for_login: true).execute! do |user|
@codes = user.generate_otp_backup_codes!
end
 
Loading
Loading
@@ -70,7 +70,7 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
end
 
def codes
Users::UpdateService.new(current_user, current_user).execute! do |user|
Users::UpdateService.new(current_user).execute! do |user|
@codes = user.generate_otp_backup_codes!
end
end
Loading
Loading
Loading
Loading
@@ -12,7 +12,7 @@ class ProfilesController < Profiles::ApplicationController
user_params.except!(:email) if @user.external_email?
 
respond_to do |format|
result = Users::UpdateService.new(current_user, @user, user_params).execute
result = Users::UpdateService.new(@user, user_params).execute
 
if result[:status] == :success
message = "Profile was successfully updated"
Loading
Loading
@@ -27,7 +27,7 @@ class ProfilesController < Profiles::ApplicationController
end
 
def reset_private_token
Users::UpdateService.new(current_user, @user).execute!(skip_authorization: true) do |user|
Users::UpdateService.new(@user).execute!(skip_authorization: true) do |user|
user.reset_authentication_token!
end
 
Loading
Loading
@@ -37,7 +37,7 @@ class ProfilesController < Profiles::ApplicationController
end
 
def reset_incoming_email_token
Users::UpdateService.new(current_user, @user).execute!(skip_authorization: true) do |user|
Users::UpdateService.new(@user).execute!(skip_authorization: true) do |user|
user.reset_incoming_email_token!
end
 
Loading
Loading
@@ -47,7 +47,7 @@ class ProfilesController < Profiles::ApplicationController
end
 
def reset_rss_token
Users::UpdateService.new(current_user, @user).execute!(skip_authorization: true) do |user|
Users::UpdateService.new(@user).execute!(skip_authorization: true) do |user|
user.reset_rss_token!
end
 
Loading
Loading
@@ -63,7 +63,7 @@ class ProfilesController < Profiles::ApplicationController
end
 
def update_username
result = Users::UpdateService.new(current_user, @user, username: user_params[:username]).execute
result = Users::UpdateService.new(@user, username: user_params[:username]).execute
 
options = if result[:status] == :success
{ notice: "Username successfully changed" }
Loading
Loading
Loading
Loading
@@ -60,7 +60,7 @@ class SessionsController < Devise::SessionsController
 
return unless user && user.require_password?
 
Users::UpdateService.new(user, user).execute do |user|
Users::UpdateService.new(user).execute do |user|
@token = user.generate_reset_token
end
 
Loading
Loading
Loading
Loading
@@ -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
 
Users::UpdateService.new(self, self).execute(validate: false)
Users::UpdateService.new(self).execute(validate: false)
end
 
attr_accessor :force_random_password
Loading
Loading
@@ -963,7 +963,7 @@ class User < ActiveRecord::Base
if attempts_exceeded?
lock_access! unless access_locked?
else
Users::UpdateService.new(self, self).execute(validate: false)
Users::UpdateService.new(self).execute(validate: false)
end
end
 
Loading
Loading
@@ -1122,7 +1122,7 @@ class User < ActiveRecord::Base
&creation_block
)
 
Users::UpdateService.new(user, user).execute(validate: false)
Users::UpdateService.new(user).execute(validate: false)
user
ensure
Gitlab::ExclusiveLease.cancel(lease_key, uuid)
Loading
Loading
module Emails
class DestroyService < ::Emails::BaseService
def execute
Email.find_by_email(@email).destroy && update_secondary_emails!
Email.find_by_email!(@email).destroy && update_secondary_emails!
end
 
private
 
def update_secondary_emails!
result = ::Users::UpdateService.new(@current_user, @current_user).execute do |user|
result = ::Users::UpdateService.new(@current_user).execute do |user|
user.update_secondary_emails!
end
 
Loading
Loading
module Users
# Service for updating a user.
class UpdateService < BaseService
def initialize(current_user, user, params = {})
@current_user = current_user
def initialize(user, params = {})
@user = user
@params = params.dup
end
 
def execute(skip_authorization: false, validate: true, &block)
assign_attributes(skip_authorization, &block)
def execute(validate: true, &block)
assign_attributes(&block)
 
if @user.save(validate: validate)
success
Loading
Loading
@@ -20,23 +19,17 @@ module Users
def execute!(*args, &block)
result = execute(*args, &block)
 
raise ActiveRecord::RecordInvalid(result[:message]) unless result[:status] == :success
raise ActiveRecord::RecordInvalid.new(@user) unless result[:status] == :success
 
true
end
 
private
 
def assign_attributes(skip_authorization, &block)
raise Gitlab::Access::AccessDeniedError unless skip_authorization || can_update_user?
def assign_attributes(&block)
yield(@user) if block_given?
 
@user.assign_attributes(params) if params.any?
end
def can_update_user?
current_user == @user || current_user&.admin?
end
end
end
Loading
Loading
@@ -132,7 +132,7 @@ module API
return { success: false, message: 'Two-factor authentication is not enabled for this user' }
end
 
::Users::UpdateService.new(user, user).execute! do |user|
::Users::UpdateService.new(user).execute! do |user|
@codes = user.generate_otp_backup_codes!
end
 
Loading
Loading
Loading
Loading
@@ -35,7 +35,7 @@ module API
new_notification_email = params.delete(:notification_email)
 
if new_notification_email
::Users::UpdateService.new(current_user, current_user, notification_email: new_notification_email).execute
::Users::UpdateService.new(current_user, notification_email: new_notification_email).execute
end
 
notification_setting.update(declared_params(include_missing: false))
Loading
Loading
Loading
Loading
@@ -156,7 +156,7 @@ module API
 
user_params[:password_expires_at] = Time.now if user_params[:password].present?
 
result = ::Users::UpdateService.new(current_user, user, user_params.except(:extern_uid, :provider)).execute
result = ::Users::UpdateService.new(user, user_params.except(:extern_uid, :provider)).execute
 
if result[:status] == :success
present user, with: Entities::UserPublic
Loading
Loading
Loading
Loading
@@ -16,7 +16,7 @@ module Gitlab
def self.allowed?(user)
self.open(user) do |access|
if access.allowed?
Users::UpdateService.new(user, user, last_credential_check_a: Time.now).execute
Users::UpdateService.new(user, last_credential_check_a: Time.now).execute
 
true
else
Loading
Loading
Loading
Loading
@@ -32,7 +32,7 @@ module Gitlab
 
block_after_save = needs_blocking?
 
Users::UpdateService.new(gl_user, gl_user).execute!
Users::UpdateService.new(gl_user).execute!
 
gl_user.block if block_after_save
 
Loading
Loading
Loading
Loading
@@ -2,61 +2,42 @@ require 'spec_helper'
 
describe Users::UpdateService, services: true do
let(:user) { create(:user) }
let(:admin) { create(:admin) }
 
describe '#execute' do
it 'updates the name' do
result = update_user(user, user, name: 'New Name')
result = update_user(user, name: 'New Name')
 
expect(result).to eq({ status: :success })
expect(user.name).to eq('New Name')
end
 
context 'when updated by an admin' do
it 'updates the name' do
result = update_user(admin, user, name: 'New Name')
expect(result).to eq({ status: :success })
expect(user.name).to eq('New Name')
end
end
it 'returns an error result when record cannot be updated' do
expect do
update_user(user, create(:user), { name: 'New Name' })
end.to raise_error Gitlab::Access::AccessDeniedError
update_user(user, { email: 'invalid' })
end.not_to change { user.reload.email }
end
 
def update_user(current_user, user, opts)
described_class.new(current_user, user, opts).execute
def update_user(user, opts)
described_class.new(user, opts).execute
end
end
 
describe '#execute!' do
it 'updates the name' do
result = update_user(user, user, name: 'New Name')
result = update_user(user, name: 'New Name')
 
expect(result).to be true
expect(user.name).to eq('New Name')
end
 
context 'when updated by an admin' do
it 'updates the name' do
result = update_user(admin, user, name: 'New Name')
expect(result).to be true
expect(user.name).to eq('New Name')
end
end
it 'returns an error result when record cannot be updated' do
expect do
update_user(user, create(:user), { name: 'New Name' })
end.to raise_error Gitlab::Access::AccessDeniedError
update_user(user, { email: 'invalid' })
end.to raise_error(ActiveRecord::RecordInvalid)
end
 
def update_user(current_user, user, opts)
described_class.new(current_user, user, opts).execute!
def update_user(user, opts)
described_class.new(user, opts).execute!
end
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment