wycats / merb

master merb branch

6c740834 » wycats 2008-10-08 Move things to merb-more 1 # The openid strategy attempts to login users based on the OpenID protocol
2 # http://openid.net/
3 #
4 # Overwrite the on_sucess!, on_failure!, on_setup_needed!, and on_cancel! to customize events.
5 #
6 # Overwite the required_reg_fields method to require different sreg fields. Default is email and nickname
7 #
8 # Overwrite the openid_store method to customize your session store
9 #
10 # == Requirments
11 #
12 # === Routes:
13 # :openid - an action that is accessilbe via http GET and protected via ensure_authenticated
14 # :signup - a url accessed via GET that takes a user to a signup form (overwritable)
15 #
16 # === Attributes
17 # :identity_url - A string for holding the identity_url associated with this user (overwritable)
18 #
19 # install the ruby-openid gem
c72db0a7 » snusnu 2009-10-18 [merb-auth-more] Run shared... 20
6c740834 » wycats 2008-10-08 Move things to merb-more 21 require 'openid'
22 require 'openid/store/filesystem'
23 require 'openid/extensions/sreg'
24
d2a9c75c » hassox 2008-10-09 Changes the Authentication ... 25 class Merb::Authentication
6c740834 » wycats 2008-10-08 Move things to merb-more 26 module Strategies
27 module Basic
9a1eb96a » hassox 2008-11-06 Updates the openid strategy... 28 class OpenID < Merb::Authentication::Strategy
6c740834 » wycats 2008-10-08 Move things to merb-more 29 def run!
588ad874 » hassox 2008-10-10 Finishes adding protect to ... 30 if request.params[:'openid.mode']
6c740834 » wycats 2008-10-08 Move things to merb-more 31 response = consumer.complete(request.send(:query_params), "#{request.protocol}://#{request.host}" + request.path)
32 case response.status.to_s
33 when 'success'
34 sreg_response = ::OpenID::SReg::Response.from_success_response(response)
35 result = on_success!(response, sreg_response)
36 Merb.logger.info "\n\n#{result.inspect}\n\n"
37 result
38 when 'failure'
39 on_failure!(response)
40 when 'setup_needed'
41 on_setup_needed!(response)
42 when 'cancel'
43 on_cancel!(response)
44 end
45 elsif identity_url = params[:openid_url]
46 begin
47 openid_request = consumer.begin(identity_url)
48 openid_reg = ::OpenID::SReg::Request.new
30e77b26 » Matthew Ford 2009-02-04 [merb-auth-more] Fix requir... 49 openid_reg.request_fields(required_reg_fields, true)
50 openid_reg.request_fields(optional_reg_fields)
6c740834 » wycats 2008-10-08 Move things to merb-more 51 openid_request.add_extension(openid_reg)
504eb7bf » hassox 2008-11-06 Adds a method to openid to ... 52 customize_openid_request!(openid_request)
60fe5e79 » hassox 2008-11-06 Extracts the openid callbac... 53 redirect!(openid_request.redirect_url("#{request.protocol}://#{request.host}", openid_callback_url))
6c740834 » wycats 2008-10-08 Move things to merb-more 54 rescue ::OpenID::OpenIDError => e
55 request.session.authentication.errors.clear!
56 request.session.authentication.errors.add(:openid, 'The OpenID verification failed')
57 nil
58 end
59 end
60 end # run!
61
62
504eb7bf » hassox 2008-11-06 Adds a method to openid to ... 63 # Overwrite this to add extra options to the OpenID request before it is made.
64 #
65 # @example request.return_to_args["remember_me"] = 1 # remember_me=1 is added when returning from the OpenID provider.
66 #
67 # @api overwritable
68 def customize_openid_request!(openid_request)
69 end
70
60fe5e79 » hassox 2008-11-06 Extracts the openid callbac... 71 # Used to define the callback url for the openid provider. By default it
72 # is set to the named :openid route.
73 #
74 # @api overwritable
75 def openid_callback_url
76 "#{request.protocol}://#{request.host}#{Merb::Router.url(:openid)}"
77 end
78
6c740834 » wycats 2008-10-08 Move things to merb-more 79 # Overwrite the on_success! method with the required behavior for successful logins
80 #
81 # @api overwritable
82 def on_success!(response, sreg_response)
83 if user = find_user_by_identity_url(response.identity_url)
84 user
85 else
86 request.session[:'openid.url'] = response.identity_url
87 required_reg_fields.each do |f|
88 session[:"openid.#{f}"] = sreg_response.data[f] if sreg_response.data[f]
89 end if sreg_response
90 redirect!(Merb::Router.url(:signup))
91 end
92 end
93
94 # Overwrite the on_failure! method with the required behavior for failed logins
95 #
96 # @api overwritable
97 def on_failure!(response)
98 session.authentication.errors.clear!
99 session.authentication.errors.add(:openid, 'OpenID verification failed, maybe the provider is down? Or the session timed out')
100 nil
101 end
102
103 #
104 # @api overwritable
105 def on_setup_needed!(response)
106 request.session.authentication.errors.clear!
107 request.session.authentication.errors.add(:openid, 'OpenID does not seem to be configured correctly')
108 nil
109 end
110
111 #
112 # @api overwritable
113 def on_cancel!(response)
114 request.session.authentication.errors.clear!
115 request.session.authentication.errors.add(:openid, 'OpenID rejected our request')
116 nil
117 end
118
119 #
120 # @api overwritable
121 def required_reg_fields
122 ['nickname', 'email']
123 end
124
30e77b26 » Matthew Ford 2009-02-04 [merb-auth-more] Fix requir... 125 #
126 # @api overwritable
127 def optional_reg_fields
128 ['fullname']
129 end
130
6c740834 » wycats 2008-10-08 Move things to merb-more 131 # Overwrite this to support an ORM other than DataMapper
132 #
133 # @api overwritable
134 def find_user_by_identity_url(url)
135 user_class.first(:identity_url => url)
136 end
137
138 # Overwrite this method to set your store
139 #
140 # @api overwritable
141 def openid_store
142 ::OpenID::Store::Filesystem.new("#{Merb.root}/tmp/openid")
143 end
144
145 private
146 def consumer
147 @consumer ||= ::OpenID::Consumer.new(request.session, openid_store)
148 end
149
150 end # OpenID
151 end # Basic
152 end # Strategies
d2a9c75c » hassox 2008-10-09 Changes the Authentication ... 153 end # Merb::Authentication