1+ module AuthenticatedSystem
2+ module Controller
3+ protected
4+ # Returns true or false if the user is logged in.
5+ # Preloads @current_user with the user model if they're logged in.
6+ def logged_in?
7+ current_user != :false
8+ end
9+
10+ # Accesses the current user from the session. Set it to :false if login fails
11+ # so that future calls do not hit the database.
12+ def current_user
13+ @current_user ||= ( login_from_session || login_from_basic_auth || login_from_cookie || :false )
14+ end
15+
16+ # Store the given user in the session.
17+ def current_user = ( new_user )
18+ session [ :user ] = ( new_user . nil? || new_user . is_a? ( Symbol ) ) ? nil : new_user . id
19+ @current_user = new_user
20+ end
21+
22+ # Check if the user is authorized
23+ #
24+ # Override this method in your controllers if you want to restrict access
25+ # to only a few actions or if you want to check if the user
26+ # has the correct rights.
27+ #
28+ # Example:
29+ #
30+ # # only allow nonbobs
31+ # def authorized?
32+ # current_user.login != "bob"
33+ # end
34+ def authorized?
35+ logged_in?
36+ end
37+
38+ # Filter method to enforce a login requirement.
39+ #
40+ # To require logins for all actions, use this in your controllers:
41+ #
42+ # before_filter :login_required
43+ #
44+ # To require logins for specific actions, use this in your controllers:
45+ #
46+ # before_filter :login_required, :only => [ :edit, :update ]
47+ #
48+ # To skip this in a subclassed controller:
49+ #
50+ # skip_before_filter :login_required
51+ #
52+ def login_required
53+ authorized? || throw ( :halt , :access_denied )
54+ end
55+
56+ # Redirect as appropriate when an access request fails.
57+ #
58+ # The default action is to redirect to the login screen.
59+ #
60+ # Override this method in your controllers if you want to have special
61+ # behavior in case the user is not authorized
62+ # to access the requested action. For example, a popup window might
63+ # simply close itself.
64+ def access_denied
65+ case content_type
66+ when :html
67+ store_location
68+ redirect url ( :login )
69+ when :xml
70+ headers [ "Status" ] = "Unauthorized"
71+ headers [ "WWW-Authenticate" ] = %(Basic realm="Web Password")
72+ set_status ( 401 )
73+ render :text => "Couldn't authenticate you"
74+ end
75+ end
76+
77+ # Store the URI of the current request in the session.
78+ #
79+ # We can return to this location by calling #redirect_back_or_default.
80+ def store_location
81+ session [ :return_to ] = request . uri
82+ end
83+
84+ # Redirect to the URI stored by the most recent store_location call or
85+ # to the passed default.
86+ def redirect_back_or_default ( default )
87+ loc = session [ :return_to ] || default
88+ session [ :return_to ] = nil
89+ redirect loc
90+ end
91+
92+ # Inclusion hook to make #current_user and #logged_in?
93+ # available as ActionView helper methods.
94+ # def self.included(base)
95+ # base.send :helper_method, :current_user, :logged_in?
96+ # end
97+
98+ # Called from #current_user. First attempt to login by the user id stored in the session.
99+ def login_from_session
100+ self . current_user = User . find_authenticated_model_with_id ( session [ :user ] ) if session [ :user ]
101+ end
102+
103+ # Called from #current_user. Now, attempt to login by basic authentication information.
104+ def login_from_basic_auth
105+ username , passwd = get_auth_data
106+ self . current_user = User . authenticate ( username , passwd ) if username && passwd
107+ end
108+
109+ # Called from #current_user. Finaly, attempt to login by an expiring token in the cookie.
110+ def login_from_cookie
111+ user = cookies [ :auth_token ] && User . find_authenticated_model_with_remember_token ( cookies [ :auth_token ] )
112+ if user && user . remember_token?
113+ user . remember_me
114+ cookies [ :auth_token ] = { :value => user . remember_token , :expires => user . remember_token_expires_at }
115+ self . current_user = user
116+ end
117+ end
118+
119+ def reset_session
120+ session . data . each { |k , v | session . data . delete ( k ) }
121+ end
122+
123+ private
124+ @@http_auth_headers = %w( Authorization HTTP_AUTHORIZATION X-HTTP_AUTHORIZATION X_HTTP_AUTHORIZATION REDIRECT_X_HTTP_AUTHORIZATION )
125+
126+ # gets BASIC auth info
127+ def get_auth_data
128+ auth_key = @@http_auth_headers . detect { |h | request . env . has_key? ( h ) }
129+ auth_data = request . env [ auth_key ] . to_s . split unless auth_key . blank?
130+ return auth_data && auth_data [ 0 ] == 'Basic' ? Base64 . decode64 ( auth_data [ 1 ] ) . split ( ':' ) [ 0 ..1 ] : [ nil , nil ]
131+ end
132+ end
133+ end
134+
135+ Merb ::BootLoader . after_app_loads do
136+ Application . send ( :include , AuthenticatedSystem ::Controller )
137+ end
0 commit comments