authlogic_rpx 1.0.3 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +7 -0
- data/README.rdoc +87 -24
- data/Rakefile +3 -3
- data/authlogic_rpx.gemspec +6 -5
- data/lib/authlogic_rpx/acts_as_authentic.rb +24 -4
- data/lib/authlogic_rpx/helper.rb +12 -6
- data/lib/authlogic_rpx/session.rb +41 -18
- data/lib/authlogic_rpx/version.rb +1 -1
- data/test/fixtures/users.yml +5 -0
- data/test/libs/user_session.rb +1 -0
- data/test/session_test.rb +6 -1
- data/test/test_helper.rb +18 -6
- metadata +5 -5
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
== 1.0.4 released 2009-10-10
|
2
|
+
|
3
|
+
* added new hooks for profile mapping (Session.map_rpx_data_each_login, ActsAsAuthentic.map_added_rpx_data) based on suggestion by trosser (github issue #5)
|
4
|
+
* now supporting obtrusive (javascript pop-over) and unobtrusive (link) RPX pop-up sign-in forms. See rpx_popup method. (github issue #4)
|
5
|
+
* updated support for rpx_now gem version 0.6.6
|
6
|
+
* documentation updates
|
7
|
+
|
1
8
|
== 1.0.3 released 2009-10-07
|
2
9
|
|
3
10
|
* added general error handler for session validation to give clean 'failure' when underlying errors encountered (e.g. user model database constraint violation)
|
data/README.rdoc
CHANGED
@@ -35,14 +35,14 @@ Three gems are required: authlogic, grosser-rpx_now, and authlogic_rpx. Install
|
|
35
35
|
|
36
36
|
Currently tested versions:
|
37
37
|
* authlogic 2.1.2,2.1.1
|
38
|
-
*
|
39
|
-
* authlogic_rpx 1.0.
|
38
|
+
* rpx_now 0.6.6
|
39
|
+
* authlogic_rpx 1.0.4
|
40
40
|
|
41
41
|
|
42
42
|
=== 1. Direct gem installation
|
43
43
|
|
44
44
|
sudo gem install authlogic
|
45
|
-
sudo gem install
|
45
|
+
sudo gem install rpx_now --source http://gemcutter.org
|
46
46
|
sudo gem install authlogic_rpx --source http://gemcutter.org
|
47
47
|
|
48
48
|
|
@@ -50,9 +50,9 @@ Currently tested versions:
|
|
50
50
|
|
51
51
|
Include in config/environment.rb:
|
52
52
|
|
53
|
-
config.gem
|
54
|
-
config.gem
|
55
|
-
config.gem
|
53
|
+
config.gem 'authlogic', :version => '>= 2.1.1'
|
54
|
+
config.gem 'rpx_now', :version => '>= 0.6.6', :source => 'http://gemcutter.org'
|
55
|
+
config.gem 'authlogic_rpx', :version => '>= 1.0.4', :source => 'http://gemcutter.org'
|
56
56
|
|
57
57
|
Then to install, run from the command line:
|
58
58
|
|
@@ -63,9 +63,9 @@ Then to install, run from the command line:
|
|
63
63
|
|
64
64
|
Include in RAILS_ROOT/.gems:
|
65
65
|
|
66
|
-
authlogic
|
67
|
-
|
68
|
-
authlogic_rpx --source gemcutter.org
|
66
|
+
authlogic --version '>= 2.1.1'
|
67
|
+
rpx_now --version '>= 0.6.6' --source gemcutter.org
|
68
|
+
authlogic_rpx --version '>= 1.0.4' --source gemcutter.org
|
69
69
|
|
70
70
|
|
71
71
|
== Using Authlogic RPX
|
@@ -79,7 +79,7 @@ An important capability to be aware of is "auto registration". This means that w
|
|
79
79
|
The main steps for enabling Authlogic RPX:
|
80
80
|
* 1. Enable RPX for your user model
|
81
81
|
* 2. Add RPX configuration for the Authlogic session model
|
82
|
-
* 3 Add custom user profile mapping (optional)
|
82
|
+
* 3. Add custom user profile mapping (optional)
|
83
83
|
* 4. Add application controller helpers: current_user, current_user_session
|
84
84
|
* 5. Setup the Authlogic session controller
|
85
85
|
* 6. Setup the Authlogic user controller
|
@@ -90,7 +90,9 @@ The main steps for enabling Authlogic RPX:
|
|
90
90
|
=== 1. Enable RPX for your user model
|
91
91
|
|
92
92
|
The user model requires an additional field called "rpx_identifier". Creat a migration to add this.
|
93
|
-
You may need to remove database constraints on other fields if they will be unused in the RPX case (e.g. crypted_password and password_salt to make password authentication optional)
|
93
|
+
You may need to remove database constraints on other fields if they will be unused in the RPX case (e.g. crypted_password and password_salt to make password authentication optional).
|
94
|
+
|
95
|
+
If you are using auto-registration, you must also remove any database constraints for fields that will be automatically mapped (see notes in "3. Add custom user profile mapping during auto-registration")
|
94
96
|
|
95
97
|
class AddUsersRpxIdentifier < ActiveRecord::Migration
|
96
98
|
def self.up
|
@@ -156,19 +158,20 @@ For example, to disable auto-registration and enable extended info:
|
|
156
158
|
|
157
159
|
{See the source for the sample user_session.rb}[http://github.com/tardate/rails-authlogic-rpx-sample/blob/master/app/models/user_session.rb].
|
158
160
|
|
159
|
-
=== 3. Add custom user profile mapping
|
161
|
+
=== 3. Add custom user profile mapping (optional)
|
160
162
|
|
161
|
-
|
163
|
+
Authlogic_rpx provides three hooks for mapping information from the RPX profile into your application's user model:
|
164
|
+
|
165
|
+
* map_rpx_data: user profile mapping during auto-registration
|
166
|
+
* map_rpx_data_each_login: user profile mapping during login
|
167
|
+
* map_added_rpx_data: user profile mapping when adding RPX to an existing account
|
168
|
+
|
169
|
+
See https://rpxnow.com/docs#profile_data for the definition of available attributes in the RPX profile.
|
162
170
|
|
163
|
-
|
164
|
-
Authlogic_rpx will optimistically attempt to save the user record during registration, and violating a unique constraint will cause the authentication/registration to fail.
|
171
|
+
=== 3a. map_rpx_data: user profile mapping during auto-registration
|
165
172
|
|
166
|
-
|
173
|
+
When users auto-register, profile data from RPX is available to be inserted in the user's record on your site. By default, authlogic_rpx will map the username and email fields.
|
167
174
|
|
168
|
-
validates_uniqueness_of :username, :case_sensitive => false
|
169
|
-
|
170
|
-
This will allow the auto-registration to proceed, and the user can be given a chance to rectify the validation errors on your user profile page.
|
171
|
-
|
172
175
|
If you have other fields you want to map, you can provide your own implementation of the map_rpx_data method in the UserSession model. In that method, you will be updating the "self.attempted_record" object, with information from the "@rpx_data" object. See the {RPX documentation}[https://rpxnow.com/docs#profile_data] to find out about the set of information that is available.
|
173
176
|
|
174
177
|
class UserSession < Authlogic::Session::Base
|
@@ -196,6 +199,62 @@ If you have other fields you want to map, you can provide your own implementatio
|
|
196
199
|
|
197
200
|
end
|
198
201
|
|
202
|
+
{See the source for the sample user_session.rb}[http://github.com/tardate/rails-authlogic-rpx-sample/blob/master/app/models/user_session.rb].
|
203
|
+
|
204
|
+
WARNING: if you are using auto-registration, any fields you map should NOT have constraints enforced at the database level.
|
205
|
+
Authlogic_rpx will optimistically attempt to save the user record during registration, and violating a database constraint will cause the authentication/registration to fail.
|
206
|
+
|
207
|
+
You can/should enforce any required validations at the model level e.g.
|
208
|
+
|
209
|
+
validates_uniqueness_of :username, :case_sensitive => false
|
210
|
+
|
211
|
+
This will allow the auto-registration to proceed, and the user can be given a chance to rectify the validation errors on your user profile page.
|
212
|
+
|
213
|
+
If it is not acceptable in your application to have user records created with potential validation errors in auto-populated fields, you will need to override map_rpx_data and implement whatever special handling makes sense in your case. For example:
|
214
|
+
|
215
|
+
* directly check for uniqueness and other validation requirements
|
216
|
+
* automatically "uniquify" certain fields like username
|
217
|
+
* save conflicting profile information to "pending user review" columns or a seperate table
|
218
|
+
|
219
|
+
|
220
|
+
==== 3b. map_rpx_data_each_login: user profile mapping during login
|
221
|
+
|
222
|
+
map_rpx_data_each_login provides a hook to allow you to map RPX profile information every time the user logs in.
|
223
|
+
|
224
|
+
By default, nothing is mapped. If you have other fields you want to map, you can provide your own implementation of the map_rpx_data_each_login method in the UserSession model.
|
225
|
+
|
226
|
+
This would mainly be used to update relatively volatile information that you are maintaining in the user model (such as profile image url)
|
227
|
+
|
228
|
+
In the map_rpx_data_each_login procedure, you will be writing to fields of the "self.attempted_record" object, pulling data from the @rpx_data object. For example:
|
229
|
+
|
230
|
+
def map_rpx_data_each_login
|
231
|
+
# we'll always update photo_url
|
232
|
+
self.attempted_record.photo_url = @rpx_data['profile']['photo']
|
233
|
+
end
|
234
|
+
|
235
|
+
{See the source for the sample user_session.rb}[http://github.com/tardate/rails-authlogic-rpx-sample/blob/master/app/models/user_session.rb].
|
236
|
+
|
237
|
+
|
238
|
+
==== 3c. map_added_rpx_data: user profile mapping when adding RPX to an existing account
|
239
|
+
|
240
|
+
map_added_rpx_data maps additional fields from the RPX response into the user object during the "add RPX to existing account" process.
|
241
|
+
|
242
|
+
By default, it only maps the rpx_identifier field. If you have other fields you want to map, you can provide your own implementation of the map_added_rpx_data method in the User model (NOT UserSession, unlike for map_rpx_data and map_rpx_data_each_login).
|
243
|
+
|
244
|
+
NB: If you override this method, you will be responsible for also mapping the rpx_identifier.
|
245
|
+
|
246
|
+
In the map_added_rpx_data procedure, you will be writing to fields of the "self" object, pulling data from the rpx_data parameter. For example:
|
247
|
+
|
248
|
+
def map_added_rpx_data( rpx_data )
|
249
|
+
self.rpx_identifier = rpx_data['profile']['identifier']
|
250
|
+
|
251
|
+
# map some additional fields, e.g. photo_url
|
252
|
+
self.photo_url = rpx_data['profile']['photo'] if photo_url.blank?
|
253
|
+
end
|
254
|
+
|
255
|
+
{See the source for the sample user.rb}[http://github.com/tardate/rails-authlogic-rpx-sample/blob/master/app/models/user.rb].
|
256
|
+
|
257
|
+
|
199
258
|
=== 4. Add application controller helpers: current_user, current_user_session
|
200
259
|
|
201
260
|
We'll add current_user and current_user_session helpers. These can then be used in controllers and views to get a handle on the "current" logged in user.
|
@@ -367,6 +426,7 @@ Each takes an options hash:
|
|
367
426
|
* <tt>app_name:</tt> name of the application you set when registering your service at rpxnow.com (will be prepended to RPX domain and used in RPX dialogues)
|
368
427
|
* <tt>return_url:</tt> url for the RPX callback (e.g. user_sessions_url)
|
369
428
|
* <tt>add_rpx:</tt> Optional. If true, requests RPX callback to add to current session. Else runs normal authentication process (default). See "7. Allow users to "Add RPX" to existing accounts"
|
429
|
+
* <tt>unobtrusive:</tt> true/false; sets javascript style for link. unobtrusive=true links directly to rpxnow site, whereas unobtrusive=false does a javascript pop-over. Default: true (only used by rpx_popup)
|
370
430
|
|
371
431
|
For example, to insert a login link in a navigation bar is as simple as this:
|
372
432
|
|
@@ -376,7 +436,7 @@ For example, to insert a login link in a navigation bar is as simple as this:
|
|
376
436
|
<%= link_to "Profile", user_path(:current) %> |
|
377
437
|
<%= link_to "Sign out", signout_path %>
|
378
438
|
<% else %>
|
379
|
-
<%= rpx_popup( :link_text => "Register/Sign in with RPX..", :app_name => "rails-authlogic-rpx-sample", :return_url => user_sessions_url ) %>>
|
439
|
+
<%= rpx_popup( :link_text => "Register/Sign in with RPX..", :app_name => "rails-authlogic-rpx-sample", :return_url => user_sessions_url, :unobtrusive => false ) %>>
|
380
440
|
<% end %>
|
381
441
|
</div>
|
382
442
|
|
@@ -407,6 +467,11 @@ You'll note this is almost identical to the "update". The main difference is tha
|
|
407
467
|
|
408
468
|
map.addrpxauth "addrpxauth", :controller => "users", :action => "addrpxauth", :method => :post
|
409
469
|
|
470
|
+
To make an "Add RPX authentication for this account.." link, use rpx_popup as for normal RPX login, but set the return_url to the "addrpxauth" callback you have provided, and set the option :add_rpx to tru:
|
471
|
+
|
472
|
+
<%= rpx_popup( :link_text => "Add RPX authentication for this account..", :app_name => RPX_APP_NAME, :return_url => addrpxauth_url, :add_rpx => true, :unobtrusive => false ) %>
|
473
|
+
|
474
|
+
|
410
475
|
=== 9. There is no 9
|
411
476
|
|
412
477
|
That's all there is. To see Authlogic_RPX in action, check out the demonstration Rails application:
|
@@ -451,16 +516,14 @@ Some design principles:
|
|
451
516
|
|
452
517
|
# update manifest file
|
453
518
|
$ rake manifest
|
454
|
-
|
455
519
|
# update gemspec
|
456
520
|
$ rake build_gemspec
|
457
|
-
|
458
521
|
# build the gem
|
459
522
|
gem build authlogic_rpx.gemspec
|
460
|
-
|
461
523
|
# push the gem to gemcutter (e.g. for version 1.0.3)
|
462
524
|
gem push authlogic_rpx-1.0.3.gem
|
463
525
|
|
526
|
+
|
464
527
|
== Kudos and Kopywrite
|
465
528
|
|
466
529
|
Thanks to {binarylogic}[http://github.com/binarylogic] for cleaning up authentication in rails by creating Authlogic in the first place and offering it to the community.
|
data/Rakefile
CHANGED
@@ -10,11 +10,11 @@ Echoe.new("authlogic_rpx") do |p|
|
|
10
10
|
p.summary = "Authlogic plug-in for RPX support"
|
11
11
|
p.description = "Authlogic extension/plugin that provides RPX (rpxnow.com) authentication support"
|
12
12
|
|
13
|
-
p.runtime_dependencies = ["authlogic >=2.1.1", "
|
13
|
+
p.runtime_dependencies = ["authlogic >=2.1.1", "rpx_now >=0.6.6" ]
|
14
14
|
p.development_dependencies = []
|
15
15
|
|
16
16
|
p.author = "Paul Gallagher / tardate"
|
17
|
-
p.email =
|
17
|
+
p.email = "gallagher.paul@gmail.com"
|
18
18
|
|
19
|
-
p.
|
19
|
+
p.install_message = ""
|
20
20
|
end
|
data/authlogic_rpx.gemspec
CHANGED
@@ -2,16 +2,17 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{authlogic_rpx}
|
5
|
-
s.version = "1.0.
|
5
|
+
s.version = "1.0.4"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Paul Gallagher / tardate"]
|
9
|
-
s.date = %q{2009-10-
|
9
|
+
s.date = %q{2009-10-15}
|
10
10
|
s.description = %q{Authlogic extension/plugin that provides RPX (rpxnow.com) authentication support}
|
11
11
|
s.email = %q{gallagher.paul@gmail.com}
|
12
12
|
s.extra_rdoc_files = ["CHANGELOG.rdoc", "README.rdoc", "lib/authlogic_rpx.rb", "lib/authlogic_rpx/acts_as_authentic.rb", "lib/authlogic_rpx/helper.rb", "lib/authlogic_rpx/session.rb", "lib/authlogic_rpx/version.rb"]
|
13
13
|
s.files = ["CHANGELOG.rdoc", "MIT-LICENSE", "Manifest", "README.rdoc", "Rakefile", "authlogic_rpx.gemspec", "init.rb", "lib/authlogic_rpx.rb", "lib/authlogic_rpx/acts_as_authentic.rb", "lib/authlogic_rpx/helper.rb", "lib/authlogic_rpx/session.rb", "lib/authlogic_rpx/version.rb", "rails/init.rb", "test/acts_as_authentic_test.rb", "test/fixtures/users.yml", "test/libs/rails_trickery.rb", "test/libs/user.rb", "test/libs/user_session.rb", "test/session_test.rb", "test/test_helper.rb"]
|
14
14
|
s.homepage = %q{http://github.com/tardate/authlogic_rpx}
|
15
|
+
s.post_install_message = %q{}
|
15
16
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Authlogic_rpx", "--main", "README.rdoc"]
|
16
17
|
s.require_paths = ["lib"]
|
17
18
|
s.rubyforge_project = %q{authlogic_rpx}
|
@@ -25,13 +26,13 @@ Gem::Specification.new do |s|
|
|
25
26
|
|
26
27
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
27
28
|
s.add_runtime_dependency(%q<authlogic>, [">= 2.1.1"])
|
28
|
-
s.add_runtime_dependency(%q<
|
29
|
+
s.add_runtime_dependency(%q<rpx_now>, [">= 0.6.6"])
|
29
30
|
else
|
30
31
|
s.add_dependency(%q<authlogic>, [">= 2.1.1"])
|
31
|
-
s.add_dependency(%q<
|
32
|
+
s.add_dependency(%q<rpx_now>, [">= 0.6.6"])
|
32
33
|
end
|
33
34
|
else
|
34
35
|
s.add_dependency(%q<authlogic>, [">= 2.1.1"])
|
35
|
-
s.add_dependency(%q<
|
36
|
+
s.add_dependency(%q<rpx_now>, [">= 0.6.6"])
|
36
37
|
end
|
37
38
|
end
|
@@ -64,16 +64,36 @@ module AuthlogicRpx
|
|
64
64
|
!using_rpx? && require_password?
|
65
65
|
end
|
66
66
|
|
67
|
+
# hook for adding RPX identifier to an existing account. This is invoked prior to model validation.
|
68
|
+
# RPX information is plucked from the controller session object (where it was placed by the session model as a result
|
69
|
+
# of the RPX callback)
|
70
|
+
# The minimal action taken is to populate the rpx_identifier field in the user model.
|
71
|
+
#
|
72
|
+
# This procedure chains to the map_added_rpx_data, which may be over-ridden in your project to perform
|
73
|
+
# additional mapping of RPX information to the user model as may be desired.
|
74
|
+
#
|
67
75
|
def adding_rpx_identifier
|
68
76
|
return true unless session_class && session_class.controller
|
69
|
-
|
70
|
-
unless
|
71
|
-
session_class.controller.session['
|
72
|
-
|
77
|
+
added_rpx_data = session_class.controller.session['added_rpx_data']
|
78
|
+
unless added_rpx_data.blank?
|
79
|
+
session_class.controller.session['added_rpx_data'] = nil
|
80
|
+
map_added_rpx_data( added_rpx_data )
|
73
81
|
end
|
74
82
|
return true
|
75
83
|
end
|
76
84
|
|
85
|
+
# map_added_rpx_data maps additional fields from the RPX response into the user object during the "add RPX to existing account" process.
|
86
|
+
# Override this in your user model to perform field mapping as may be desired
|
87
|
+
# See https://rpxnow.com/docs#profile_data for the definition of available attributes
|
88
|
+
#
|
89
|
+
# By default, it only maps the rpx_identifier field.
|
90
|
+
#
|
91
|
+
def map_added_rpx_data( rpx_data )
|
92
|
+
self.rpx_identifier = rpx_data['profile']['identifier']
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
|
77
97
|
# experimental - a feature of RPX paid accounts and not properly developed/tested yet
|
78
98
|
def map_id?
|
79
99
|
self.class.map_id
|
data/lib/authlogic_rpx/helper.rb
CHANGED
@@ -6,6 +6,7 @@ module AuthlogicRpx
|
|
6
6
|
# * <tt>app_name:</tt> name of the application (will be prepended to RPX domain and used in RPX dialogues)
|
7
7
|
# * <tt>return_url:</tt> url for the RPX callback (e.g. user_sessions_url)
|
8
8
|
# * <tt>add_rpx:</tt> if true, requests RPX callback to add to current session. Else runs normal authentication process (default)
|
9
|
+
#
|
9
10
|
def rpx_embed(options = {})
|
10
11
|
params = (
|
11
12
|
{ :authenticity_token => form_authenticity_token, :add_rpx => options[:add_rpx] }.collect { |n| "#{n[0]}=#{ u(n[1]) }" if n[1] }
|
@@ -19,17 +20,22 @@ module AuthlogicRpx
|
|
19
20
|
# * <tt>app_name:</tt> name of the application (will be prepended to RPX domain and used in RPX dialogues)
|
20
21
|
# * <tt>return_url:</tt> url for the RPX callback (e.g. user_sessions_url)
|
21
22
|
# * <tt>add_rpx:</tt> if true, requests RPX callback to add to current session. Else runs normal authentication process (default)
|
23
|
+
# * <tt>unobtrusive:</tt> true/false; sets javascript style for link. Default: true
|
24
|
+
#
|
25
|
+
# NB: i18n considerations? supports a :language parameter (not tested)
|
22
26
|
def rpx_popup(options = {})
|
23
27
|
params = (
|
24
28
|
{ :authenticity_token => form_authenticity_token, :add_rpx => options[:add_rpx] }.collect { |n| "#{n[0]}=#{ u(n[1]) }" if n[1] }
|
25
29
|
).compact.join('&')
|
30
|
+
unobtrusive = options[:unobtrusive].nil? ? true : options[:unobtrusive]
|
31
|
+
return_url = options[:return_url] + '?' + params
|
32
|
+
return_url = u( return_url ) if unobtrusive # double-encoding required only if unobtrusive mode used
|
26
33
|
RPXNow.popup_code(
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
# NB: i18n considerations? supports a :language parameter (not tested)
|
34
|
+
options[:link_text],
|
35
|
+
options[:app_name],
|
36
|
+
return_url,
|
37
|
+
:unobtrusive=>unobtrusive
|
38
|
+
)
|
33
39
|
end
|
34
40
|
|
35
41
|
end
|
@@ -62,7 +62,6 @@ module AuthlogicRpx
|
|
62
62
|
klass.class_eval do
|
63
63
|
attr_accessor :new_registration
|
64
64
|
attr_accessor :rpx_identifier
|
65
|
-
attr_accessor :rpx_data
|
66
65
|
after_persisting :add_rpx_identifier, :if => :adding_rpx_identifier?
|
67
66
|
validate :validate_by_rpx, :if => :authenticating_with_rpx?
|
68
67
|
end
|
@@ -83,10 +82,14 @@ module AuthlogicRpx
|
|
83
82
|
end
|
84
83
|
|
85
84
|
private
|
85
|
+
# Tests if current request is for RPX authentication
|
86
|
+
#
|
86
87
|
def authenticating_with_rpx?
|
87
88
|
controller.params[:token] && !controller.params[:add_rpx]
|
88
89
|
end
|
89
90
|
|
91
|
+
# hook instance finder method to class
|
92
|
+
#
|
90
93
|
def find_by_rpx_identifier_method
|
91
94
|
self.class.find_by_rpx_identifier_method
|
92
95
|
end
|
@@ -103,25 +106,25 @@ module AuthlogicRpx
|
|
103
106
|
self.class.rpx_extended_info_value
|
104
107
|
end
|
105
108
|
|
109
|
+
# Tests if current request is the special case of adding RPX to an existing account
|
110
|
+
#
|
106
111
|
def adding_rpx_identifier?
|
107
112
|
controller.params[:token] && controller.params[:add_rpx]
|
108
113
|
end
|
109
114
|
|
110
|
-
# the
|
111
|
-
# has been
|
112
|
-
# user
|
113
|
-
#
|
114
|
-
#
|
115
|
-
#
|
116
|
-
# On return to the controller, you can test for new_registration? and registration_complete?
|
117
|
-
# to determine the most appropriate action
|
115
|
+
# Handles the special case of RPX being added to an existing account.
|
116
|
+
# At this point, a session has been established as a result of a "save" on the user model (which indirectly triggers user session validation).
|
117
|
+
# We do not directly add the RPX details to the user record here in order to avoid getting
|
118
|
+
# into a recursive dance between the session and user models.
|
119
|
+
# Rather, it uses the trick of adding the necessary RPX information to the session object,
|
120
|
+
# and the user model will pluck these values out before completing its validation step.
|
118
121
|
#
|
119
122
|
def add_rpx_identifier
|
120
|
-
data = RPXNow.user_data(controller.params[:token])
|
121
|
-
controller.session['
|
123
|
+
data = RPXNow.user_data(controller.params[:token], :extended=> rpx_extended_info? ) {|raw| raw }
|
124
|
+
controller.session['added_rpx_data'] = data if data
|
122
125
|
end
|
123
126
|
|
124
|
-
# the main RPX magic. At this
|
127
|
+
# the main RPX magic. At this point, a session is being validated and we know RPX identifier
|
125
128
|
# has been provided. We'll callback to RPX to verify the token, and authenticate the matching
|
126
129
|
# user.
|
127
130
|
# If no user is found, and we have auto_register enabled (default) this method will also
|
@@ -158,30 +161,50 @@ module AuthlogicRpx
|
|
158
161
|
errors.add_to_base("We did not find any accounts with that login. Enter your details and create an account.")
|
159
162
|
return false
|
160
163
|
end
|
164
|
+
else
|
165
|
+
map_rpx_data_each_login
|
161
166
|
end
|
162
167
|
|
163
|
-
rescue
|
164
|
-
errors.add_to_base("There was an error in authentication. Please try again or contact the system administrators for assistance")
|
165
|
-
return false
|
166
168
|
end
|
167
169
|
|
168
170
|
# map_rpx_data maps additional fields from the RPX response into the user object during auto-registration.
|
169
|
-
# Override this in your session
|
171
|
+
# Override this in your session model to change the field mapping
|
170
172
|
# See https://rpxnow.com/docs#profile_data for the definition of available attributes
|
171
173
|
#
|
172
|
-
#
|
174
|
+
# In this procedure, you will be writing to fields of the "self.attempted_record" object, pulling data from the @rpx_data object.
|
175
|
+
#
|
176
|
+
# WARNING: if you are using auto-registration, any fields you map should NOT have constraints enforced at the database level.
|
173
177
|
# authlogic_rpx will optimistically attempt to save the user record during registration, and
|
174
|
-
# violating a
|
178
|
+
# violating a database constraint will cause the authentication/registration to fail.
|
175
179
|
#
|
176
180
|
# You can/should enforce any required validations at the model level e.g.
|
177
181
|
# validates_uniqueness_of :username, :case_sensitive => false
|
178
182
|
# This will allow the auto-registration to proceed, and the user can be given a chance to rectify the validation errors
|
179
183
|
# on your user profile page.
|
180
184
|
#
|
185
|
+
# If it is not acceptable in your application to have user records created with potential validation errors in auto-populated fields, you
|
186
|
+
# will need to override map_rpx_data and implement whatever special handling makes sense in your case. For example:
|
187
|
+
# - directly check for uniqueness and other validation requirements
|
188
|
+
# - automatically "uniquify" fields like username
|
189
|
+
# - save conflicting profile information to "pending user review" columns or a seperate table
|
190
|
+
#
|
181
191
|
def map_rpx_data
|
182
192
|
self.attempted_record.send("#{klass.login_field}=", @rpx_data['profile']['preferredUsername'] ) if attempted_record.send(klass.login_field).blank?
|
183
193
|
self.attempted_record.send("#{klass.email_field}=", @rpx_data['profile']['email'] ) if attempted_record.send(klass.email_field).blank?
|
184
194
|
end
|
195
|
+
|
196
|
+
# map_rpx_data_each_login provides a hook to allow you to map RPX profile information every time the user
|
197
|
+
# logs in.
|
198
|
+
# By default, nothing is mapped.
|
199
|
+
#
|
200
|
+
# This would mainly be used to update relatively volatile information that you are maintaining in the user model (such as profile image url)
|
201
|
+
#
|
202
|
+
# In this procedure, you will be writing to fields of the "self.attempted_record" object, pulling data from the @rpx_data object.
|
203
|
+
#
|
204
|
+
#
|
205
|
+
def map_rpx_data_each_login
|
206
|
+
|
207
|
+
end
|
185
208
|
|
186
209
|
end
|
187
210
|
|
data/test/fixtures/users.yml
CHANGED
@@ -0,0 +1,5 @@
|
|
1
|
+
john:
|
2
|
+
persistence_token: 6cde0674657a8a313ce952df979de2830309aa4c11ca65805dd00bfdc65dbcc2f5e36718660a1d2e68c1a08c276d996763985d2f06fd3d076eb7bc4d97b1e317
|
3
|
+
single_access_token: <%= Authlogic::Random.friendly_token %>
|
4
|
+
perishable_token: <%= Authlogic::Random.friendly_token %>
|
5
|
+
rpx_identifier : johns_rpx_identifier
|
data/test/libs/user_session.rb
CHANGED
data/test/session_test.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
2
|
|
3
3
|
class SessionTest < ActiveSupport::TestCase
|
4
|
-
|
4
|
+
def test_authenticate_by_record
|
5
|
+
session = UserSession.new
|
6
|
+
assert session.respond_to?(:record)
|
7
|
+
session.record = users(:john)
|
8
|
+
assert_equal users(:john), session.record
|
9
|
+
end
|
5
10
|
end
|
data/test/test_helper.rb
CHANGED
@@ -2,9 +2,10 @@ require "test/unit"
|
|
2
2
|
require "rubygems"
|
3
3
|
require "ruby-debug"
|
4
4
|
require "active_record"
|
5
|
+
require "action_controller"
|
5
6
|
|
6
7
|
ActiveRecord::Schema.verbose = false
|
7
|
-
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :
|
8
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
8
9
|
ActiveRecord::Base.configurations = true
|
9
10
|
ActiveRecord::Schema.define(:version => 1) do
|
10
11
|
|
@@ -33,13 +34,21 @@ ActiveRecord::Schema.define(:version => 1) do
|
|
33
34
|
end
|
34
35
|
|
35
36
|
require "active_record/fixtures"
|
36
|
-
|
37
|
-
|
38
|
-
require
|
39
|
-
|
37
|
+
Rails = true
|
38
|
+
|
39
|
+
require "authlogic/test_case"
|
40
|
+
|
41
|
+
include Authlogic::TestCase
|
42
|
+
|
43
|
+
|
44
|
+
#require File.dirname(__FILE__) + "/../../authlogic/lib/authlogic"
|
45
|
+
#require File.dirname(__FILE__) + "/../../authlogic/lib/authlogic/test_case"
|
46
|
+
#require File.dirname(__FILE__) + "/libs/rails_trickery"
|
40
47
|
require File.dirname(__FILE__) + '/libs/user'
|
41
48
|
require File.dirname(__FILE__) + '/libs/user_session'
|
42
49
|
|
50
|
+
require File.dirname(__FILE__) + "./../rails/init.rb"
|
51
|
+
|
43
52
|
class ActiveSupport::TestCase
|
44
53
|
include ActiveRecord::TestFixtures
|
45
54
|
self.fixture_path = File.dirname(__FILE__) + "/fixtures"
|
@@ -57,5 +66,8 @@ class ActiveSupport::TestCase
|
|
57
66
|
def controller
|
58
67
|
@controller ||= Authlogic::TestCase::ControllerAdapter.new(ActionController.new)
|
59
68
|
end
|
60
|
-
|
69
|
+
|
70
|
+
def redirecting_to_rpx?
|
71
|
+
controller.redirecting_to.to_s =~ /^http:\/\/rpxnow.com/
|
72
|
+
end
|
61
73
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: authlogic_rpx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Gallagher / tardate
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-10-
|
12
|
+
date: 2009-10-15 00:00:00 +08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -23,14 +23,14 @@ dependencies:
|
|
23
23
|
version: 2.1.1
|
24
24
|
version:
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
|
-
name:
|
26
|
+
name: rpx_now
|
27
27
|
type: :runtime
|
28
28
|
version_requirement:
|
29
29
|
version_requirements: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 0.6.6
|
34
34
|
version:
|
35
35
|
description: Authlogic extension/plugin that provides RPX (rpxnow.com) authentication support
|
36
36
|
email: gallagher.paul@gmail.com
|
@@ -71,7 +71,7 @@ has_rdoc: true
|
|
71
71
|
homepage: http://github.com/tardate/authlogic_rpx
|
72
72
|
licenses: []
|
73
73
|
|
74
|
-
post_install_message:
|
74
|
+
post_install_message: ""
|
75
75
|
rdoc_options:
|
76
76
|
- --line-numbers
|
77
77
|
- --inline-source
|