Rcov C0 Coverage Information - RCov

app/controllers/main_controller.rb

Name Total Lines Lines of Code Total Coverage Code Coverage
app/controllers/main_controller.rb 376 234
82.71%
76.92%

Key

Code reported as executed by Ruby looks like this...and this: this line is also marked as covered.Lines considered as run by rcov, but not reported by Ruby, look like this,and this: these lines were inferred by rcov (using simple heuristics).Finally, here's a line marked as not executed.

Coverage Details

1 
2 # Controller responsible for providing login and logout processes
3 # as well as displaying main page
4 class MainController < ApplicationController
5 
6   include MainHelper
7   protect_from_forgery :except => [:login, :page_not_found]
8 
9   # check for authorization
10   before_filter      :authorize_for_user,
11                      :except => [:login,
12                                  :page_not_found]
13   before_filter :authorize_only_for_admin, :only => [:login_as]
14 
15   #########################################################################
16   # Authentication
17 
18   # Handles login requests; usually redirected here when trying to access
19   # the website and has not logged in yet, or session has expired.  User
20   # is redirected to main page if session is still active and valid.
21 
22   def login
23     # external auth has been done, skip markus authorization
24     if MarkusConfigurator.markus_config_remote_user_auth
25       if @markus_auth_remote_user.nil?
26         render :file => "#{::Rails.root.to_s}/public/403.html",
27           :status => 403
28         return
29       else
30         login_success = login_without_authentication(@markus_auth_remote_user)
31         if login_success
32           uri = session[:redirect_uri]
33           session[:redirect_uri] = nil
34           refresh_timeout
35           current_user.set_api_key # set api key in DB for user if not yet set
36           # redirect to last visited page or to main page
37           redirect_to( uri || { :action => 'index' } )
38           return
39         else
40           @login_error = flash[:login_notice]
41           render :remote_user_auth_login_fail
42           return
43         end
44       end
45     end
46 
47     @current_user = current_user
48     # redirect to main page if user is already logged in.
49     if logged_in? && !request.post?
50       redirect_to :action => 'index'
51       return
52     end
53     return unless request.post?
54 
55     # strip username
56     params[:user_login].strip!
57 
58     # Get information of the user that is trying to login if his or her
59     # authentication is valid
60     validation_result = validate_user(params[:user_login], params[:user_login], params[:user_password])
61     if !validation_result[:error].nil?
62       flash[:login_notice] = validation_result[:error]
63       redirect_to :action => 'login'
64       return
65     end
66     # validation worked
67     found_user = validation_result[:user]
68     if found_user.nil?
69       return
70     end
71 
72     # Has this student been hidden?
73     if found_user.student? && found_user.hidden
74       flash[:login_notice] = I18n.t("account_disabled")
75       redirect_to(:action => 'login') && return
76     end
77 
78     self.current_user = found_user
79 
80     if logged_in?
81       uri = session[:redirect_uri]
82       session[:redirect_uri] = nil
83       refresh_timeout
84       current_user.set_api_key # set api key in DB for user if not yet set
85       # redirect to last visited page or to main page
86       redirect_to( uri || { :action => 'index' } )
87     else
88       flash[:login_notice] = I18n.t(:login_failed)
89     end
90   end
91 
92 
93   # Clear the sesssion for current user and redirect to login page
94   def logout
95     logout_redirect = MarkusConfigurator.markus_config_logout_redirect
96     if logout_redirect == "NONE"
97       page_not_found
98       return
99     end
100     m_logger = MarkusLogger.instance
101 
102     # The real_uid field of session keeps track of the uid of the original
103     # user that is logged in if there is a role switch
104     if !session[:real_uid].nil? && !session[:uid].nil?
105       #An admin was logged in as a student or grader
106       m_logger.log("Admin '#{User.find_by_id(session[:real_uid]).user_name}' logged out from '#{User.find_by_id(session[:uid]).user_name}'.")
107     else
108       #The user was not assuming another role
109       m_logger.log("User '#{current_user.user_name}' logged out.")
110     end
111     clear_session
112     cookies.delete :auth_token
113     reset_session
114     if logout_redirect == 'DEFAULT'
115       redirect_to :action => 'login'
116       return
117     else
118       redirect_to logout_redirect
119       return
120     end
121   end
122 
123   def index
124     @current_user = current_user
125     if @current_user.student? or @current_user.ta?
126       redirect_to :controller => 'assignments', :action => 'index'
127       return
128     end
129     @assignments = Assignment.find(:all)
130     render :action => 'index', :layout => 'content'
131   end
132 
133   def about
134     # dummy action for remote rjs calls
135     # triggered by clicking on the about icon
136   end
137 
138   def reset_api_key
139     render :file => "#{::Rails.root.to_s}/public/404.html", :status => 404 and return unless request.post?
140     # Students shouldn't be able to change their API key
141     if !@current_user.student?
142       @current_user.reset_api_key
143       @current_user.save
144     else
145       render :file => "#{::Rails.root.to_s}/public/404.html", :status => 404 and return
146     end
147     render :action => 'api_key_replace', :locals => {:user => @current_user }
148   end
149 
150   # Render 404 error (page not found) if no other route matches.
151   # See config/routes.rb
152   def page_not_found
153     render :file => "#{::Rails.root.to_s}/public/404.html", :status => 404
154   end
155 
156   # Authenticates the admin (i.e. validates her password). Given the user, that
157   # the admin would like to login as and the admin's password switch to the
158   # desired user on success.
159   #
160   # If the current user already recorded, matches the password entered in the
161   # form, grant the current user (an admin) access to the account of the user
162   # name entered in the form.
163   #
164   # Relevant partials:
165   #   role_switch_handler
166   #   role_switch_error
167   #   role_switch_content
168   #   role_switch
169   def login_as
170     validation_result = nil
171     if MarkusConfigurator.markus_config_remote_user_auth
172       validation_result = validate_user_without_login(params[:effective_user_login],
173                                         params[:user_login])
174     else
175       validation_result = validate_user(params[:effective_user_login],
176                                         params[:user_login],
177                                         params[:admin_password])
178     end
179     if !validation_result[:error].nil?
180       # There were validation errors
181       render :partial => "role_switch_handler",
182         :locals => { :error => validation_result[:error], :success => false }
183       return
184     end
185 
186     found_user = validation_result[:user]
187     if found_user.nil?
188       return
189     end
190 
191     # Check if an admin is trying to login as another admin. Should not be allowed
192     if found_user.admin?
193       # error
194       render :partial => "role_switch_handler", :locals =>
195             { :error => I18n.t(:cannot_login_as_another_admin), :success => false }
196       return
197     end
198 
199     # Log the admin that assumed the role of another user together with the time
200     # and date that the role switch occurred
201     m_logger = MarkusLogger.instance
202     m_logger.log("Admin '#{current_user.user_name}' logged in as '#{params[:effective_user_login]}'.")
203 
204     # Save the uid of the admin that is switching roles
205     session[:real_uid] = session[:uid]
206     # Change the uid of the current user
207     self.current_user = found_user
208 
209     if logged_in?
210       uri = session[:redirect_uri]
211       session[:redirect_uri] = nil
212       refresh_timeout
213       current_user.set_api_key # set api key in DB for user if not yet set
214       # All good, redirect to the main page of the viewer, discard
215       # role switch modal
216       render :partial => "role_switch_handler", :locals =>
217             { :success => true }
218       return
219     else
220       render :partial => "role_switch_handler", :locals =>
221             { :error => I18n.t(:login_failed), :success => false }
222       return
223     end
224   end
225 
226   def role_switch
227     # dummy action for remote rjs calls
228     # triggered by clicking on the "Switch role" link
229     # please keep.
230   end
231 
232   # Action only relevant if REMOTE_USER config is on and if an
233   # admin switched role. Since there might not be a logout link
234   # provide a vehicle to expire the session (I.e. cancel the
235   # role switch).
236   def clear_role_switch_session
237     m_logger = MarkusLogger.instance
238 
239     # The real_uid field of session keeps track of the uid of the original
240     # user that is logged in if there is a role switch
241     if !session[:real_uid].nil? && !session[:uid].nil?
242       # An admin was logged in as a student or grader
243       m_logger.log("Admin '#{User.find_by_id(session[:real_uid]).user_name}' logged out from '#{User.find_by_id(session[:uid]).user_name}'.")
244     else
245       #The user was not assuming another role
246       m_logger.log("WARNING: Possible break in attempt from '#{current_user.user_name}'.")
247     end
248     clear_session
249     cookies.delete :auth_token
250     reset_session
251     redirect_to :action => 'login'
252     return
253   end
254 
255 private
256 
257   def login_without_authentication(markus_auth_remote_user)
258     found_user = User.authorize(markus_auth_remote_user)
259     # if not nil, user authorized to enter MarkUs
260     if found_user.nil?
261       # This message actually means "User not allowed to use MarkUs",
262       # but it's from a security-perspective
263       # not a good idea to report this to the outside world. It makes it
264       # easier for attempted break-ins
265       # if one can distinguish between existent and non-existent users.
266       flash[:login_notice] = I18n.t(:login_failed)
267       return false
268     end
269 
270     # Has this student been hidden?
271     if found_user.student? && found_user.hidden
272       flash[:login_notice] = I18n.t("account_disabled")
273       return false
274     end
275 
276     # For admins we have a possibility of role switches,
277     # so check if the real_uid is set in the session.
278     if found_user.admin? && !session[:real_uid].nil? &&
279        session[:real_uid] != session[:uid]
280       self.current_user = User.find_by_id(session[:uid])
281       m_logger = MarkusLogger.instance
282       m_logger.log("Admin '#{found_user.user_name}' logged in as '#{current_user.user_name}'.")
283     else
284       self.current_user = found_user
285     end
286 
287     if logged_in?
288       return true
289     else
290       flash[:login_notice] = I18n.t(:login_failed)
291       return false
292     end
293   end
294 
295   # Returns the user with user name "effective_user" from the database given that the user
296   # with user name "real_user" is authenticated. Effective and real users might be the
297   # same for regular logins and are different on an assume role call.
298   #
299   # This function is called both by the login and login_as actions.
300   def validate_user(effective_user, real_user, password)
301     validation_result = Hash.new
302     validation_result[:user] = nil # Let's be explicit
303     # check for blank username and password
304     blank_login = effective_user.blank?
305     blank_pwd = password.blank?
306     validation_result[:error] = get_blank_message(blank_login, blank_pwd)
307     return validation_result if blank_login || blank_pwd
308 
309     # Two stage user verification: authentication and authorization
310     authenticate_response = User.authenticate(real_user,
311                                               password)
312     if authenticate_response == User::AUTHENTICATE_BAD_PLATFORM
313       validation_result[:error] = I18n.t("external_authentication_not_supported")
314       return validation_result
315     end
316     if authenticate_response == User::AUTHENTICATE_SUCCESS
317       # Username/password combination is valid. Check if user is
318       # allowed to use MarkUs.
319       #
320       # sets this user as logged in if effective_user is a user in MarkUs
321       found_user = User.authorize(effective_user)
322       # if not nil, user authorized to enter MarkUs
323       if found_user.nil?
324         # This message actually means "User not allowed to use MarkUs",
325         # but it's from a security-perspective
326         # not a good idea to report this to the outside world. It makes it
327         # easier for attempted break-ins
328         # if one can distinguish between existent and non-existent users.
329         validation_result[:error] = I18n.t(:login_failed)
330         return validation_result
331       end
332     else
333       validation_result[:error] = I18n.t(:login_failed)
334       return validation_result
335     end
336 
337     # All good, set error to nil. Let's be explicit.
338     # Also, set the user key to found_user
339     validation_result[:error] = nil
340     validation_result[:user] = found_user
341     return validation_result
342   end
343 
344   # Returns the user with user name "effective_user" from the database given that the user
345   # with user name "real_user" is authenticated. Effective and real users must be
346   # different.
347   def validate_user_without_login(effective_user, real_user)
348     validation_result = Hash.new
349     validation_result[:user] = nil # Let's be explicit
350     # check for blank username
351     blank_login = effective_user.blank?
352     validation_result[:error] = get_blank_message(blank_login, false)
353     return validation_result if blank_login
354 
355     # Can't do user authentication, for a remote user setup, so
356     # only do authorization (i.e. valid user) checks.
357     found_user = User.authorize(effective_user)
358     # if not nil, user authorized to enter MarkUs
359     if found_user.nil?
360       # This message actually means "User not allowed to use MarkUs",
361       # but it's from a security-perspective
362       # not a good idea to report this to the outside world. It makes it
363       # easier for attempted break-ins
364       # if one can distinguish between existent and non-existent users.
365       validation_result[:error] = I18n.t(:login_failed)
366       return validation_result
367     end
368 
369     # All good, set error to nil. Let's be explicit.
370     # Also, set the user key to found_user
371     validation_result[:error] = nil
372     validation_result[:user] = found_user
373     return validation_result
374   end
375 
376 end

Generated on Tue Feb 07 00:07:35 -0500 2012 with rcov 0.9.10