1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 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
|
require 'rack/openid'
require 'rack/request'
module Rack
class OpenID
# A simple OpenID middleware that restricts access to
# a single identifier.
#
# use Rack::OpenID::SimpleAuth, "http://example.org"
#
# SimpleAuth will automatically insert the required Rack::OpenID
# middleware, so use Rack::OpenID is unnecessary.
class SimpleAuth
def self.new(*args)
Rack::OpenID.new(super)
end
attr_reader :app, :identifier
def initialize(app, identifier)
@app = app
@identifier = identifier
end
def call(env)
if session_authenticated?(env)
app.call(env)
elsif successful_response?(env)
authenticate_session(env)
redirect_to requested_url(env)
else
authentication_request
end
end
private
def session(env)
env['rack.session'] || raise_session_error
end
def raise_session_error
raise RuntimeError, 'Rack::OpenID::SimpleAuth requires a session'
end
def session_authenticated?(env)
session(env)['authenticated'] == true
end
def authenticate_session(env)
session(env)['authenticated'] = true
end
def successful_response?(env)
if resp = env[OpenID::RESPONSE]
resp.status == :success && resp.display_identifier == identifier
end
end
def requested_url(env)
req = Rack::Request.new(env)
req.url
end
def redirect_to(url)
[303, {'Content-Type' => 'text/html', 'Location' => url}, []]
end
def authentication_request
[401, { OpenID::AUTHENTICATE_HEADER => www_authenticate_header }, []]
end
def www_authenticate_header
OpenID.build_header(:identifier => identifier)
end
end
end
end
|