2010-04-20 23:05:11 +00:00
require 'digest/sha2'
class UserController < ApplicationController
layout " default "
before_filter :blocked_only , :only = > [ :authenticate , :update , :edit , :modify_blacklist ]
before_filter :janitor_only , :only = > [ :invites ]
before_filter :mod_only , :only = > [ :block , :unblock , :show_blocked_users ]
before_filter :post_member_only , :only = > [ :set_avatar ]
2012-06-27 21:07:15 +07:00
before_filter :no_anonymous , :only = > [ :change_password , :change_email ]
2010-09-07 03:25:28 +00:00
helper :post , :tag_subscription
2010-04-20 23:05:11 +00:00
helper :avatar
auto_complete_for :user , :name
protected
def save_cookies ( user )
cookies [ :login ] = { :value = > user . name , :expires = > 1 . year . from_now }
cookies [ :pass_hash ] = { :value = > user . password_hash , :expires = > 1 . year . from_now }
session [ :user_id ] = user . id
end
public
2012-07-26 20:55:37 +02:00
def autocomplete_name
keyword = params [ :term ] . to_s
@users = User . where ( [ 'name LIKE ?' , " * #{ keyword } * " . to_escaped_for_sql_like ] ) . pluck ( :name ) if keyword . length > = 2
respond_to do | format |
format . json { render :json = > ( @users || [ ] ) }
end
end
2012-07-08 23:23:33 +07:00
# FIXME: this method is crap and only function as temporary workaround
# until I convert the controllers to resourceful version which is
# planned for 3.2 branch (at least 3.2.1).
def remove_avatar
# When removing other user's avatar, ensure current user is mod or higher.
if @current_user . id != params [ :id ] and not @current_user . is_mod_or_higher?
access_denied
return
end
@user = User . find ( params [ :id ] )
@user . avatar_post_id = nil
if @user . save
flash [ :notice ] = 'Avatar removed'
else
flash [ :notice ] = 'Failed removing avatar'
end
redirect_to :action = > :show , :id = > params [ :id ]
end
2012-06-11 19:48:35 +07:00
def change_password
@title = 'Change Password'
end
2012-06-27 21:07:15 +07:00
def change_email
@title = 'Change Email'
@current_user . current_email = @current_user . email
end
2010-04-20 23:05:11 +00:00
def auto_complete_for_member_name
@users = User . find ( :all , :order = > " lower(name) " , :conditions = > [ " level = ? AND name ILIKE ? ESCAPE E' \\ \\ ' " , CONFIG [ " user_levels " ] [ " Member " ] , params [ :member ] [ :name ] + " % " ] )
render :layout = > false , :text = > " <ul> " + @users . map { | x | " <li> " + x . name + " </li> " } . join ( " " ) + " </ul> "
end
def show
if params [ :name ]
@user = User . find_by_name ( params [ :name ] )
else
@user = User . find ( params [ :id ] )
end
if @user . nil?
redirect_to " /404 "
2011-04-17 15:00:33 +00:00
else
if @user == @current_user then
set_title " My Profile "
else
set_title @user . name + " 's Profile "
end
2010-04-20 23:05:11 +00:00
end
if @current_user . is_mod_or_higher?
2012-07-07 01:36:31 +07:00
@user_ips = @user . user_logs . order ( 'created_at DESC' ) . pluck ( 'ip_addr' ) . uniq
2010-04-20 23:05:11 +00:00
end
end
2012-06-04 17:13:54 +07:00
2010-04-20 23:05:11 +00:00
def invites
if request . post?
if params [ :member ]
begin
@current_user . invite! ( params [ :member ] [ :name ] , params [ :member ] [ :level ] )
flash [ :notice ] = " User was invited "
2012-06-04 17:13:54 +07:00
2010-04-20 23:05:11 +00:00
rescue ActiveRecord :: RecordNotFound
flash [ :notice ] = " Account not found "
2012-06-04 17:13:54 +07:00
2010-04-20 23:05:11 +00:00
rescue User :: NoInvites
flash [ :notice ] = " You have no invites for use "
2012-06-04 17:13:54 +07:00
2010-04-20 23:05:11 +00:00
rescue User :: HasNegativeRecord
flash [ :notice ] = " This use has a negative record and must be invited by an admin "
end
end
2012-06-04 17:13:54 +07:00
2010-04-20 23:05:11 +00:00
redirect_to :action = > " invites "
else
@invited_users = User . find ( :all , :conditions = > [ " invited_by = ? " , @current_user . id ] , :order = > " lower(name) " )
end
end
2012-06-04 17:13:54 +07:00
2010-04-20 23:05:11 +00:00
def home
set_title " My Account "
end
def index
set_title " Users "
2012-06-04 17:13:54 +07:00
2010-04-20 23:05:11 +00:00
@users = User . paginate ( User . generate_sql ( params ) . merge ( :per_page = > 20 , :page = > params [ :page ] ) )
respond_to_list ( " users " )
end
def authenticate
save_cookies ( @current_user )
2012-06-04 17:13:54 +07:00
2010-04-20 23:05:11 +00:00
if params [ :url ] . blank?
path = { :action = > " home " }
else
path = params [ :url ]
end
2012-06-04 17:13:54 +07:00
2010-04-20 23:05:11 +00:00
respond_to_success ( " You are now logged in " , path )
end
def check
if request . post?
user = User . find_by_name ( params [ :username ] )
ret = { :exists = > false }
ret [ :name ] = params [ :username ]
if not user
2012-06-04 17:13:54 +07:00
respond_to_success ( " User does not exist " , { } , :api = > { :response = > " unknown-user " } . merge ( ret ) )
2010-04-20 23:05:11 +00:00
return
end
# Return some basic information about the user even if the password isn't given, for
# UI cosmetics.
ret [ :exists ] = true
ret [ :id ] = user . id
ret [ :name ] = user . name
ret [ :no_email ] = user . email . blank?
user = User . authenticate ( params [ :username ] , params [ :password ] || " " )
if not user
respond_to_success ( " Wrong password " , { } , :api = > { :response = > " wrong-password " } . merge ( ret ) )
return
end
ret [ :pass_hash ] = user . password_hash
2010-11-30 23:48:56 +00:00
ret [ :user_info ] = user . user_info_cookie
2010-04-20 23:05:11 +00:00
respond_to_success ( " Successful " , { } , :api = > { :response = > " success " } . merge ( ret ) )
2012-05-12 08:48:34 -07:00
else
redirect_to root_path
2010-04-20 23:05:11 +00:00
end
end
def login
set_title " Login "
end
def create
user = User . create ( params [ :user ] )
if user . errors . empty?
save_cookies ( user )
ret = { :exists = > false }
ret [ :name ] = user . name
ret [ :id ] = user . id
ret [ :pass_hash ] = user . password_hash
2010-11-30 23:48:56 +00:00
ret [ :user_info ] = user . user_info_cookie
2010-04-20 23:05:11 +00:00
2010-09-06 23:40:45 +00:00
respond_to_success ( " New account created " , { :action = > " home " } , :api = > { :response = > " success " } . merge ( ret ) )
2010-04-20 23:05:11 +00:00
else
error = user . errors . full_messages . join ( " , " )
respond_to_success ( " Error: " + error , { :action = > " signup " } , :api = > { :response = > " error " , :errors = > user . errors . full_messages } )
end
end
def signup
set_title " Signup "
@user = User . new
end
def logout
set_title " Logout "
session [ :user_id ] = nil
cookies [ :login ] = nil
cookies [ :pass_hash ] = nil
2010-09-10 01:23:12 +00:00
dest = { :action = > " home " }
dest = params [ :from ] if params [ :from ]
respond_to_success ( " You are now logged out " , dest )
2010-04-20 23:05:11 +00:00
end
def update
if params [ :commit ] == " Cancel "
redirect_to :action = > " home "
return
end
2012-06-04 17:13:54 +07:00
2010-04-20 23:05:11 +00:00
if @current_user . update_attributes ( params [ :user ] )
2010-10-11 03:59:58 +00:00
respond_to_success ( " Account settings saved " , :action = > " edit " )
2010-04-20 23:05:11 +00:00
else
2012-06-11 20:53:45 +07:00
if params [ :render ] and params [ :render ] [ :view ]
2012-06-30 18:04:06 +07:00
render get_view_name_for_edit ( params [ :render ] [ :view ] )
2012-06-11 20:53:45 +07:00
else
respond_to_error ( @current_user , :action = > " edit " )
end
2010-04-20 23:05:11 +00:00
end
end
def modify_blacklist
added_tags = params [ :add ] || [ ]
removed_tags = params [ :remove ] || [ ]
tags = @current_user . blacklisted_tags_array
added_tags . each { | tag |
tags << tag if not tags . include? ( tag )
}
tags -= removed_tags
if @current_user . update_attribute ( :blacklisted_tags , tags . join ( " \n " ) )
respond_to_success ( " Tag blacklist updated " , { :action = > " home " } , :api = > { :result = > @current_user . blacklisted_tags_array } )
else
respond_to_error ( @current_user , :action = > " edit " )
end
end
def remove_from_blacklist
end
def edit
set_title " Edit Account "
@user = @current_user
end
2012-06-04 17:13:54 +07:00
2010-04-20 23:05:11 +00:00
def reset_password
set_title " Reset Password "
if request . post?
@user = User . find_by_name ( params [ :user ] [ :name ] )
2012-06-04 17:13:54 +07:00
2010-04-20 23:05:11 +00:00
if @user . nil?
respond_to_error ( " That account does not exist " , { :action = > " reset_password " } , :api = > { :result = > " unknown-user " } )
return
end
2012-06-04 17:13:54 +07:00
2010-04-20 23:05:11 +00:00
if @user . email . blank?
respond_to_error ( " You never supplied an email address, therefore you cannot have your password automatically reset " ,
{ :action = > " login " } , :api = > { :result = > " no-email " } )
return
end
2012-06-04 17:13:54 +07:00
2010-04-20 23:05:11 +00:00
if @user . email != params [ :user ] [ :email ]
respond_to_error ( " That is not the email address you supplied " ,
{ :action = > " login " } , :api = > { :result = > " wrong-email " } )
return
end
2012-06-04 17:13:54 +07:00
2010-04-20 23:05:11 +00:00
begin
User . transaction do
# If the email is invalid, abort the password reset
new_password = @user . reset_password
2012-07-16 19:54:47 +07:00
UserMailer . new_password ( @user , new_password ) . deliver
2010-04-20 23:05:11 +00:00
respond_to_success ( " Password reset. Check your email in a few minutes. " ,
{ :action = > " login " } , :api = > { :result = > " success " } )
return
end
rescue Net :: SMTPSyntaxError , Net :: SMTPFatalError
respond_to_success ( " Your email address was invalid " ,
{ :action = > " login " } , :api = > { :result = > " invalid-email " } )
return
end
else
@user = User . new
2012-05-12 08:48:34 -07:00
redirect_to root_path if params [ :format ] and params [ :format ] != 'html'
2010-04-20 23:05:11 +00:00
end
end
2012-06-04 17:13:54 +07:00
2010-04-20 23:05:11 +00:00
def block
@user = User . find ( params [ :id ] )
2012-06-04 17:13:54 +07:00
2010-04-20 23:05:11 +00:00
if request . post?
if @user . is_mod_or_higher?
flash [ :notice ] = " You can not ban other moderators or administrators "
redirect_to :action = > " block "
return
end
2012-06-04 17:13:54 +07:00
2010-04-20 23:05:11 +00:00
Ban . create ( params [ :ban ] . merge ( :banned_by = > @current_user . id , :user_id = > params [ :id ] ) )
redirect_to :action = > " show_blocked_users "
else
@ban = Ban . new ( :user_id = > @user . id , :duration = > " 1 " )
end
end
2012-06-04 17:13:54 +07:00
2010-04-20 23:05:11 +00:00
def unblock
params [ :user ] . keys . each do | user_id |
Ban . destroy_all ( [ " user_id = ? " , user_id ] )
end
2012-06-04 17:13:54 +07:00
2010-04-20 23:05:11 +00:00
redirect_to :action = > " show_blocked_users "
end
2012-06-04 17:13:54 +07:00
2010-04-20 23:05:11 +00:00
def show_blocked_users
2011-04-17 15:00:33 +00:00
set_title " Blocked users "
2010-04-20 23:05:11 +00:00
#@users = User.find(:all, :select => "users.*", :joins => "JOIN bans ON bans.user_id = users.id", :conditions => ["bans.banned_by = ?", @current_user.id])
2012-06-24 22:20:18 +02:00
@users = User . find ( :all , :select = > " users.* " , :joins = > " JOIN bans ON bans.user_id = users.id " , :order = > " expires_at ASC " )
2010-04-20 23:05:11 +00:00
@ip_bans = IpBans . find ( :all )
2012-06-04 17:13:54 +07:00
end
2010-04-20 23:05:11 +00:00
if CONFIG [ " enable_account_email_activation " ]
def resend_confirmation
if request . post?
user = User . find_by_email ( params [ :email ] )
2012-06-04 17:13:54 +07:00
2010-04-20 23:05:11 +00:00
if user . nil?
flash [ :notice ] = " No account exists with that email "
redirect_to :action = > " home "
return
end
2012-06-04 17:13:54 +07:00
2010-04-20 23:05:11 +00:00
if user . is_blocked_or_higher?
flash [ :notice ] = " Your account is already activated "
redirect_to :action = > " home "
return
end
2012-06-04 17:13:54 +07:00
2010-04-20 23:05:11 +00:00
UserMailer :: deliver_confirmation_email ( user )
flash [ :notice ] = " Confirmation email sent "
redirect_to :action = > " home "
end
end
def activate_user
flash [ :notice ] = " Invalid confirmation code "
2012-06-04 17:13:54 +07:00
2010-04-20 23:05:11 +00:00
users = User . find ( :all , :conditions = > [ " level = ? " , CONFIG [ " user_levels " ] [ " Unactivated " ] ] )
users . each do | user |
if User . confirmation_hash ( user . name ) == params [ " hash " ]
user . update_attribute ( :level , CONFIG [ " starting_level " ] )
flash [ :notice ] = " Account has been activated "
break
end
end
redirect_to :action = > " home "
end
end
2012-06-04 17:13:54 +07:00
2010-04-20 23:05:11 +00:00
def set_avatar
@user = @current_user
if params [ :user_id ] then
@user = User . find ( params [ :user_id ] )
respond_to_error ( " Not found " , :action = > " index " , :status = > 404 ) unless @user
end
if ! @user . is_anonymous? && ! @current_user . has_permission? ( @user , :id )
access_denied ( )
return
end
if request . post?
if @user . set_avatar ( params ) then
redirect_to :action = > " show " , :id = > @user . id
else
respond_to_error ( @user , :action = > " home " )
end
end
if ! @user . is_anonymous? && params [ :id ] == @user . avatar_post_id then
@old = params
end
@params = params
@post = Post . find ( params [ :id ] )
end
2010-12-23 05:22:21 +00:00
def error
report = params [ :report ]
2012-06-04 17:13:54 +07:00
2012-04-29 10:56:41 -07:00
file = " #{ Rails . root } /log/user_errors.log "
2010-12-23 05:22:21 +00:00
File . open ( file , " a " ) do | f |
2012-05-11 11:22:38 -07:00
f . write ( report . to_s + " \n \n \n ------------------------------------------- \n \n \n " )
2010-12-23 05:22:21 +00:00
end
render :json = > { :success = > true }
end
2012-06-30 18:04:06 +07:00
private
def get_view_name_for_edit ( param )
case param
when 'change_email'
:change_email
when 'change_password'
:change_password
else
:edit
end
end
2010-04-20 23:05:11 +00:00
end