[1] | 1 | module AuthenticatedSystem |
---|
| 2 | protected |
---|
| 3 | # Returns true or false if the user is logged in. |
---|
| 4 | # Preloads @current_user with the user model if they're logged in. |
---|
| 5 | def logged_in? |
---|
| 6 | current_user != :false |
---|
| 7 | end |
---|
| 8 | |
---|
| 9 | # Accesses the current user from the session. |
---|
| 10 | def current_user |
---|
| 11 | @current_user ||= (session[:user] && User.find_by_id(session[:user])) || :false |
---|
| 12 | end |
---|
| 13 | |
---|
| 14 | # Store the given user in the session. |
---|
| 15 | def current_user=(new_user) |
---|
| 16 | session[:user] = (new_user.nil? || new_user.is_a?(Symbol)) ? nil : new_user.id |
---|
| 17 | @current_user = new_user |
---|
| 18 | end |
---|
| 19 | |
---|
| 20 | # Check if the user is authorized. |
---|
| 21 | # |
---|
| 22 | # Override this method in your controllers if you want to restrict access |
---|
| 23 | # to only a few actions or if you want to check if the user |
---|
| 24 | # has the correct rights. |
---|
| 25 | # |
---|
| 26 | # Example: |
---|
| 27 | # |
---|
| 28 | # # only allow nonbobs |
---|
| 29 | # def authorize? |
---|
| 30 | # current_user.login != "bob" |
---|
| 31 | # end |
---|
| 32 | def authorized? |
---|
| 33 | true |
---|
| 34 | end |
---|
| 35 | |
---|
| 36 | # Filter method to enforce a login requirement. |
---|
| 37 | # |
---|
| 38 | # To require logins for all actions, use this in your controllers: |
---|
| 39 | # |
---|
| 40 | # before_filter :login_required |
---|
| 41 | # |
---|
| 42 | # To require logins for specific actions, use this in your controllers: |
---|
| 43 | # |
---|
| 44 | # before_filter :login_required, :only => [ :edit, :update ] |
---|
| 45 | # |
---|
| 46 | # To skip this in a subclassed controller: |
---|
| 47 | # |
---|
| 48 | # skip_before_filter :login_required |
---|
| 49 | # |
---|
| 50 | def login_required |
---|
| 51 | username, passwd = get_auth_data |
---|
| 52 | self.current_user ||= User.authenticate(username, passwd) || :false if username && passwd |
---|
| 53 | logged_in? && authorized? ? true : 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 | respond_to do |accepts| |
---|
| 66 | accepts.html do |
---|
| 67 | store_location |
---|
| 68 | redirect_to :controller => '/account', :action => 'login' |
---|
| 69 | end |
---|
| 70 | accepts.xml do |
---|
| 71 | headers["Status"] = "Unauthorized" |
---|
| 72 | headers["WWW-Authenticate"] = %(Basic realm="Web Password") |
---|
| 73 | render :text => "Could't authenticate you", :status => '401 Unauthorized' |
---|
| 74 | end |
---|
| 75 | end |
---|
| 76 | false |
---|
| 77 | end |
---|
| 78 | |
---|
| 79 | # Store the URI of the current request in the session. |
---|
| 80 | # |
---|
| 81 | # We can return to this location by calling #redirect_back_or_default. |
---|
| 82 | def store_location |
---|
| 83 | session[:return_to] = request.request_uri |
---|
| 84 | end |
---|
| 85 | |
---|
| 86 | # Redirect to the URI stored by the most recent store_location call or |
---|
| 87 | # to the passed default. |
---|
| 88 | def redirect_back_or_default(default) |
---|
| 89 | session[:return_to] ? redirect_to(session[:return_to]) : redirect_to(default) |
---|
| 90 | session[:return_to] = nil |
---|
| 91 | end |
---|
| 92 | |
---|
| 93 | # Inclusion hook to make #current_user and #logged_in? |
---|
| 94 | # available as ActionView helper methods. |
---|
| 95 | def self.included(base) |
---|
| 96 | base.send :helper_method, :current_user, :logged_in? |
---|
| 97 | end |
---|
| 98 | |
---|
| 99 | # When called with before_filter :login_from_cookie will check for an :auth_token |
---|
| 100 | # cookie and log the user back in if apropriate |
---|
| 101 | def login_from_cookie |
---|
| 102 | return unless cookies[:auth_token] && !logged_in? |
---|
| 103 | user = User.find_by_remember_token(cookies[:auth_token]) |
---|
| 104 | if user && user.remember_token? |
---|
| 105 | user.remember_me |
---|
| 106 | self.current_user = user |
---|
| 107 | cookies[:auth_token] = { :value => self.current_user.remember_token , :expires => self.current_user.remember_token_expires_at } |
---|
| 108 | flash[:notice] = "Logged in successfully" |
---|
| 109 | end |
---|
| 110 | end |
---|
| 111 | |
---|
| 112 | private |
---|
| 113 | @@http_auth_headers = %w(X-HTTP_AUTHORIZATION HTTP_AUTHORIZATION Authorization) |
---|
| 114 | # gets BASIC auth info |
---|
| 115 | def get_auth_data |
---|
| 116 | auth_key = @@http_auth_headers.detect { |h| request.env.has_key?(h) } |
---|
| 117 | auth_data = request.env[auth_key].to_s.split unless auth_key.blank? |
---|
| 118 | return auth_data && auth_data[0] == 'Basic' ? Base64.decode64(auth_data[1]).split(':')[0..1] : [nil, nil] |
---|
| 119 | end |
---|
| 120 | end |
---|