Mercurial > hg > soundsoftware-site
comparison .svn/pristine/bc/bcf601e4c2eab267682f5366299899e20f6d08d2.svn-base @ 1295:622f24f53b42 redmine-2.3
Update to Redmine SVN revision 11972 on 2.3-stable branch
author | Chris Cannam |
---|---|
date | Fri, 14 Jun 2013 09:02:21 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1294:3e4c3460b6ca | 1295:622f24f53b42 |
---|---|
1 OpenIdAuthentication | |
2 ==================== | |
3 | |
4 Provides a thin wrapper around the excellent ruby-openid gem from JanRan. Be sure to install that first: | |
5 | |
6 gem install ruby-openid | |
7 | |
8 To understand what OpenID is about and how it works, it helps to read the documentation for lib/openid/consumer.rb | |
9 from that gem. | |
10 | |
11 The specification used is http://openid.net/specs/openid-authentication-2_0.html. | |
12 | |
13 | |
14 Prerequisites | |
15 ============= | |
16 | |
17 OpenID authentication uses the session, so be sure that you haven't turned that off. | |
18 | |
19 Alternatively, you can use the file-based store, which just relies on on tmp/openids being present in RAILS_ROOT. But be aware that this store only works if you have a single application server. And it's not safe to use across NFS. It's recommended that you use the database store if at all possible. To use the file-based store, you'll also have to add this line to your config/environment.rb: | |
20 | |
21 OpenIdAuthentication.store = :file | |
22 | |
23 This particular plugin also relies on the fact that the authentication action allows for both POST and GET operations. | |
24 If you're using RESTful authentication, you'll need to explicitly allow for this in your routes.rb. | |
25 | |
26 The plugin also expects to find a root_url method that points to the home page of your site. You can accomplish this by using a root route in config/routes.rb: | |
27 | |
28 map.root :controller => 'articles' | |
29 | |
30 This plugin relies on Rails Edge revision 6317 or newer. | |
31 | |
32 | |
33 Example | |
34 ======= | |
35 | |
36 This example is just to meant to demonstrate how you could use OpenID authentication. You might well want to add | |
37 salted hash logins instead of plain text passwords and other requirements on top of this. Treat it as a starting point, | |
38 not a destination. | |
39 | |
40 Note that the User model referenced in the simple example below has an 'identity_url' attribute. You will want to add the same or similar field to whatever | |
41 model you are using for authentication. | |
42 | |
43 Also of note is the following code block used in the example below: | |
44 | |
45 authenticate_with_open_id do |result, identity_url| | |
46 ... | |
47 end | |
48 | |
49 In the above code block, 'identity_url' will need to match user.identity_url exactly. 'identity_url' will be a string in the form of 'http://example.com' - | |
50 If you are storing just 'example.com' with your user, the lookup will fail. | |
51 | |
52 There is a handy method in this plugin called 'normalize_url' that will help with validating OpenID URLs. | |
53 | |
54 OpenIdAuthentication.normalize_url(user.identity_url) | |
55 | |
56 The above will return a standardized version of the OpenID URL - the above called with 'example.com' will return 'http://example.com/' | |
57 It will also raise an InvalidOpenId exception if the URL is determined to not be valid. | |
58 Use the above code in your User model and validate OpenID URLs before saving them. | |
59 | |
60 config/routes.rb | |
61 | |
62 map.root :controller => 'articles' | |
63 map.resource :session | |
64 | |
65 | |
66 app/views/sessions/new.erb | |
67 | |
68 <% form_tag(session_url) do %> | |
69 <p> | |
70 <label for="name">Username:</label> | |
71 <%= text_field_tag "name" %> | |
72 </p> | |
73 | |
74 <p> | |
75 <label for="password">Password:</label> | |
76 <%= password_field_tag %> | |
77 </p> | |
78 | |
79 <p> | |
80 ...or use: | |
81 </p> | |
82 | |
83 <p> | |
84 <label for="openid_identifier">OpenID:</label> | |
85 <%= text_field_tag "openid_identifier" %> | |
86 </p> | |
87 | |
88 <p> | |
89 <%= submit_tag 'Sign in', :disable_with => "Signing in…" %> | |
90 </p> | |
91 <% end %> | |
92 | |
93 app/controllers/sessions_controller.rb | |
94 class SessionsController < ApplicationController | |
95 def create | |
96 if using_open_id? | |
97 open_id_authentication | |
98 else | |
99 password_authentication(params[:name], params[:password]) | |
100 end | |
101 end | |
102 | |
103 | |
104 protected | |
105 def password_authentication(name, password) | |
106 if @current_user = @account.users.authenticate(params[:name], params[:password]) | |
107 successful_login | |
108 else | |
109 failed_login "Sorry, that username/password doesn't work" | |
110 end | |
111 end | |
112 | |
113 def open_id_authentication | |
114 authenticate_with_open_id do |result, identity_url| | |
115 if result.successful? | |
116 if @current_user = @account.users.find_by_identity_url(identity_url) | |
117 successful_login | |
118 else | |
119 failed_login "Sorry, no user by that identity URL exists (#{identity_url})" | |
120 end | |
121 else | |
122 failed_login result.message | |
123 end | |
124 end | |
125 end | |
126 | |
127 | |
128 private | |
129 def successful_login | |
130 session[:user_id] = @current_user.id | |
131 redirect_to(root_url) | |
132 end | |
133 | |
134 def failed_login(message) | |
135 flash[:error] = message | |
136 redirect_to(new_session_url) | |
137 end | |
138 end | |
139 | |
140 | |
141 | |
142 If you're fine with the result messages above and don't need individual logic on a per-failure basis, | |
143 you can collapse the case into a mere boolean: | |
144 | |
145 def open_id_authentication | |
146 authenticate_with_open_id do |result, identity_url| | |
147 if result.successful? && @current_user = @account.users.find_by_identity_url(identity_url) | |
148 successful_login | |
149 else | |
150 failed_login(result.message || "Sorry, no user by that identity URL exists (#{identity_url})") | |
151 end | |
152 end | |
153 end | |
154 | |
155 | |
156 Simple Registration OpenID Extension | |
157 ==================================== | |
158 | |
159 Some OpenID Providers support this lightweight profile exchange protocol. See more: http://www.openidenabled.com/openid/simple-registration-extension | |
160 | |
161 You can support it in your app by changing #open_id_authentication | |
162 | |
163 def open_id_authentication(identity_url) | |
164 # Pass optional :required and :optional keys to specify what sreg fields you want. | |
165 # Be sure to yield registration, a third argument in the #authenticate_with_open_id block. | |
166 authenticate_with_open_id(identity_url, | |
167 :required => [ :nickname, :email ], | |
168 :optional => :fullname) do |result, identity_url, registration| | |
169 case result.status | |
170 when :missing | |
171 failed_login "Sorry, the OpenID server couldn't be found" | |
172 when :invalid | |
173 failed_login "Sorry, but this does not appear to be a valid OpenID" | |
174 when :canceled | |
175 failed_login "OpenID verification was canceled" | |
176 when :failed | |
177 failed_login "Sorry, the OpenID verification failed" | |
178 when :successful | |
179 if @current_user = @account.users.find_by_identity_url(identity_url) | |
180 assign_registration_attributes!(registration) | |
181 | |
182 if current_user.save | |
183 successful_login | |
184 else | |
185 failed_login "Your OpenID profile registration failed: " + | |
186 @current_user.errors.full_messages.to_sentence | |
187 end | |
188 else | |
189 failed_login "Sorry, no user by that identity URL exists" | |
190 end | |
191 end | |
192 end | |
193 end | |
194 | |
195 # registration is a hash containing the valid sreg keys given above | |
196 # use this to map them to fields of your user model | |
197 def assign_registration_attributes!(registration) | |
198 model_to_registration_mapping.each do |model_attribute, registration_attribute| | |
199 unless registration[registration_attribute].blank? | |
200 @current_user.send("#{model_attribute}=", registration[registration_attribute]) | |
201 end | |
202 end | |
203 end | |
204 | |
205 def model_to_registration_mapping | |
206 { :login => 'nickname', :email => 'email', :display_name => 'fullname' } | |
207 end | |
208 | |
209 Attribute Exchange OpenID Extension | |
210 =================================== | |
211 | |
212 Some OpenID providers also support the OpenID AX (attribute exchange) protocol for exchanging identity information between endpoints. See more: http://openid.net/specs/openid-attribute-exchange-1_0.html | |
213 | |
214 Accessing AX data is very similar to the Simple Registration process, described above -- just add the URI identifier for the AX field to your :optional or :required parameters. For example: | |
215 | |
216 authenticate_with_open_id(identity_url, | |
217 :required => [ :email, 'http://schema.openid.net/birthDate' ]) do |result, identity_url, registration| | |
218 | |
219 This would provide the sreg data for :email, and the AX data for 'http://schema.openid.net/birthDate' | |
220 | |
221 | |
222 | |
223 Copyright (c) 2007 David Heinemeier Hansson, released under the MIT license |