2018-09-14 01:42:05 -04:00
# frozen_string_literal: true
2013-01-20 06:20:50 -05:00
class Admin :: UsersController < Admin :: ApplicationController
2019-02-12 17:26:07 -05:00
include RoutableActions
2021-06-16 11:10:08 -04:00
before_action :user , except : [ :index , :new , :create ]
2018-11-24 07:39:16 -05:00
before_action :check_impersonation_availability , only : :impersonate
2020-10-01 14:10:20 -04:00
before_action :ensure_destroy_prerequisites_met , only : [ :destroy ]
2021-05-14 14:10:34 -04:00
before_action :check_ban_user_feature_flag , only : [ :ban ]
2013-01-26 05:08:34 -05:00
2020-10-05 17:08:47 -04:00
feature_category :users
2021-04-22 08:09:49 -04:00
PAGINATION_WITH_COUNT_LIMIT = 1000
2011-10-08 17:36:38 -04:00
def index
2021-06-16 11:10:08 -04:00
return redirect_to admin_cohorts_path if params [ :tab ] == 'cohorts'
2021-04-23 08:09:52 -04:00
2019-02-16 17:26:15 -05:00
@users = User . filter_items ( params [ :filter ] ) . order_name_asc
2016-10-25 13:14:58 -04:00
@users = @users . search_with_secondary_emails ( params [ :search_query ] ) if params [ :search_query ] . present?
2021-04-13 20:10:39 -04:00
@users = users_with_included_associations ( @users )
2018-04-04 05:19:47 -04:00
@users = @users . sort_by_attribute ( @sort = params [ :sort ] )
2015-02-05 22:15:05 -05:00
@users = @users . page ( params [ :page ] )
2021-04-22 08:09:49 -04:00
@users = @users . without_count if paginate_without_count?
2021-04-23 08:09:52 -04:00
end
2021-01-27 10:09:15 -05:00
2011-10-08 17:36:38 -04:00
def show
2015-06-22 11:12:20 -04:00
end
2021-08-09 05:22:41 -04:00
# rubocop: disable CodeReuse/ActiveRecord
2015-06-22 11:12:20 -04:00
def projects
2021-08-09 05:22:41 -04:00
@personal_projects = user . personal_projects . includes ( :topics )
@joined_projects = user . projects . joined ( @user ) . includes ( :topics )
2015-06-22 11:12:20 -04:00
end
def keys
2017-08-15 06:27:37 -04:00
@keys = user . keys . order_id_desc
2011-10-08 17:36:38 -04:00
end
def new
2014-06-26 16:24:17 -04:00
@user = User . new
2011-10-08 17:36:38 -04:00
end
def edit
2013-06-26 08:57:02 -04:00
user
2011-10-08 17:36:38 -04:00
end
2016-04-22 17:19:55 -04:00
def impersonate
2021-09-30 14:11:31 -04:00
if can? ( user , :log_in ) && ! impersonation_in_progress?
2016-04-22 17:19:55 -04:00
session [ :impersonator_id ] = current_user . id
warden . set_user ( user , scope : :user )
2021-09-30 14:11:31 -04:00
clear_access_token_session_keys!
2016-04-22 17:19:55 -04:00
2019-07-23 02:14:09 -04:00
log_impersonation_event
2016-05-03 23:55:35 -04:00
2019-03-21 09:31:05 -04:00
flash [ :alert ] = _ ( " You are now impersonating %{username} " ) % { username : user . username }
2016-04-22 17:19:55 -04:00
redirect_to root_path
2017-03-07 22:05:01 -05:00
else
flash [ :alert ] =
2021-09-30 14:11:31 -04:00
if impersonation_in_progress?
_ ( " You are already impersonating another user " )
elsif user . blocked?
2019-03-21 09:31:05 -04:00
_ ( " You cannot impersonate a blocked user " )
2017-03-07 22:05:01 -05:00
elsif user . internal?
2019-03-21 09:31:05 -04:00
_ ( " You cannot impersonate an internal user " )
2017-03-07 22:05:01 -05:00
else
2019-03-21 09:31:05 -04:00
_ ( " You cannot impersonate a user who cannot log in " )
2017-03-07 22:05:01 -05:00
end
redirect_to admin_user_path ( user )
2016-04-22 17:19:55 -04:00
end
end
2020-10-15 08:09:06 -04:00
def approve
result = Users :: ApproveService . new ( current_user ) . execute ( user )
if result [ :status ] == :success
redirect_back_or_admin_user ( notice : _ ( " Successfully approved " ) )
else
redirect_back_or_admin_user ( alert : result [ :message ] )
end
end
2020-12-02 19:09:53 -05:00
def reject
result = Users :: RejectService . new ( current_user ) . execute ( user )
if result [ :status ] == :success
redirect_to admin_users_path , status : :found , notice : _ ( " You've rejected %{user} " % { user : user . name } )
else
redirect_back_or_admin_user ( alert : result [ :message ] )
end
end
2019-10-09 20:06:44 -04:00
def activate
return redirect_back_or_admin_user ( notice : _ ( " Error occurred. A blocked user must be unblocked to be activated " ) ) if user . blocked?
user . activate
redirect_back_or_admin_user ( notice : _ ( " Successfully activated " ) )
end
def deactivate
return redirect_back_or_admin_user ( notice : _ ( " Error occurred. A blocked user cannot be deactivated " ) ) if user . blocked?
return redirect_back_or_admin_user ( notice : _ ( " Successfully deactivated " ) ) if user . deactivated?
2020-10-14 02:08:33 -04:00
return redirect_back_or_admin_user ( notice : _ ( " Internal users cannot be deactivated " ) ) if user . internal?
2019-10-09 20:06:44 -04:00
return redirect_back_or_admin_user ( notice : _ ( " The user you are trying to deactivate has been active in the past %{minimum_inactive_days} days and cannot be deactivated " ) % { minimum_inactive_days : :: User :: MINIMUM_INACTIVE_DAYS } ) unless user . can_be_deactivated?
user . deactivate
redirect_back_or_admin_user ( notice : _ ( " Successfully deactivated " ) )
end
2012-09-16 07:44:54 -04:00
def block
2020-02-13 10:08:52 -05:00
result = Users :: BlockService . new ( current_user ) . execute ( user )
2020-10-15 08:09:06 -04:00
if result [ :status ] == :success
2019-03-21 09:31:05 -04:00
redirect_back_or_admin_user ( notice : _ ( " Successfully blocked " ) )
2012-09-16 07:44:54 -04:00
else
2019-03-21 09:31:05 -04:00
redirect_back_or_admin_user ( alert : _ ( " Error occurred. User was not blocked " ) )
2012-04-16 16:33:03 -04:00
end
end
2012-09-16 07:44:54 -04:00
def unblock
2015-12-29 15:58:38 -05:00
if user . ldap_blocked?
2019-03-21 09:31:05 -04:00
redirect_back_or_admin_user ( alert : _ ( " This user cannot be unlocked manually from GitLab " ) )
2017-06-15 04:57:27 -04:00
elsif update_user { | user | user . activate }
2019-03-21 09:31:05 -04:00
redirect_back_or_admin_user ( notice : _ ( " Successfully unblocked " ) )
2012-09-16 07:44:54 -04:00
else
2019-03-21 09:31:05 -04:00
redirect_back_or_admin_user ( alert : _ ( " Error occurred. User was not unblocked " ) )
2012-04-16 16:33:03 -04:00
end
end
2021-05-14 14:10:34 -04:00
def ban
result = Users :: BanService . new ( current_user ) . execute ( user )
if result [ :status ] == :success
redirect_back_or_admin_user ( notice : _ ( " Successfully banned " ) )
else
redirect_back_or_admin_user ( alert : _ ( " Error occurred. User was not banned " ) )
end
end
def unban
2021-08-02 11:08:56 -04:00
result = Users :: UnbanService . new ( current_user ) . execute ( user )
if result [ :status ] == :success
2021-05-14 14:10:34 -04:00
redirect_back_or_admin_user ( notice : _ ( " Successfully unbanned " ) )
else
redirect_back_or_admin_user ( alert : _ ( " Error occurred. User was not unbanned " ) )
end
end
2015-07-02 01:26:14 -04:00
def unlock
2017-06-15 04:57:27 -04:00
if update_user { | user | user . unlock_access! }
2021-08-16 05:09:05 -04:00
redirect_back_or_admin_user ( notice : _ ( " Successfully unlocked " ) )
2015-07-02 01:26:14 -04:00
else
2019-03-21 09:31:05 -04:00
redirect_back_or_admin_user ( alert : _ ( " Error occurred. User was not unlocked " ) )
2015-07-02 01:26:14 -04:00
end
end
2015-07-29 10:32:01 -04:00
def confirm
2017-06-15 04:57:27 -04:00
if update_user { | user | user . confirm }
2019-03-21 09:31:05 -04:00
redirect_back_or_admin_user ( notice : _ ( " Successfully confirmed " ) )
2015-07-29 10:32:01 -04:00
else
2019-03-21 09:31:05 -04:00
redirect_back_or_admin_user ( alert : _ ( " Error occurred. User was not confirmed " ) )
2015-07-29 10:32:01 -04:00
end
end
2015-07-10 17:11:18 -04:00
def disable_two_factor
2020-08-20 11:10:18 -04:00
result = TwoFactor :: DestroyService . new ( current_user , user : user ) . execute
2017-06-15 04:57:27 -04:00
2020-08-20 11:10:18 -04:00
if result [ :status ] == :success
redirect_to admin_user_path ( user ) ,
notice : _ ( 'Two-factor authentication has been disabled for this user' )
else
redirect_to admin_user_path ( user ) , alert : result [ :message ]
end
2015-07-10 17:11:18 -04:00
end
2011-10-08 17:36:38 -04:00
def create
2013-06-13 14:06:27 -04:00
opts = {
2017-03-27 05:37:24 -04:00
reset_password : true ,
skip_confirmation : true
2013-06-13 14:06:27 -04:00
}
2017-03-27 05:37:24 -04:00
@user = Users :: CreateService . new ( current_user , user_params . merge ( opts ) ) . execute
2011-10-08 17:36:38 -04:00
respond_to do | format |
2017-03-27 05:37:24 -04:00
if @user . persisted?
2019-03-21 09:31:05 -04:00
format . html { redirect_to [ :admin , @user ] , notice : _ ( 'User was successfully created.' ) }
2013-06-26 08:57:02 -04:00
format . json { render json : @user , status : :created , location : @user }
2011-10-08 17:36:38 -04:00
else
2013-06-22 08:08:11 -04:00
format . html { render " new " }
2013-06-26 08:57:02 -04:00
format . json { render json : @user . errors , status : :unprocessable_entity }
2011-10-08 17:36:38 -04:00
end
end
end
def update
2014-07-16 08:12:33 -04:00
user_params_with_pass = user_params . dup
2014-06-26 16:24:17 -04:00
if params [ :user ] [ :password ] . present?
2017-08-29 10:15:48 -04:00
password_params = {
2014-06-26 16:24:17 -04:00
password : params [ :user ] [ :password ] ,
2017-08-29 10:15:48 -04:00
password_confirmation : params [ :user ] [ :password_confirmation ]
}
2020-09-04 05:08:38 -04:00
password_params [ :password_expires_at ] = Time . current if admin_making_changes_for_another_user?
2017-08-29 10:15:48 -04:00
user_params_with_pass . merge! ( password_params )
2014-02-25 03:15:43 -05:00
end
2011-10-08 17:36:38 -04:00
2021-05-24 11:10:27 -04:00
cc_validation_params = process_credit_card_validation_params ( user_params_with_pass . delete ( :credit_card_validation_attributes ) )
user_params_with_pass . merge! ( cc_validation_params )
2011-10-08 17:36:38 -04:00
respond_to do | format |
2017-09-27 05:48:33 -04:00
result = Users :: UpdateService . new ( current_user , user_params_with_pass . merge ( user : user ) ) . execute do | user |
2017-06-22 05:37:36 -04:00
user . skip_reconfirmation!
2020-09-04 05:08:38 -04:00
user . send_only_admin_changed_your_password_notification! if admin_making_changes_for_another_user?
2017-06-22 05:37:36 -04:00
end
2017-06-14 11:41:19 -04:00
2017-06-15 04:57:27 -04:00
if result [ :status ] == :success
2019-03-21 09:31:05 -04:00
format . html { redirect_to [ :admin , user ] , notice : _ ( 'User was successfully updated.' ) }
2011-10-08 17:36:38 -04:00
format . json { head :ok }
else
2013-03-26 01:42:08 -04:00
# restore username to keep form action url.
2013-06-26 08:57:02 -04:00
user . username = params [ :id ]
2013-06-22 08:08:11 -04:00
format . html { render " edit " }
2020-10-16 11:08:46 -04:00
format . json { render json : [ result [ :message ] ] , status : :internal_server_error }
2011-10-08 17:36:38 -04:00
end
end
end
def destroy
2020-10-01 14:10:20 -04:00
user . delete_async ( deleted_by : current_user , params : destroy_params )
2011-10-08 17:36:38 -04:00
respond_to do | format |
2019-11-17 07:06:19 -05:00
format . html { redirect_to admin_users_path , status : :found , notice : _ ( " The user is being deleted. " ) }
2011-10-08 17:36:38 -04:00
format . json { head :ok }
end
end
2013-01-25 13:38:24 -05:00
2014-06-23 03:45:26 -04:00
def remove_email
email = user . emails . find ( params [ :email_id ] )
2017-10-05 06:48:22 -04:00
success = Emails :: DestroyService . new ( current_user , user : user ) . execute ( email )
2015-02-06 18:23:58 -05:00
2017-06-16 03:30:24 -04:00
respond_to do | format |
2017-06-22 05:27:37 -04:00
if success
2019-03-21 09:31:05 -04:00
format . html { redirect_back_or_admin_user ( notice : _ ( 'Successfully removed email.' ) ) }
2017-06-16 03:30:24 -04:00
format . json { head :ok }
else
2019-03-21 09:31:05 -04:00
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 : :bad_request }
2017-06-16 03:30:24 -04:00
end
2014-06-23 03:45:26 -04:00
end
end
2013-01-25 13:38:24 -05:00
protected
2021-05-24 11:10:27 -04:00
def process_credit_card_validation_params ( cc_validation_params )
return unless cc_validation_params && cc_validation_params [ :credit_card_validated_at ]
cc_validation = cc_validation_params [ :credit_card_validated_at ]
if cc_validation == " 1 " && ! user . credit_card_validated_at
{
credit_card_validation_attributes : {
credit_card_validated_at : Time . zone . now
}
}
elsif cc_validation == " 0 " && user . credit_card_validated_at
{
credit_card_validation_attributes : {
_destroy : true
}
}
end
end
2021-04-22 08:09:49 -04:00
def paginate_without_count?
counts = Gitlab :: Database :: Count . approximate_counts ( [ User ] )
counts [ User ] > PAGINATION_WITH_COUNT_LIMIT
end
2021-04-13 20:10:39 -04:00
def users_with_included_associations ( users )
users . includes ( :authorized_projects ) # rubocop: disable CodeReuse/ActiveRecord
end
2020-09-04 05:08:38 -04:00
def admin_making_changes_for_another_user?
user != current_user
2017-08-29 10:15:48 -04:00
end
2020-10-01 14:10:20 -04:00
def destroy_params
params . permit ( :hard_delete )
end
def ensure_destroy_prerequisites_met
return if hard_delete?
if user . solo_owned_groups . present?
message = s_ ( 'AdminUsers|You must transfer ownership or delete the groups owned by this user before you can delete their account' )
redirect_to admin_user_path ( user ) , status : :see_other , alert : message
end
end
def hard_delete?
destroy_params [ :hard_delete ]
end
2013-06-26 08:57:02 -04:00
def user
2021-08-19 11:10:29 -04:00
@user || = find_routable! ( User , params [ :id ] , request . fullpath )
2019-02-12 17:26:07 -05:00
end
def build_canonical_path ( user )
url_for ( safe_params . merge ( id : user . to_param ) )
2013-01-25 13:38:24 -05:00
end
2014-06-26 08:11:45 -04:00
2015-10-20 03:28:28 -04:00
def redirect_back_or_admin_user ( options = { } )
redirect_back_or_default ( default : default_route , options : options )
end
def default_route
[ :admin , @user ]
end
2017-01-10 08:53:20 -05:00
def user_params
2018-06-25 09:11:00 -04:00
params . require ( :user ) . permit ( allowed_user_params )
2017-01-10 08:53:20 -05:00
end
2018-06-25 09:11:00 -04:00
def allowed_user_params
2017-01-10 08:53:20 -05:00
[
2017-02-06 16:38:08 -05:00
:access_level ,
2017-01-10 08:53:20 -05:00
:avatar ,
:bio ,
:can_create_group ,
:color_scheme_id ,
:email ,
:extern_uid ,
:external ,
:force_random_password ,
:hide_no_password ,
:hide_no_ssh_key ,
:key_id ,
:linkedin ,
:name ,
:password_expires_at ,
:projects_limit ,
:provider ,
:remember_me ,
:skype ,
2017-09-11 11:44:42 -04:00
:theme_id ,
2017-01-10 08:53:20 -05:00
:twitter ,
:username ,
2020-05-28 05:08:05 -04:00
:website_url ,
2021-05-24 11:10:27 -04:00
:note ,
credit_card_validation_attributes : [ :credit_card_validated_at ]
2017-01-10 08:53:20 -05:00
]
end
2017-06-15 04:57:27 -04:00
2017-06-23 11:11:31 -04:00
def update_user ( & block )
2017-09-27 05:48:33 -04:00
result = Users :: UpdateService . new ( current_user , user : user ) . execute ( & block )
2017-06-15 04:57:27 -04:00
result [ :status ] == :success
end
2018-11-24 07:39:16 -05:00
def check_impersonation_availability
access_denied! unless Gitlab . config . gitlab . impersonation_enabled
end
2019-07-23 02:14:09 -04:00
2021-05-14 14:10:34 -04:00
def check_ban_user_feature_flag
access_denied! unless Feature . enabled? ( :ban_user_feature_flag )
end
2019-07-23 02:14:09 -04:00
def log_impersonation_event
Gitlab :: AppLogger . info ( _ ( " User %{current_user_username} has started impersonating %{username} " ) % { current_user_username : current_user . username , username : user . username } )
end
2011-10-08 17:36:38 -04:00
end
2019-09-13 09:26:31 -04:00
2021-05-11 17:10:21 -04:00
Admin :: UsersController . prepend_mod_with ( 'Admin::UsersController' )