storing the ip if one user is logged in from different machine
[opensuse:yast-web-client.git] / webclient / lib / authenticated_system.rb
1 #--
2 # Webyast Webservice framework
3 #
4 # Copyright (C) 2009, 2010 Novell, Inc. 
5 #   This library is free software; you can redistribute it and/or modify
6 # it only under the terms of version 2.1 of the GNU Lesser General Public
7 # License as published by the Free Software Foundation. 
8 #
9 #   This library is distributed in the hope that it will be useful, but WITHOUT
10 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 
12 # details. 
13 #
14 #   You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software 
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 #++
18
19 module AuthenticatedSystem
20   protected
21     # Returns true or false if the account is logged in.
22     # Preloads @current_account with the account model if they're logged in.
23     def logged_in?
24       !!current_account
25     end
26
27     # Accesses the current account from the session. 
28     # Future calls avoid the database because nil is not equal to false.
29     def current_account
30       @current_account ||= (login_from_session || login_from_basic_auth || login_from_cookie) unless @current_account == false # RORSCAN_ITL
31     end
32
33     # Store the given account id in the session.
34     def current_account=(new_account)
35       session[:account_id] = new_account ? new_account.id : nil
36       @current_account = new_account || false
37     end
38
39     # Check if the account is authorized
40     #
41     # Override this method in your controllers if you want to restrict access
42     # to only a few actions or if you want to check if the account
43     # has the correct rights.
44     #
45     # Example:
46     #
47     #  # only allow nonbobs
48     #  def authorized?
49     #    current_account.login != "bob"
50     #  end
51     def authorized?
52       logged_in?
53     end
54
55     # Filter method to enforce a login requirement.
56     #
57     # To require logins for all actions, use this in your controllers:
58     #
59     #   before_filter :login_required
60     #
61     # To require logins for specific actions, use this in your controllers:
62     #
63     #   before_filter :login_required, :only => [ :edit, :update ]
64     #
65     # To skip this in a subclassed controller:
66     #
67     #   skip_before_filter :login_required
68     #
69     def login_required
70       authorized? || access_denied
71     end
72
73     # Redirect as appropriate when an access request fails.
74     #
75     # The default action is to redirect to the login screen.
76     #
77     # Override this method in your controllers if you want to have special
78     # behavior in case the account is not authorized
79     # to access the requested action.  For example, a popup window might
80     # simply close itself.
81     def access_denied
82       store_location
83       redirect_to :controller => "session", :action => "new", :hostid => "localhost" #redirect by default to locahost appliance (bnc#602807)
84     end
85
86     # Store the URI of the current request in the session.
87     #
88     # We can return to this location by calling #redirect_back_or_default.
89     def store_location
90       session[:return_to] = request.request_uri
91     end
92
93     # Redirect to the URI stored by the most recent store_location call or
94     # to the passed default.
95     def redirect_back_or_default(default)      
96       redirect_to(session[:return_to] || default)
97       session[:return_to] = nil
98     end
99
100     # Inclusion hook to make #current_account and #logged_in?
101     # available as ActionView helper methods.
102     def self.included(base)
103       base.send :helper_method, :current_account, :logged_in?
104     end
105
106     # Called from #current_account.  First attempt to login by the account id stored in the session.
107     def login_from_session
108       self.current_account = Account.find_by_id(session[:account_id]) if session[:account_id]
109     end
110
111     # Called from #current_account.  Now, attempt to login by basic authentication information.
112     def login_from_basic_auth
113       authenticate_with_http_basic do |username, password|
114         return false if session[:host].blank?
115         self.current_account = Account.authenticate(username, password, session[:host], request.remote_ip)
116       end
117     end
118
119     # Called from #current_account.  Finaly, attempt to login by an expiring token in the cookie.
120     def login_from_cookie
121       account = cookies[:auth_token] && Account.find_by_remember_token(cookies[:auth_token])
122       if account && account.remember_token?
123         auth_token = { :value => account.remember_token, :expires => account.remember_token_expires_at }
124         # make cookie accessible via https only
125         auth_token[:secure] = true if ENV["RAILS_ENV"] == "production"
126         cookies[:auth_token] = auth_token
127         self.current_account = account
128       end
129     end
130 end