Class: Rack::OpenID

Inherits:
Object
  • Object
show all
Defined in:
lib/rack/openid.rb,
lib/rack/openid/simple_auth.rb

Overview

A Rack middleware that provides a more HTTPish API around the ruby-openid library.

You trigger an OpenID request similar to HTTP authentication. From your app, return a "401 Unauthorized" and a "WWW-Authenticate" header with the identifier you would like to validate.

On competition, the OpenID response is automatically verified and assigned to env["rack.openid.response"].

Defined Under Namespace

Classes: MissingResponse, SimpleAuth, TimeoutResponse

Constant Summary

HTTP_METHODS =

:stopdoc:

%w(GET
RESPONSE =
"rack.openid.response"
AUTHENTICATE_HEADER =
"WWW-Authenticate"
AUTHENTICATE_REGEXP =
/^OpenID/
URL_FIELD_SELECTOR =
lambda { |field| field.to_s =~ %r{^https?://} }

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, store = nil) ⇒ OpenID

Initialize middleware with application and optional OpenID::Store. If no store is given, OpenID::Store::Memory is used.

use Rack::OpenID

or

use Rack::OpenID, OpenID::Store::Memcache.new


85
86
87
88
# File 'lib/rack/openid.rb', line 85

def initialize(app, store = nil)
  @app = app
  @store = store || default_store
end

Class Method Details

.build_header(params = {}) ⇒ Object

Helper method for building the "WWW-Authenticate" header value.

Rack::OpenID.build_header(:identifier => "http://josh.openid.com/")
  #=> OpenID identifier="http://josh.openid.com/"


25
26
27
28
29
30
31
32
33
# File 'lib/rack/openid.rb', line 25

def self.build_header(params = {})
  'OpenID ' + params.map { |key, value|
    if value.is_a?(Array)
      "#{key}=\"#{value.join(',')}\""
    else
      "#{key}=\"#{value}\""
    end
  }.join(', ')
end

.parse_header(str) ⇒ Object

Helper method for parsing "WWW-Authenticate" header values into a hash.

Rack::OpenID.parse_header("OpenID identifier='http://josh.openid.com/'")
  #=> {:identifier => "http://josh.openid.com/"}


40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/rack/openid.rb', line 40

def self.parse_header(str)
  params = {}
  if str =~ AUTHENTICATE_REGEXP
    str = str.gsub(/#{AUTHENTICATE_REGEXP}\s+/, '')
    str.split(', ').each { |pair|
      key, *value = pair.split('=')
      value = value.join('=')
      value.gsub!(/^\"/, '').gsub!(/\"$/, "")
      value = value.split(',')
      params[key] = value.length > 1 ? value : value.first
    }
  end
  params
end

Instance Method Details

#call(env) ⇒ Object

Standard Rack call dispatch that accepts an env and returns a [status, header, body] response.



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/rack/openid.rb', line 92

def call(env)
  req = Rack::Request.new(env)
  if req.params["openid.mode"]
    complete_authentication(env)
  end

  status, headers, body = @app.call(env)

  qs = headers[AUTHENTICATE_HEADER]
  if status.to_i == 401 && qs && qs.match(AUTHENTICATE_REGEXP)
    begin_authentication(env, qs)
  else
    [status, headers, body]
  end
end