Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

153 lines (138 sloc) 5.37 kb
# The openid strategy attempts to login users based on the OpenID protocol
# http://openid.net/
#
# Overwrite the on_sucess!, on_failure!, on_setup_needed!, and on_cancel! to customize events.
#
# Overwite the required_reg_fields method to require different sreg fields. Default is email and nickname
#
# Overwrite the openid_store method to customize your session store
#
# == Requirments
#
# === Routes:
# :openid - an action that is accessilbe via http GET and protected via ensure_authenticated
# :signup - a url accessed via GET that takes a user to a signup form (overwritable)
#
# === Attributes
# :identity_url - A string for holding the identity_url associated with this user (overwritable)
#
# install the ruby-openid gem
require 'openid'
require 'openid/store/filesystem'
require 'openid/extensions/sreg'
class Merb::Authentication
module Strategies
module Basic
class OpenID < Merb::Authentication::Strategy
def run!
if request.params[:'openid.mode']
response = consumer.complete(request.send(:query_params), "#{request.protocol}://#{request.host}" + request.path)
case response.status.to_s
when 'success'
sreg_response = ::OpenID::SReg::Response.from_success_response(response)
result = on_success!(response, sreg_response)
Merb.logger.info "\n\n#{result.inspect}\n\n"
result
when 'failure'
on_failure!(response)
when 'setup_needed'
on_setup_needed!(response)
when 'cancel'
on_cancel!(response)
end
elsif identity_url = params[:openid_url]
begin
openid_request = consumer.begin(identity_url)
openid_reg = ::OpenID::SReg::Request.new
openid_reg.request_fields(required_reg_fields, true)
openid_reg.request_fields(optional_reg_fields)
openid_request.add_extension(openid_reg)
customize_openid_request!(openid_request)
redirect!(openid_request.redirect_url("#{request.protocol}://#{request.host}", openid_callback_url))
rescue ::OpenID::OpenIDError => e
request.session.authentication.errors.clear!
request.session.authentication.errors.add(:openid, 'The OpenID verification failed')
nil
end
end
end # run!
# Overwrite this to add extra options to the OpenID request before it is made.
#
# @example request.return_to_args["remember_me"] = 1 # remember_me=1 is added when returning from the OpenID provider.
#
# @api overwritable
def customize_openid_request!(openid_request)
end
# Used to define the callback url for the openid provider. By default it
# is set to the named :openid route.
#
# @api overwritable
def openid_callback_url
"#{request.protocol}://#{request.host}#{Merb::Router.url(:openid)}"
end
# Overwrite the on_success! method with the required behavior for successful logins
#
# @api overwritable
def on_success!(response, sreg_response)
if user = find_user_by_identity_url(response.identity_url)
user
else
request.session[:'openid.url'] = response.identity_url
required_reg_fields.each do |f|
session[:"openid.#{f}"] = sreg_response.data[f] if sreg_response.data[f]
end if sreg_response
redirect!(Merb::Router.url(:signup))
end
end
# Overwrite the on_failure! method with the required behavior for failed logins
#
# @api overwritable
def on_failure!(response)
session.authentication.errors.clear!
session.authentication.errors.add(:openid, 'OpenID verification failed, maybe the provider is down? Or the session timed out')
nil
end
#
# @api overwritable
def on_setup_needed!(response)
request.session.authentication.errors.clear!
request.session.authentication.errors.add(:openid, 'OpenID does not seem to be configured correctly')
nil
end
#
# @api overwritable
def on_cancel!(response)
request.session.authentication.errors.clear!
request.session.authentication.errors.add(:openid, 'OpenID rejected our request')
nil
end
#
# @api overwritable
def required_reg_fields
['nickname', 'email']
end
#
# @api overwritable
def optional_reg_fields
['fullname']
end
# Overwrite this to support an ORM other than DataMapper
#
# @api overwritable
def find_user_by_identity_url(url)
user_class.first(:identity_url => url)
end
# Overwrite this method to set your store
#
# @api overwritable
def openid_store
::OpenID::Store::Filesystem.new("#{Merb.root}/tmp/openid")
end
private
def consumer
@consumer ||= ::OpenID::Consumer.new(request.session, openid_store)
end
end # OpenID
end # Basic
end # Strategies
end # Merb::Authentication
Jump to Line
Something went wrong with that request. Please try again.