Class | LoginController
In: | test/functional/login_controller_test.rb app/controllers/login_controller.rb
Parent: | Object

This controller takes care of security.

Copyright (c) 2006 Logica

### Methods

auto_complete_for_user_email change_password confirm_account index login logout lost_password new_cadmin redirect2page rescue_action sign_up

### Constants

FLASH_CENTRAL_ADMIN_ALREADY_CREATED | = | 'You can only create the central admin if this user has not been created yet!'
FLASH_INVALID_PW | = | 'Invalid combination of username password!'
FLASH_NO_VALID_TOKEN | = | 'Not a valid token!'
FLASH_PASSWORD_ACTIVATED | = | 'New password activated!'
FLASH_LOST_PASSWORD_ABUSE | = | 'A notification was sent to the administrator reporting the abuse of your email address'
FLASH_CENTRAL_ADMIN_CREATED | = | 'Central admin user created!'
FLASH_PW_CONFIRMATION_EMAIL_SENT | = | 'A confirmation email has been sent to your email address. Please confirm your account by clicking on the hyperlink in this email'
FLASH_EMAIL_NOT_FOUND | = | 'Email address not found!'
FLASH_UNOT_ADMIN | = | "You are not an admin user!"
FLASH_UNOT_CADMIN | = | "You are not the central administrator!"

### Public Instance methods

auto_complete_for_user_email()

[Source]

         # File app/controllers/login_controller.rb, line 222
    222:   def auto_complete_for_user_email
    223:     search = params[:user][:email]
    224:     logger.debug("search:" + search)
    225:     @users = User.find(:all, :conditions => ["email like ?", search + "%"], :order => "email ASC") unless search.blank?
    226:     if @users.length == 1
    227:       render :inline => "<ul class=\"autocomplete_list\"><li class=\"autocomplete_item\"><%= @users[0].email %></li></ul>"
    228:     else
    229:       render :inline => "<ul class=\"autocomplete_list\"></ul>"
    230:     end
    231:   end

change_password()

Action change_password allows a user to change the password

[Source]

         # File app/controllers/login_controller.rb, line 103
    103:   def  change_password
    104:     @user= User.find(session['user'].id)
    105:     if  request.get?
    106:     else
    107:       @user.errors.add(:password, "Can't be blank") if params[:user][:password].blank? # blank? returns true if its receiver is nil or an empty string
    108:       @user.change_password(User.new(params[:user]))
    109:       if  @user.save
    110:         flash['success'] = 'Password was succesfully changed'
    111:       else
    112:         @user= User.find(session['user'].id)
    113:       end
    114:     end
    115:   end

confirm_account()

Action confirm_account is used to confirm a new password send by email. Without confirmation anyone could reset passwords. The token used for confirmation is just the new password hashed twice. The new password is stored in the column `confirmation_token`. Action resend_password is used to request a new password.

[Source]

        # File app/controllers/login_controller.rb, line 84
    84:   def confirm_account
    85:     @user = User.find(params[:id])
    86:     if  @user.confirm_account(params[:tk])
    87:       if  @user.save
    88:         flash['success'] = FLASH_PASSWORD_ACTIVATED
    89:       else
    90:         raise "Failed to activate account for #{@user.email}"
    91:       end
    92:     else
    93:       flash['error'] = FLASH_NO_VALID_TOKEN
    94:     end
    95:     redirect_to :action => 'login'
    96:   end

index()

[Source]

         # File app/controllers/login_controller.rb, line 117
    117:   def     index
    118:     redirect_to :action => 'login'
    119:   end

login()

Action login checks if there is a cookie. With ‘posts’ we try to login using User.try_to_login. If the user wants to be remembered a cookie is created. ‘Gets’ can login the user if the user has a good cookie.

[Source]

         # File app/controllers/login_controller.rb, line 153
    153:   def login
    154:     @wikis = Wiki.find(:all, :conditions => ['obsolete_on is null'])
    155:     @login_message = AdminMessage.text('Login')
    156:     if request.get?
    157:       if  cookies[:epfwiki_id] && User.exists?(cookies[:epfwiki_id])
    158:         logger.info("Found cookie and user with id " + cookies[:epfwiki_id])
    159:         @user = User.find(cookies[:epfwiki_id])
    160:         token = cookies[:epfwiki_token]
    161:         if @user.confirm_account(token)
    162:           logger.info("Token good, refresh cookies and login user")
    163:           create_cookie(@user) # refresh van cookie
    164:           @user.update_attributes({:http_user_agent => request.env['HTTP_USER_AGENT'], :ip_address => request.env['REMOTE_ADDR'] , :last_logon => Time.now, :logon_count => @user.logon_count + 1, :logon_using_cookie_count => @user.logon_using_cookie_count + 1})
    165:           session['user'] = @user
    166:           redirect2page
    167:         else
    168:           logger.info("An account was found but the token was not correct #{request.env.inspect}")
    169:           expire_cookie
    170:           session['user'] = nil
    171:           @user = User.new
    172:         end
    173:       else
    174:         logger.debug("Cookie not found, or user not found with id in cookie: #{cookies.inspect}, cookies['epfwiki_id']: #{cookies['epfwiki_id']}, User.exists?(cookies[:epfwiki_id]): #{User.exists?(cookies[:epfwiki_id])}")
    175:         expire_cookie # if it exists, it is invalid
    176:         @cadmin = User.find_central_admin
    177:         if  @cadmin
    178:                   logger.debug('Cadmin found, displaying the login form')
    179:           session['user'] = nil
    180:           @user = User.new
    181:         else
    182:           logger.debug('Cadmin not found, displaying form to create cadmin user')
    183:           redirect_to :action => 'new_cadmin'
    184:         end
    185:       end
    186:     else
    187:       @user = User.new(params[:user])
    188:       @logged_in_user = @user.try_to_login
    189:       if @logged_in_user
    190:         logger.info("Login succesfull")
    191:         session['user'] = @logged_in_user
    192:         if @user.remember_me == "0" # remember_me = 0, do not remember_me is 1
    193:           create_cookie(@logged_in_user)
    194:         end
    195:         @logged_in_user.update_attributes({:http_user_agent => request.env['HTTP_USER_AGENT'], :ip_address => request.env['REMOTE_ADDR'] , :last_logon => Time.now, :logon_count => @logged_in_user.logon_count + 1})
    196:         redirect2page
    197:       else
    198:         @user = User.new
    199:         flash['notice'] = FLASH_INVALID_PW
    200:         logger.info("Invalid combination of username password for #{@user.email}")
    201:       end
    202:     end
    203:   end

logout()

destroy the session and cookie redirect to login

[Source]

         # File app/controllers/login_controller.rb, line 206
    206:   def logout
    207:     session['user'] = nil
    208:     flash[:notice] = "Logged out"
    209:     redirect_to :action => "login"
    210:     expire_cookie
    211:   end

lost_password()

Generate a new password for a user and sends it in a email. The new password is activated after the user confirms it. The old passwords remains active, otherwise any user can disable accounts!

[Source]

         # File app/controllers/login_controller.rb, line 124
    124:   def lost_password
    125:     if  request.get?
    126:       @user = User.new
    127:     else
    128:       @user = User.new(params[:user])
    129:       logger.info('Finding user with email: ' + @user.email.downcase)
    130:       @user_by_email = User.find_by_email(@user.email.downcase)
    131:       if @user_by_email
    132:         @user_by_email.password = @user.password
    133:         @user_by_email.password_confirmation = @user.password_confirmation
    134:         if @user_by_email.valid?
    135:           @user_by_email.set_new_pw(@user_by_email.password)
    136:           if  @user_by_email.save
    137:             urls = [url_for(:controller => 'login', :action => 'confirm_account', :id => @user_by_email.id, :tk => @user_by_email.token_new)]
    138:             Notifier::deliver_lost_password(@user_by_email, urls)
    139:             flash['success'] = FLASH_PW_CONFIRMATION_EMAIL_SENT
    140:             redirect_to :action => "login"
    141:           end
    142:         else
    143:         end
    144:       else
    145:         @user.email = ""
    146:         flash['notice'] = FLASH_EMAIL_NOT_FOUND
    147:       end
    148:     end
    149:   end

new_cadmin()

Is be used to create the first user, the central admin account

[Source]

        # File app/controllers/login_controller.rb, line 40
    40:   def new_cadmin
    41:     if  User.count > 0
    42:       flash['error'] = FLASH_CENTRAL_ADMIN_ALREADY_CREATED
    43:       redirect_to :action => 'login'
    44:     else
    45:       if request.get?
    46:         @user = User.new
    47:       else
    48:         @user = User.new_cadmin(params[:user])
    49:         if  @user.save
    50:           flash['success'] = FLASH_CENTRAL_ADMIN_CREATED
    51:           redirect_to :action => 'login'
    52:         else
    53:           render :action => 'new_cadmin'
    54:         end
    55:       end
    56:     end
    57:   end

redirect2page()

[Source]

         # File app/controllers/login_controller.rb, line 213
    213:   def redirect2page
    214:     if session["return_to"]
    215:       redirect_to(session["return_to"])
    216:       session["return_to"] = nil
    217:     else
    218:       redirect_to :controller => "users", :action => "account"
    219:     end
    220:   end

rescue_action(e)

[Source]

        # File test/functional/login_controller_test.rb, line 22
    22:                        def rescue_action(e) raise e end

sign_up()

Action sign_up creates the account or displays the form to create the account. Passwords can be generated or supplied by the user. If passwords are supplied by the user the account needs to be confirmed, see confirm_account

[Source]

        # File app/controllers/login_controller.rb, line 63
    63:   def sign_up
    64:     if request.get?
    65:       @user = User.new
    66:     else
    67:       @user = User.new_signup(params[:user])
    68:       if @user.save
    69:         flash['success'] =  FLASH_PW_CONFIRMATION_EMAIL_SENT
    70:         Notifier::deliver_welcome_pw_confirmationlink(@user, request.host + (request.port == 80 ? '' : ':' + request.port.to_s))
    71:         redirect_to :action => "login"
    72:       else
    73:         logger.info("Failed to save user on signup #{@user.inspect}")
    74:         @user.email = @user.email.gsub(@user.email_extension,"") if @user.email && @user.email_extension
    75:         @user.password = ""
    76:         @user.password_confirmation = ""
    77:       end
    78:     end
    79:   end

[Validate]