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

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_SENT = 'Password sent!'
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

[Source]

     # File app/controllers/login_controller.rb, line 238
238:   def auto_complete_for_user_email
239:     search = params[:user][:email]
240:     logger.debug("search:" + search)
241:     @users = User.find(:all, :conditions => ["email like ?", search + "%"], :order => "email ASC") unless search.blank?
242:     if @users.length == 1
243:       render :inline => "<ul class=\"autocomplete_list\"><li class=\"autocomplete_item\"><%= @users[0].email %></li></ul>" 
244:     else
245:       render :inline => "<ul class=\"autocomplete_list\"></ul>"
246:     end
247:   end

Action change_password allows a user to change the password

[Source]

     # File app/controllers/login_controller.rb, line 106
106:   def  change_password
107:     @user= User.find(session['user'].id)
108:     if  request.get?
109:     else
110:       @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
111:       @user.change_password(User.new(params[:user]))
112:       if  @user.save
113:         flash['success'] = 'Password was succesfully changed'
114:       else
115:         @user= User.find(session['user'].id)
116:       end
117:     end
118:   end

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 87
87:   def confirm_account
88:     @user = User.find(params[:id])
89:     if  @user.confirm_account(params[:tk])
90:       if  @user.save
91:         flash['success'] = FLASH_PASSWORD_ACTIVATED 
92:       else
93:         raise "Failed to activate account for #{@user.email}"
94:       end
95:     else
96:       flash['error'] = FLASH_NO_VALID_TOKEN
97:     end
98:     redirect_to :action => 'login'
99:   end

[Source]

     # File app/controllers/login_controller.rb, line 131
131:   def     index
132:     redirect_to :action => 'login'
133:   end

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 169
169:   def login
170:     @wikis = Wiki.find(:all, :conditions => ['obsolete_on is null'])
171:     @login_message = AdminMessage.find_by_guid('Login').text    
172:     if request.get?
173:       if  cookies[:epfwiki_id] && User.exists?(cookies[:epfwiki_id])
174:         logger.info("Found cookie and user with id " + cookies[:epfwiki_id])
175:         @user = User.find(cookies[:epfwiki_id])         
176:         token = cookies[:epfwiki_token]
177:         if @user.confirm_account(token)
178:           logger.info("Token good, refresh cookies and login user")
179:           create_cookie(@user) # refresh van cookie
180:           @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})
181:           session['user'] = @user
182:           redirect2page
183:         else
184:           logger.info("An account was found but the token was not correct #{request.env.inspect}")        
185:           expire_cookie
186:           session['user'] = nil
187:           @user = User.new
188:         end
189:       else
190:         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])}")
191:         expire_cookie # if it exists, it is invalid
192:         @cadmin = User.find_central_admin
193:         if  @cadmin
194:                   logger.debug('Cadmin found, displaying the login form')
195:           session['user'] = nil
196:           @user = User.new
197:         else
198:           logger.debug('Cadmin not found, displaying form to create cadmin user')
199:           redirect_to :action => 'new_cadmin'
200:         end
201:       end
202:     else
203:       @user = User.new(params[:user])
204:       @logged_in_user = @user.try_to_login
205:       if @logged_in_user
206:         logger.info("Login succesfull")
207:         session['user'] = @logged_in_user
208:         if @user.remember_me == "0" # remember_me = 0, do not remember_me is 1
209:           create_cookie(@logged_in_user)
210:         end
211:         @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})
212:         redirect2page
213:       else
214:         @user = User.new
215:         flash['notice'] = FLASH_INVALID_PW
216:         logger.info("Invalid combination of username password for #{@user.email}")
217:       end
218:     end
219:   end

destroy the session and cookie redirect to login

[Source]

     # File app/controllers/login_controller.rb, line 222
222:   def logout
223:     session['user'] = nil
224:     flash[:notice] = "Logged out"
225:     redirect_to :action => "login"
226:     expire_cookie
227:   end

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 138
138:   def lost_password
139:     if  request.get?
140:       @user = User.new
141:     else
142:       @user = User.new(params[:user])
143:       logger.info('Finding user with email: ' + @user.email.downcase)
144:       @user_by_email = User.find_by_email(@user.email.downcase)
145:       if  @user_by_email
146:         @user_by_email.set_new_pw
147:         if  @user_by_email.save
148:           urls = [url_for(:controller => 'login', :action => 'confirm_account', :id => @user_by_email.id, :tk => @user_by_email.token_new)]
149:           urls << url_for(:constroller => 'login', :action => 'report_password_reset_attempt', :id => @user_by_email.id, :tk => @user_by_email.token_new)
150:           Notifier::deliver_lost_password(@user_by_email, urls)
151:           #Notifier::deliver_env_to(User.find_central_admin, 
152:           #                         session.instance_variable_get("@data"), 
153:           #params, 
154:           #request.env)
155:           flash['success'] = FLASH_PW_SENT
156:           redirect_to :action => "login"
157:         else
158:           logger.error(@user_by_email.errors.full_messages.join(', '))
159:         end
160:       else
161:         @user.email = ""
162:         flash['notice'] = FLASH_EMAIL_NOT_FOUND
163:       end
164:     end
165:   end

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

[Source]

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

[Source]

     # File app/controllers/login_controller.rb, line 229
229:   def redirect2page
230:     if session["return_to"]
231:       redirect_to(session["return_to"])
232:       session["return_to"] = nil
233:     else
234:       redirect_to :controller => "users", :action => "account"
235:     end
236:   end

With action report_password_reset_attempt users can report that they received a new password that they didn‘t request.

[Source]

     # File app/controllers/login_controller.rb, line 121
121:   def report_password_reset_attempt
122:     @user = User.find(params[:id])
123:     Notifier::deliver_env_to(User.find_central_admin, 
124:                              session.instance_variable_get("@data"), 
125:     params, 
126:     request.env)
127:     flash['notice'] = ::MSG_LOST_PASSWORD_ABUSE 
128:     redirect_to :controller => 'users', :action => 'show'
129:   end

[Source]

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

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 62
62:   def sign_up
63:     if request.get?
64:       @user = User.new
65:     else
66:       @user = User.new_signup(params[:user])
67:       if @user.save
68:         if ENV['EPFWIKI_GENERATE_PASSWORDS'] == '1'
69:           flash['success'] =  FLASH_PW_SENT
70:         else
71:           flash['success'] =  FLASH_PW_CONFIRMATION_EMAIL_SENT
72:         end
73:         Notifier::deliver_welcome_pw_confirmationlink(@user, request.host + (request.port == 80 ? '' : ':' + request.port.to_s))
74:         redirect_to :action => "login" 
75:       else
76:         logger.info("Failed to save user on signup #{@user.inspect}")
77:         @user.email = @user.email.gsub(@user.email_extension,"") if @user.email && @user.email_extension
78:         @user.password = ""
79:         @user.password_confirmation = ""
80:       end
81:     end
82:   end

[Validate]