2013-02-14 12:57:26 -05:00
require_dependency 'discourse_hub'
2013-06-06 16:40:10 +02:00
require_dependency 'user_name_suggester'
2014-09-18 10:48:56 -04:00
require_dependency 'rate_limiter'
2013-02-05 14:16:51 -05:00
class UsersController < ApplicationController
2013-08-14 12:20:05 +02:00
skip_before_filter :authorize_mini_profiler , only : [ :avatar ]
2016-03-07 14:40:11 -05:00
skip_before_filter :check_xhr , only : [ :show , :password_reset , :update , :account_created , :activate_account , :perform_account_activation , :user_preferences_redirect , :avatar , :my_redirect , :toggle_anon , :admin_login ]
2013-02-05 14:16:51 -05:00
2016-08-12 16:35:10 +10:00
before_filter :ensure_logged_in , only : [ :username , :update , :user_preferences_redirect , :upload_user_image ,
:pick_avatar , :destroy_user_image , :destroy , :check_emails , :topic_tracking_state ]
2013-11-12 14:37:38 -08:00
before_filter :respond_to_suspicious_request , only : [ :create ]
2013-02-07 16:45:24 +01:00
2013-05-22 11:20:16 -04:00
# we need to allow account creation with bad CSRF tokens, if people are caching, the CSRF token on the
2013-05-03 16:43:11 +10:00
# page is going to be empty, this means that server will see an invalid CSRF and blow the session
# once that happens you can't log in with social
2013-06-05 14:01:24 +10:00
skip_before_filter :verify_authenticity_token , only : [ :create ]
2013-07-15 12:12:54 -04:00
skip_before_filter :redirect_to_login_if_required , only : [ :check_username ,
:create ,
:get_honeypot_value ,
2014-09-23 19:20:57 +05:30
:account_created ,
2013-07-15 12:12:54 -04:00
:activate_account ,
2014-07-15 10:47:47 -07:00
:perform_account_activation ,
2013-07-15 12:12:54 -04:00
:send_activation_email ,
2015-04-27 16:29:48 +05:30
:password_reset ,
2016-01-04 11:48:54 -05:00
:confirm_email_token ,
2015-04-27 16:29:48 +05:30
:admin_login ]
2013-05-03 16:43:11 +10:00
2015-03-19 11:48:16 -04:00
def index
end
2013-02-07 16:45:24 +01:00
def show
2015-10-28 19:56:08 +01:00
raise Discourse :: InvalidAccess if SiteSetting . hide_user_profiles_from_public && ! current_user
2016-09-23 12:44:08 +08:00
@user = fetch_user_from_params (
{ include_inactive : current_user . try ( :staff? ) } ,
[ { user_profile : :card_image_badge } ]
)
2013-03-08 15:04:37 -05:00
user_serializer = UserSerializer . new ( @user , scope : guardian , root : 'user' )
2015-12-17 18:06:04 +11:00
# TODO remove this options from serializer
user_serializer . omit_stats = true
2015-03-24 12:33:17 -04:00
topic_id = params [ :include_post_count_for ] . to_i
if topic_id != 0
user_serializer . topic_post_count = { topic_id = > Post . where ( topic_id : topic_id , user_id : @user . id ) . count }
end
2015-09-14 15:51:17 +08:00
if ! params [ :skip_track_visit ] && ( @user != current_user )
track_visit_to_user_profile
end
2015-02-02 12:55:32 -05:00
# This is a hack to get around a Rails issue where values with periods aren't handled correctly
# when used as part of a route.
if params [ :external_id ] and params [ :external_id ] . ends_with? '.json'
return render_json_dump ( user_serializer )
end
2013-03-08 15:04:37 -05:00
respond_to do | format |
format . html do
2014-11-27 19:51:13 +01:00
@restrict_fields = guardian . restrict_user_fields? ( @user )
2013-03-08 15:04:37 -05:00
store_preloaded ( " user_ #{ @user . username } " , MultiJson . dump ( user_serializer ) )
end
format . json do
render_json_dump ( user_serializer )
end
2013-02-05 14:16:51 -05:00
end
end
2014-10-20 13:15:58 -04:00
def card_badge
end
def update_card_badge
user = fetch_user_from_params
guardian . ensure_can_edit! ( user )
user_badge = UserBadge . find_by ( id : params [ :user_badge_id ] . to_i )
if user_badge && user_badge . user == user && user_badge . badge . image . present?
user . user_profile . update_column ( :card_image_badge_id , user_badge . badge . id )
else
user . user_profile . update_column ( :card_image_badge_id , nil )
end
render nothing : true
end
2013-02-05 14:16:51 -05:00
def user_preferences_redirect
redirect_to email_preferences_path ( current_user . username_lower )
end
def update
2013-10-07 11:19:45 +01:00
user = fetch_user_from_params
2013-02-05 14:16:51 -05:00
guardian . ensure_can_edit! ( user )
2014-09-26 14:48:34 -04:00
if params [ :user_fields ] . present?
2015-02-06 09:03:23 +11:00
params [ :custom_fields ] = { } unless params [ :custom_fields ] . present?
2015-03-20 15:18:43 -04:00
fields = UserField . all
fields = fields . where ( editable : true ) unless current_user . staff?
fields . each do | f |
2014-10-08 14:38:18 -04:00
val = params [ :user_fields ] [ f . id . to_s ]
2014-10-02 15:56:28 -04:00
val = nil if val === " false "
2015-02-23 13:02:30 -05:00
val = val [ 0 ... UserField . max_length ] if val
2014-10-08 14:38:18 -04:00
return render_json_error ( I18n . t ( " login.missing_user_field " ) ) if val . blank? && f . required?
params [ :custom_fields ] [ " user_field_ #{ f . id } " ] = val
2014-09-26 14:48:34 -04:00
end
end
2014-09-08 15:17:31 -04:00
json_result ( user , serializer : UserSerializer , additional_errors : [ :user_profile ] ) do | u |
2013-12-10 12:46:35 -05:00
updater = UserUpdater . new ( current_user , user )
2013-11-01 14:06:20 -07:00
updater . update ( params )
2013-02-07 16:45:24 +01:00
end
2013-02-05 14:16:51 -05:00
end
def username
2013-06-06 00:14:32 -07:00
params . require ( :new_username )
2013-02-05 14:16:51 -05:00
user = fetch_user_from_params
2013-08-12 14:54:52 -04:00
guardian . ensure_can_edit_username! ( user )
2013-02-07 16:45:24 +01:00
2015-01-16 14:30:46 -08:00
# TODO proper error surfacing (result is a Model#save call)
2015-03-06 16:44:54 -05:00
result = UsernameChanger . change ( user , params [ :new_username ] , current_user )
2013-02-05 14:16:51 -05:00
raise Discourse :: InvalidParameters . new ( :new_username ) unless result
2014-12-10 09:43:16 -07:00
render json : {
id : user . id ,
username : user . username
}
2013-02-05 14:16:51 -05:00
end
2014-09-29 22:31:05 +02:00
def check_emails
2014-10-29 01:06:59 +01:00
user = fetch_user_from_params ( include_inactive : true )
2014-09-29 22:31:05 +02:00
guardian . ensure_can_check_emails! ( user )
StaffActionLogger . new ( current_user ) . log_check_email ( user , context : params [ :context ] )
render json : {
email : user . email ,
associated_accounts : user . associated_accounts
}
2014-10-08 10:26:18 +11:00
rescue Discourse :: InvalidAccess
2014-09-29 22:31:05 +02:00
render json : failed_json , status : 403
end
2016-08-12 16:35:10 +10:00
def topic_tracking_state
user = fetch_user_from_params
guardian . ensure_can_edit! ( user )
report = TopicTrackingState . report ( user . id )
serializer = ActiveModel :: ArraySerializer . new ( report , each_serializer : TopicTrackingStateSerializer )
render json : MultiJson . dump ( serializer )
end
2014-04-18 08:40:53 +05:30
def badge_title
params . require ( :user_badge_id )
user = fetch_user_from_params
guardian . ensure_can_edit! ( user )
2014-07-14 18:06:50 +10:00
user_badge = UserBadge . find_by ( id : params [ :user_badge_id ] )
if user_badge && user_badge . user == user && user_badge . badge . allow_title?
2014-04-18 08:40:53 +05:30
user . title = user_badge . badge . name
2014-10-08 10:26:18 +11:00
user . user_profile . badge_granted_title = true
2014-04-18 08:40:53 +05:30
user . save!
2014-10-08 10:26:18 +11:00
user . user_profile . save!
2014-07-14 18:06:50 +10:00
else
user . title = ''
user . save!
2014-04-18 08:40:53 +05:30
end
render nothing : true
end
2013-02-05 14:16:51 -05:00
def preferences
render nothing : true
end
2014-04-21 11:52:11 -04:00
def my_redirect
2016-03-19 17:33:10 +05:30
raise Discourse :: NotFound if params [ :path ] !~ / ^[a-z_ \ - \/ ]+$ /
2015-10-14 12:40:13 -04:00
if current_user . blank?
cookies [ :destination_url ] = " /my/ #{ params [ :path ] } "
2015-10-14 13:39:31 -04:00
redirect_to " /login-preferences "
2015-10-14 12:40:13 -04:00
else
redirect_to ( path ( " /users/ #{ current_user . username } / #{ params [ :path ] } " ) )
2014-04-21 11:52:11 -04:00
end
end
2016-01-20 15:11:52 +11:00
def summary
user = fetch_user_from_params
summary = UserSummary . new ( user , guardian )
serializer = UserSummarySerializer . new ( summary , scope : guardian )
render_json_dump ( serializer )
end
2013-02-05 14:16:51 -05:00
def invited
2013-11-08 11:11:41 -08:00
inviter = fetch_user_from_params
2014-08-01 16:36:31 +05:30
offset = params [ :offset ] . to_i || 0
2015-07-11 17:39:12 +05:30
filter_by = params [ :filter ]
2013-11-05 17:52:50 -05:00
2015-07-11 17:39:12 +05:30
invites = if guardian . can_see_invite_details? ( inviter ) && filter_by == " pending "
Invite . find_pending_invites_from ( inviter , offset )
2013-11-08 11:11:41 -08:00
else
2014-08-01 16:36:31 +05:30
Invite . find_redeemed_invites_from ( inviter , offset )
2013-11-05 17:52:50 -05:00
end
2015-07-11 17:39:12 +05:30
invites = invites . filter_by ( params [ :search ] )
2014-03-21 14:13:04 -04:00
render_json_dump invites : serialize_data ( invites . to_a , InviteSerializer ) ,
can_see_invite_details : guardian . can_see_invite_details? ( inviter )
2013-02-05 14:16:51 -05:00
end
2015-08-25 00:33:25 +05:30
def invited_count
inviter = fetch_user_from_params
pending_count = Invite . find_pending_invites_count ( inviter )
redeemed_count = Invite . find_redeemed_invites_count ( inviter )
render json : { counts : { pending : pending_count , redeemed : redeemed_count ,
total : ( pending_count . to_i + redeemed_count . to_i ) } }
end
2013-02-05 14:16:51 -05:00
def is_local_username
2015-11-27 18:16:50 +01:00
usernames = params [ :usernames ]
usernames = [ params [ :username ] ] if usernames . blank?
2015-06-12 00:31:43 +10:00
2015-11-30 17:12:51 +11:00
groups = Group . where ( name : usernames ) . pluck ( :name )
2015-12-04 13:40:38 +11:00
mentionable_groups =
if current_user
Group . mentionable ( current_user )
. where ( name : usernames )
. pluck ( :name , :user_count )
. map { | name , user_count | { name : name , user_count : user_count } }
end
2015-11-30 17:12:51 +11:00
usernames -= groups
2016-05-22 18:31:46 +05:30
usernames . each ( & :downcase! )
2015-11-30 17:12:51 +11:00
result = User . where ( staged : false )
. where ( username_lower : usernames )
. pluck ( :username_lower )
2015-11-27 18:16:50 +01:00
2015-12-04 13:40:38 +11:00
render json : { valid : result , valid_groups : groups , mentionable_groups : mentionable_groups }
2013-02-05 14:16:51 -05:00
end
2013-08-24 22:57:12 -10:00
def render_available_true
render ( json : { available : true } )
end
def changing_case_of_own_username ( target_user , username )
target_user and username . downcase == target_user . username . downcase
end
# Used for checking availability of a username and will return suggestions
# if the username is not available.
2013-02-05 14:16:51 -05:00
def check_username
2013-11-19 14:15:05 -05:00
if ! params [ :username ] . present?
params . require ( :username ) if ! params [ :email ] . present?
2014-07-16 12:25:24 -04:00
return render ( json : success_json )
2013-11-19 14:15:05 -05:00
end
2013-08-24 22:57:12 -10:00
username = params [ :username ]
2013-02-05 14:16:51 -05:00
2013-08-24 22:57:12 -10:00
target_user = user_from_params_or_current_user
2013-07-30 14:13:56 -04:00
2013-06-28 16:21:46 -04:00
# The special case where someone is changing the case of their own username
2013-08-24 22:57:12 -10:00
return render_available_true if changing_case_of_own_username ( target_user , username )
2013-06-28 16:21:46 -04:00
2013-09-06 09:35:29 +00:00
checker = UsernameCheckerService . new
email = params [ :email ] || target_user . try ( :email )
2013-11-19 14:15:05 -05:00
render json : checker . check_username ( username , email )
2013-08-24 22:57:12 -10:00
end
2013-02-05 14:16:51 -05:00
2013-08-24 22:57:12 -10:00
def user_from_params_or_current_user
params [ :for_user_id ] ? User . find ( params [ :for_user_id ] ) : current_user
end
2013-02-05 14:16:51 -05:00
def create
2014-09-26 14:48:34 -04:00
params . permit ( :user_fields )
2014-07-14 15:42:14 -04:00
unless SiteSetting . allow_new_registrations
2014-09-26 14:48:34 -04:00
return fail_with ( " login.new_registrations_disabled " )
2014-07-14 15:42:14 -04:00
end
2014-09-11 12:22:11 -07:00
if params [ :password ] && params [ :password ] . length > User . max_password_length
2014-09-26 14:48:34 -04:00
return fail_with ( " login.password_too_long " )
2014-09-11 12:22:11 -07:00
end
2015-07-13 13:40:52 -07:00
if params [ :email ] && params [ :email ] . length > 254 + 1 + 253
return fail_with ( " login.email_too_long " )
end
2015-07-06 23:54:25 -07:00
if SiteSetting . reserved_usernames . split ( " | " ) . include? params [ :username ] . downcase
2015-07-01 13:44:53 -07:00
return fail_with ( " login.reserved_username " )
end
2015-11-13 19:07:28 +01:00
if user = User . where ( staged : true ) . find_by ( email : params [ :email ] . strip . downcase )
user_params . each { | k , v | user . send ( " #{ k } = " , v ) }
user . staged = false
else
user = User . new ( user_params )
end
2013-02-06 19:25:21 -05:00
2014-09-26 14:48:34 -04:00
# Handle custom fields
2014-10-08 14:38:18 -04:00
user_fields = UserField . all
if user_fields . present?
2015-01-27 11:48:27 +02:00
field_params = params [ :user_fields ] || { }
fields = user . custom_fields
user_fields . each do | f |
field_val = field_params [ f . id . to_s ]
if field_val . blank?
return fail_with ( " login.missing_user_field " ) if f . required?
else
2015-02-23 13:02:30 -05:00
fields [ " user_field_ #{ f . id } " ] = field_val [ 0 ... UserField . max_length ]
2014-09-26 14:48:34 -04:00
end
end
2015-01-27 11:48:27 +02:00
user . custom_fields = fields
2014-09-26 14:48:34 -04:00
end
2013-11-12 14:37:38 -08:00
authentication = UserAuthenticator . new ( user , session )
2014-03-26 15:39:44 +11:00
if ! authentication . has_authenticator? && ! SiteSetting . enable_local_logins
2014-11-17 12:04:29 +01:00
return render nothing : true , status : 500
2014-03-26 15:39:44 +11:00
end
2013-11-12 14:37:38 -08:00
authentication . start
2013-02-05 14:16:51 -05:00
2013-11-12 14:37:38 -08:00
activation = UserActivator . new ( user , request , session , cookies )
activation . start
2013-02-05 14:16:51 -05:00
2014-03-20 14:49:25 +11:00
# just assign a password if we have an authenticator and no password
# this is the case for Twitter
user . password = SecureRandom . hex if user . password . blank? && authentication . has_authenticator?
2013-11-12 14:37:38 -08:00
if user . save
authentication . finish
activation . finish
2014-10-01 23:03:49 +05:30
# save user email in session, to show on account-created page
2014-11-04 15:47:32 -05:00
session [ " user_created_message " ] = activation . message
2014-09-26 14:48:34 -04:00
2013-11-12 14:37:38 -08:00
render json : {
success : true ,
active : user . active? ,
2014-09-23 09:06:19 +10:00
message : activation . message ,
user_id : user . id
2013-11-12 14:37:38 -08:00
}
else
render json : {
success : false ,
message : I18n . t (
'login.errors' ,
errors : user . errors . full_messages . join ( " \n " )
) ,
errors : user . errors . to_hash ,
2016-03-03 23:31:31 +05:30
values : user . attributes . slice ( 'name' , 'username' , 'email' ) ,
2016-08-05 11:57:13 -04:00
is_developer : UsernameCheckerService . is_developer? ( user . email )
2013-11-12 14:37:38 -08:00
}
end
2013-03-07 14:56:28 -05:00
rescue ActiveRecord :: StatementInvalid
2013-11-12 14:37:38 -08:00
render json : {
success : false ,
message : I18n . t ( " login.something_already_taken " )
}
2013-02-05 14:16:51 -05:00
rescue RestClient :: Forbidden
2013-04-13 00:46:55 +02:00
render json : { errors : [ I18n . t ( " discourse_hub.access_token_problem " ) ] }
2013-02-05 14:16:51 -05:00
end
2013-02-06 19:25:21 -05:00
def get_honeypot_value
render json : { value : honeypot_value , challenge : challenge_value }
end
2013-02-05 14:16:51 -05:00
def password_reset
2015-02-20 10:28:38 +11:00
expires_now
2013-02-05 14:16:51 -05:00
2014-08-25 15:30:52 -04:00
if EmailToken . valid_token_format? ( params [ :token ] )
2016-01-04 11:48:54 -05:00
if request . put?
@user = EmailToken . confirm ( params [ :token ] )
else
email_token = EmailToken . confirmable ( params [ :token ] )
@user = email_token . try ( :user )
end
2014-08-25 15:30:52 -04:00
if @user
session [ " password- #{ params [ :token ] } " ] = @user . id
else
user_id = session [ " password- #{ params [ :token ] } " ]
@user = User . find ( user_id ) if user_id
end
2014-07-02 13:06:55 +10:00
else
2014-08-25 15:30:52 -04:00
@invalid_token = true
2014-07-02 13:06:55 +10:00
end
if ! @user
2015-02-20 10:28:38 +11:00
@error = I18n . t ( 'password_reset.no_token' )
2013-11-11 22:28:26 +11:00
elsif request . put?
2014-09-11 12:22:11 -07:00
@invalid_password = params [ :password ] . blank? || params [ :password ] . length > User . max_password_length
if @invalid_password
@user . errors . add ( :password , :invalid )
else
@user . password = params [ :password ]
@user . password_required!
2015-04-15 08:57:43 +10:00
@user . auth_token = nil
2014-09-11 12:22:11 -07:00
if @user . save
Invite . invalidate_for_email ( @user . email ) # invite link can't be used to log in anymore
logon_after_password_reset
end
2014-01-21 16:53:46 -05:00
end
2013-02-05 14:16:51 -05:00
end
2015-01-15 15:56:53 -05:00
render layout : 'no_ember'
2013-02-05 14:16:51 -05:00
end
2013-02-07 16:45:24 +01:00
2016-01-04 11:48:54 -05:00
def confirm_email_token
expires_now
EmailToken . confirm ( params [ :token ] )
render json : success_json
end
2013-10-07 11:19:45 +01:00
def logon_after_password_reset
2013-11-11 23:21:14 +05:30
message = if Guardian . new ( @user ) . can_access_forum?
# Log in the user
log_on_user ( @user )
'password_reset.success'
else
@requires_approval = true
'password_reset.success_unapproved'
end
2015-02-20 10:28:38 +11:00
@success = I18n . t ( message )
2014-07-03 17:29:44 +10:00
end
2013-10-07 11:19:45 +01:00
2015-04-27 16:29:48 +05:30
def admin_login
2015-06-05 18:43:59 +10:00
if current_user
2015-04-27 16:29:48 +05:30
return redirect_to path ( " / " )
end
if request . put?
RateLimiter . new ( nil , " admin-login-hr- #{ request . remote_ip } " , 6 , 1 . hour ) . performed!
RateLimiter . new ( nil , " admin-login-min- #{ request . remote_ip } " , 3 , 1 . minute ) . performed!
user = User . where ( email : params [ :email ] , admin : true ) . where . not ( id : Discourse :: SYSTEM_USER_ID ) . first
if user
email_token = user . email_tokens . create ( email : user . email )
2016-04-07 14:38:43 +10:00
Jobs . enqueue ( :critical_user_email , type : :admin_login , user_id : user . id , email_token : email_token . token )
2015-04-27 16:29:48 +05:30
@message = I18n . t ( " admin_login.success " )
else
@message = I18n . t ( " admin_login.error " )
end
elsif params [ :token ] . present?
# token recieved, try to login
if EmailToken . valid_token_format? ( params [ :token ] )
@user = EmailToken . confirm ( params [ :token ] )
if @user && @user . admin?
# Log in user
log_on_user ( @user )
return redirect_to path ( " / " )
else
@message = I18n . t ( " admin_login.error " )
end
else
@message = I18n . t ( " admin_login.error " )
end
end
render layout : false
rescue RateLimiter :: LimitExceeded
@message = I18n . t ( " rate_limiter.slow_down " )
render layout : false
end
2015-04-07 18:02:10 +10:00
def toggle_anon
user = AnonymousShadowCreator . get_master ( current_user ) ||
AnonymousShadowCreator . get ( current_user )
if user
log_on_user ( user )
render json : success_json
else
render json : failed_json , status : 403
end
end
2014-09-23 19:20:57 +05:30
def account_created
2016-05-05 14:37:09 -04:00
@custom_body_class = " static-account-created "
2015-05-07 11:00:22 +10:00
@message = session [ 'user_created_message' ] || I18n . t ( 'activation.missing_session' )
2014-09-23 19:20:57 +05:30
expires_now
2015-01-15 15:56:53 -05:00
render layout : 'no_ember'
2014-09-23 19:20:57 +05:30
end
2013-02-05 14:16:51 -05:00
def activate_account
2014-07-15 10:47:47 -07:00
expires_now
2015-01-15 15:56:53 -05:00
render layout : 'no_ember'
2014-07-14 12:25:42 -04:00
end
def perform_account_activation
2014-07-15 14:07:19 -04:00
raise Discourse :: InvalidAccess . new if honeypot_or_challenge_fails? ( params )
2013-02-05 14:16:51 -05:00
if @user = EmailToken . confirm ( params [ :token ] )
# Log in the user unless they need to be approved
2013-04-03 12:23:28 -04:00
if Guardian . new ( @user ) . can_access_forum?
2013-02-05 14:16:51 -05:00
@user . enqueue_welcome_message ( 'welcome_user' ) if @user . send_welcome_message
log_on_user ( @user )
2013-04-03 12:23:28 -04:00
else
@needs_approval = true
2013-02-05 14:16:51 -05:00
end
else
2015-08-24 00:29:16 +05:30
flash . now [ :error ] = I18n . t ( 'activation.already_done' )
2013-02-05 14:16:51 -05:00
end
2015-01-15 15:56:53 -05:00
render layout : 'no_ember'
2013-02-05 14:16:51 -05:00
end
2013-02-22 11:49:48 -05:00
def send_activation_email
2015-10-27 16:25:30 -04:00
if current_user . blank? || ! current_user . staff?
RateLimiter . new ( nil , " activate-hr- #{ request . remote_ip } " , 30 , 1 . hour ) . performed!
RateLimiter . new ( nil , " activate-min- #{ request . remote_ip } " , 6 , 1 . minute ) . performed!
end
2014-09-25 17:42:48 +10:00
@user = User . find_by_username_or_email ( params [ :username ] . to_s )
2014-09-25 17:45:45 +10:00
raise Discourse :: NotFound unless @user
2013-02-22 11:49:48 -05:00
@email_token = @user . email_tokens . unconfirmed . active . first
2013-10-07 11:19:45 +01:00
enqueue_activation_email if @user
2013-02-22 11:49:48 -05:00
render nothing : true
end
2013-10-07 11:19:45 +01:00
def enqueue_activation_email
@email_token || = @user . email_tokens . create ( email : @user . email )
2016-04-07 14:38:43 +10:00
Jobs . enqueue ( :critical_user_email , type : :signup , user_id : @user . id , email_token : @email_token . token )
2013-10-07 11:19:45 +01:00
end
2013-02-05 14:16:51 -05:00
def search_users
2013-02-07 05:59:25 -05:00
term = params [ :term ] . to_s . strip
2013-02-05 14:16:51 -05:00
topic_id = params [ :topic_id ]
topic_id = topic_id . to_i if topic_id
2015-04-13 20:33:13 +05:30
topic_allowed_users = params [ :topic_allowed_users ] || false
2013-02-05 14:16:51 -05:00
2015-04-13 20:33:13 +05:30
results = UserSearch . new ( term , topic_id : topic_id , topic_allowed_users : topic_allowed_users , searching_user : current_user ) . search
2013-02-05 14:16:51 -05:00
2015-09-11 15:04:29 +02:00
user_fields = [ :username , :upload_avatar_template ]
2013-10-30 15:45:13 -04:00
user_fields << :name if SiteSetting . enable_names?
2015-09-11 18:14:34 +10:00
to_render = { users : results . as_json ( only : user_fields , methods : [ :avatar_template ] ) }
2013-12-23 15:46:00 +01:00
if params [ :include_groups ] == " true "
2015-11-30 17:03:47 +11:00
to_render [ :groups ] = Group . search_group ( term ) . map do | m |
{ name : m . name , usernames : [ ] }
end
2013-12-23 15:46:00 +01:00
end
2015-12-02 15:49:43 +11:00
if params [ :include_mentionable_groups ] == " true " && current_user
to_render [ :groups ] = Group . mentionable ( current_user )
. where ( " name ILIKE :term_like " , term_like : " #{ term } % " )
. map do | m |
{ name : m . name , usernames : [ ] }
end
end
2013-12-23 15:46:00 +01:00
render json : to_render
2013-02-05 14:16:51 -05:00
end
2015-09-17 19:42:44 +02:00
AVATAR_TYPES_WITH_UPLOAD || = %w{ uploaded custom gravatar }
2014-05-26 19:46:43 +10:00
def pick_avatar
2013-08-13 22:08:29 +02:00
user = fetch_user_from_params
guardian . ensure_can_edit! ( user )
2015-05-29 10:21:41 +02:00
2015-09-11 15:04:29 +02:00
type = params [ :type ]
2015-09-11 15:47:48 +02:00
upload_id = params [ :upload_id ]
2014-05-26 19:46:43 +10:00
2015-11-12 10:26:45 +01:00
if SiteSetting . sso_overrides_avatar
return render json : failed_json , status : 422
end
if ! SiteSetting . allow_uploaded_avatars
if type == " uploaded " || type == " custom "
return render json : failed_json , status : 422
end
end
2015-09-11 15:04:29 +02:00
user . uploaded_avatar_id = upload_id
2015-09-11 15:47:48 +02:00
2015-09-17 19:42:44 +02:00
if AVATAR_TYPES_WITH_UPLOAD . include? ( type )
# make sure the upload exists
unless Upload . where ( id : upload_id ) . exists?
return render_json_error I18n . t ( " avatar.missing " )
end
if type == " gravatar "
user . user_avatar . gravatar_upload_id = upload_id
else
user . user_avatar . custom_upload_id = upload_id
end
2015-09-11 15:47:48 +02:00
end
2015-05-29 10:21:41 +02:00
2013-08-13 22:08:29 +02:00
user . save!
2015-05-29 10:21:41 +02:00
user . user_avatar . save!
2013-08-13 22:08:29 +02:00
2014-12-06 09:26:32 -07:00
render json : success_json
2013-08-13 22:08:29 +02:00
end
2014-04-14 22:55:57 +02:00
2014-06-27 14:48:39 -04:00
def destroy_user_image
2014-02-28 21:12:51 +01:00
user = fetch_user_from_params
guardian . ensure_can_edit! ( user )
2014-04-14 22:55:57 +02:00
2015-05-20 01:39:58 +02:00
case params . require ( :type )
when " profile_background "
2014-06-27 14:48:39 -04:00
user . user_profile . clear_profile_background
2015-05-20 01:39:58 +02:00
when " card_background "
2014-10-20 12:11:36 -04:00
user . user_profile . clear_card_background
2014-06-27 14:48:39 -04:00
else
2015-05-20 01:39:58 +02:00
raise Discourse :: InvalidParameters . new ( :type )
2014-06-27 14:48:39 -04:00
end
2014-04-14 22:55:57 +02:00
2015-05-20 01:39:58 +02:00
render json : success_json
2014-02-28 21:12:51 +01:00
end
2014-04-14 22:55:57 +02:00
2014-02-13 11:42:35 -05:00
def destroy
@user = fetch_user_from_params
guardian . ensure_can_delete_user! ( @user )
2014-04-14 22:55:57 +02:00
2014-10-20 16:59:06 +02:00
UserDestroyer . new ( current_user ) . destroy ( @user , { delete_posts : true , context : params [ :context ] } )
2014-04-14 22:55:57 +02:00
2014-02-13 11:42:35 -05:00
render json : success_json
end
2014-07-11 17:32:29 +10:00
def read_faq
2015-09-04 16:56:02 -04:00
if user = current_user
2014-07-11 17:32:29 +10:00
user . user_stat . read_faq = 1 . second . ago
user . user_stat . save
end
render json : success_json
end
2015-01-05 19:49:32 +01:00
def staff_info
2015-11-27 20:02:24 +01:00
@user = fetch_user_from_params ( include_inactive : true )
2015-01-05 19:49:32 +01:00
guardian . ensure_can_see_staff_info! ( @user )
result = { }
%W{ number_of_deleted_posts number_of_flagged_posts number_of_flags_given number_of_suspensions number_of_warnings } . each do | info |
result [ info ] = @user . send ( info )
end
render json : result
end
2013-02-05 14:16:51 -05:00
private
2013-02-06 19:25:21 -05:00
def honeypot_value
Digest :: SHA1 :: hexdigest ( " #{ Discourse . current_hostname } : #{ Discourse :: Application . config . secret_token } " ) [ 0 , 15 ]
end
def challenge_value
2013-08-23 16:19:23 +10:00
challenge = $redis . get ( 'SECRET_CHALLENGE' )
unless challenge && challenge . length == 16 * 2
challenge = SecureRandom . hex ( 16 )
$redis . set ( 'SECRET_CHALLENGE' , challenge )
end
challenge
2013-02-06 19:25:21 -05:00
end
2013-11-12 14:37:38 -08:00
def respond_to_suspicious_request
if suspicious? ( params )
2015-05-20 01:39:58 +02:00
render json : {
success : true ,
active : false ,
message : I18n . t ( " login.activate_email " , email : params [ :email ] )
}
2013-11-12 14:37:38 -08:00
end
end
def suspicious? ( params )
2014-09-23 09:06:19 +10:00
return false if current_user && is_api? && current_user . admin?
2013-11-12 14:37:38 -08:00
honeypot_or_challenge_fails? ( params ) || SiteSetting . invite_only?
end
def honeypot_or_challenge_fails? ( params )
2014-09-23 09:06:19 +10:00
return false if is_api?
2013-11-12 14:37:38 -08:00
params [ :password_confirmation ] != honeypot_value ||
2015-04-02 16:24:27 +02:00
params [ :challenge ] != challenge_value . try ( :reverse )
2013-11-12 14:37:38 -08:00
end
def user_params
2016-08-05 11:57:13 -04:00
result = params . permit ( :name , :email , :password , :username )
. merge ( ip_address : request . remote_ip ,
registration_ip_address : request . remote_ip ,
locale : user_locale )
if ! UsernameCheckerService . is_developer? ( result [ 'email' ] ) &&
is_api? &&
current_user . present? &&
current_user . admin?
result . merge! ( params . permit ( :active , :staged ) )
end
result
2016-02-06 11:49:39 -08:00
end
def user_locale
I18n . locale
2013-11-12 14:37:38 -08:00
end
2014-09-26 14:48:34 -04:00
def fail_with ( key )
render json : { success : false , message : I18n . t ( key ) }
end
2015-09-14 15:51:17 +08:00
def track_visit_to_user_profile
user_profile_id = @user . user_profile . id
ip = request . remote_ip
user_id = ( current_user . id if current_user )
Scheduler :: Defer . later 'Track profile view visit' do
UserProfileView . add ( user_profile_id , ip , user_id )
end
end
2013-02-05 14:16:51 -05:00
end