Class: OMF::Web::Rack::SessionAuthenticator
- Inherits:
-
Base::LObject
- Object
- Base::LObject
- OMF::Web::Rack::SessionAuthenticator
- Defined in:
- lib/omf-web/rack/session_authenticator.rb
Overview
This rack module maintains a session cookie and redirects any requests to protected pages to a ‘login’ page at the beginning of a session
Calls to the class methods are resolved inthe context of a Session using ‘OMF::Web::SessionStore’
Constant Summary collapse
- @@active =
false
- @@expire_after =
Expire authenticated session after being idle for that many seconds
2592000
Class Method Summary collapse
-
.[](key) ⇒ Object
DO NOT CALL DIRECTLY.
-
.[]=(key, value) ⇒ Object
DO NOT CALL DIRECTLY.
-
.active? ⇒ Boolean
Returns true if this Rack module has been instantiated in the current Rack stack.
-
.authenticate(expires = nil) ⇒ Object
Calling this method will authenticate the current session.
-
.authenticate_with(req) ⇒ Object
Attempt to authenticate with the provided ‘req’.
-
.authenticated? ⇒ Boolean
Return true if the session is authenticated.
-
.logout ⇒ Object
Logging out will un-authenticate this session.
-
.user ⇒ Object
Information about the authenticated user.
Instance Method Summary collapse
- #call(env) ⇒ Object
- #check_authenticated ⇒ Object
-
#initialize(app, opts = {}) ⇒ SessionAuthenticator
constructor
opts - :login_url - URL to redirect if session is not authenticated :no_session - Array of regexp on ‘path_info’ which do not require an authenticated session :expire_after - Idle time in sec after which to expire a session.
Constructor Details
#initialize(app, opts = {}) ⇒ SessionAuthenticator
opts -
:login_url - URL to redirect if session is not authenticated
:no_session - Array of regexp on 'path_info' which do not require an authenticated session
:expire_after - Idle time in sec after which to expire a session
110 111 112 113 114 115 116 117 118 |
# File 'lib/omf-web/rack/session_authenticator.rb', line 110 def initialize(app, opts = {}) @app = app @opts = opts @opts[:no_session] = (@opts[:no_session] || []).map { |s| Regexp.new(s) } if @opts[:expire_after] @@expire_after = @opts[:expire_after] end @@active = true end |
Class Method Details
.[](key) ⇒ Object
DO NOT CALL DIRECTLY
90 91 92 |
# File 'lib/omf-web/rack/session_authenticator.rb', line 90 def self.[](key) OMF::Web::SessionStore[key, :authenticator] end |
.[]=(key, value) ⇒ Object
DO NOT CALL DIRECTLY
96 97 98 |
# File 'lib/omf-web/rack/session_authenticator.rb', line 96 def self.[]=(key, value) OMF::Web::SessionStore[key, :authenticator] = value end |
.active? ⇒ Boolean
Returns true if this Rack module has been instantiated in the current Rack stack.
24 25 26 |
# File 'lib/omf-web/rack/session_authenticator.rb', line 24 def self.active? @@active end |
.authenticate(expires = nil) ⇒ Object
Calling this method will authenticate the current session
38 39 40 41 |
# File 'lib/omf-web/rack/session_authenticator.rb', line 38 def self.authenticate(expires = nil) self[:authenticated] = true self[:valid_until] = Time.now + @@expire_after end |
.authenticate_with(req) ⇒ Object
Attempt to authenticate with the provided ‘req’
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/omf-web/rack/session_authenticator.rb', line 50 def self.authenticate_with(req) p = req.params #puts ">>>>>>> AA(#{req.host_with_port}): #{p}" case t = p['method'] when 'persona' require 'net/http' unless assertion = p['assertion'] raise AuthenticationFailedException.new("Missing assertion") end http = Net::HTTP.new('verifier.login.persona.org', 443) http.use_ssl = true data = "assertion=#{assertion}&audience=#{req.host_with_port}" headers = {'Content-Type' => 'application/x-www-form-urlencoded'} reply = http.post('/verify', data, headers) unless reply.code_type == Net::HTTPOK && reply.content_type == "application/json" raise AuthenticationFailedException.new("Could not verify Persona - '#{reply.body}'") end debug "Persona reply: '#{reply.body}'" r = JSON.load(reply.body) unless ((email = r['email']) && (expires = r['expires'])) raise AuthenticationFailedException.new("Could not verify Persona - '#{r}'") end self[:user] = {name: email, email: email, method: 'persona'} authenticate(Time.at(expires)) else raise AuthenticationFailedException.new("Unsupported authentication type '#{t}'") end end |
.authenticated? ⇒ Boolean
Return true if the session is authenticated
30 31 32 33 34 |
# File 'lib/omf-web/rack/session_authenticator.rb', line 30 def self.authenticated? auth = self[:authenticated] == true && self[:valid_until] > Time.now #debug "AUTH: #{auth}" auth end |
.logout ⇒ Object
Logging out will un-authenticate this session
82 83 84 85 86 |
# File 'lib/omf-web/rack/session_authenticator.rb', line 82 def self.logout debug "LOGOUT" self[:authenticated] = false self[:user] = nil end |
.user ⇒ Object
Information about the authenticated user
45 46 47 |
# File 'lib/omf-web/rack/session_authenticator.rb', line 45 def self.user() self[:user] end |
Instance Method Details
#call(env) ⇒ Object
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/omf-web/rack/session_authenticator.rb', line 125 def call(env) req = ::Rack::Request.new(env) path_info = req.path_info sid = req.['sid'] unless sid sid = "s#{(rand * 10000000).to_i}_#{(rand * 10000000).to_i}" end Thread.current["sessionID"] = sid # needed for Session Store #debug "Request for '#{path_info}' - sid: #{sid} - #{self.class.authenticated?}" unless @opts[:no_session].find {|rx| rx.match(path_info) } # If 'login_page_url' is defined, check if this session is authenticated login_url = @opts[:login_page_url] if login_url && login_url != req.path_info begin check_authenticated rescue AuthenticationFailedException => ex if err = self.class[:login_error] login_url = login_url + "?msg=#{err}" end headers = {'Location' => login_url, "Content-Type" => ""} Rack::Utils.(headers, 'sid', sid) return [307, headers, ['Login first']] end end end status, headers, body = @app.call(env) Rack::Utils.(headers, 'sid', sid) # if sid [status, headers, body] end |
#check_authenticated ⇒ Object
120 121 122 123 |
# File 'lib/omf-web/rack/session_authenticator.rb', line 120 def check_authenticated authenticated = self.class.authenticated? raise AuthenticationFailedException.new unless authenticated end |