authlogic_rpx 1.0.4 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. data/CHANGELOG.rdoc +10 -0
  2. data/Manifest +19 -2
  3. data/README.rdoc +284 -72
  4. data/Rakefile +30 -2
  5. data/authlogic_rpx.gemspec +11 -11
  6. data/generators/add_authlogic_rpx_migration/USAGE +18 -0
  7. data/generators/add_authlogic_rpx_migration/add_authlogic_rpx_migration_generator.rb +44 -0
  8. data/generators/add_authlogic_rpx_migration/templates/migration_internal_mapping.rb +34 -0
  9. data/generators/add_authlogic_rpx_migration/templates/migration_no_mapping.rb +29 -0
  10. data/lib/authlogic_rpx.rb +1 -0
  11. data/lib/authlogic_rpx/acts_as_authentic.rb +199 -32
  12. data/lib/authlogic_rpx/helper.rb +21 -13
  13. data/lib/authlogic_rpx/rpx_identifier.rb +5 -0
  14. data/lib/authlogic_rpx/session.rb +23 -16
  15. data/lib/authlogic_rpx/version.rb +2 -2
  16. data/test/fixtures/rpxresponses.yml +20 -0
  17. data/test/fixtures/users.yml +20 -5
  18. data/test/integration/basic_authentication_and_registration_test.rb +53 -0
  19. data/test/integration/internal_mapping/basic_authentication_and_registration_test.rb +3 -0
  20. data/test/integration/internal_mapping/settings_test.rb +10 -0
  21. data/test/integration/no_mapping/basic_authentication_and_registration_test.rb +3 -0
  22. data/test/integration/no_mapping/settings_test.rb +10 -0
  23. data/test/libs/ext_test_unit.rb +30 -0
  24. data/test/libs/mock_rpx_now.rb +34 -0
  25. data/test/libs/rails_trickery.rb +2 -2
  26. data/test/libs/rpxresponse.rb +3 -0
  27. data/test/libs/user_session.rb +1 -1
  28. data/test/test_helper.rb +35 -21
  29. data/test/test_internal_mapping_helper.rb +95 -0
  30. data/test/unit/acts_as_authentic_settings_test.rb +42 -0
  31. data/test/unit/session_settings_test.rb +38 -0
  32. data/test/unit/session_validation_test.rb +16 -0
  33. data/test/unit/verify_rpx_mock_test.rb +29 -0
  34. metadata +34 -8
  35. data/test/acts_as_authentic_test.rb +0 -5
  36. data/test/session_test.rb +0 -10
@@ -1,3 +1,13 @@
1
+ == 1.1.0 released 2010-01-05
2
+
3
+ * added identity mapping and merging support [GH#10,GH#13]
4
+ * new configuration parameters: account_mapping_mode; account_merge_enabled.
5
+ * new callbacks: before_merge_rpx_data; after_merge_rpx_data.
6
+ * updated gem support to authlogic 2.1.3 and rpx_now 0.6.11
7
+ * support all rpx_now options in popup/embed code [GH#6]
8
+ * automated tests are now working [GH#7]
9
+ * documentation updates
10
+
1
11
  == 1.0.4 released 2009-10-10
2
12
 
3
13
  * 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)
data/Manifest CHANGED
@@ -4,17 +4,34 @@ Manifest
4
4
  README.rdoc
5
5
  Rakefile
6
6
  authlogic_rpx.gemspec
7
+ generators/add_authlogic_rpx_migration/USAGE
8
+ generators/add_authlogic_rpx_migration/add_authlogic_rpx_migration_generator.rb
9
+ generators/add_authlogic_rpx_migration/templates/migration_internal_mapping.rb
10
+ generators/add_authlogic_rpx_migration/templates/migration_no_mapping.rb
7
11
  init.rb
8
12
  lib/authlogic_rpx.rb
9
13
  lib/authlogic_rpx/acts_as_authentic.rb
10
14
  lib/authlogic_rpx/helper.rb
15
+ lib/authlogic_rpx/rpx_identifier.rb
11
16
  lib/authlogic_rpx/session.rb
12
17
  lib/authlogic_rpx/version.rb
13
18
  rails/init.rb
14
- test/acts_as_authentic_test.rb
19
+ test/fixtures/rpxresponses.yml
15
20
  test/fixtures/users.yml
21
+ test/integration/basic_authentication_and_registration_test.rb
22
+ test/integration/internal_mapping/basic_authentication_and_registration_test.rb
23
+ test/integration/internal_mapping/settings_test.rb
24
+ test/integration/no_mapping/basic_authentication_and_registration_test.rb
25
+ test/integration/no_mapping/settings_test.rb
26
+ test/libs/ext_test_unit.rb
27
+ test/libs/mock_rpx_now.rb
16
28
  test/libs/rails_trickery.rb
29
+ test/libs/rpxresponse.rb
17
30
  test/libs/user.rb
18
31
  test/libs/user_session.rb
19
- test/session_test.rb
20
32
  test/test_helper.rb
33
+ test/test_internal_mapping_helper.rb
34
+ test/unit/acts_as_authentic_settings_test.rb
35
+ test/unit/session_settings_test.rb
36
+ test/unit/session_validation_test.rb
37
+ test/unit/verify_rpx_mock_test.rb
@@ -1,14 +1,15 @@
1
- = Authlogic RPX
1
+ = Authlogic_RPX
2
2
 
3
3
  == Purpose
4
4
 
5
- Authlogic RPX is an Authlogic extension library that provides support for authentication using the RPX multi-authentication service offered by JanRain. To use RPX, you must first register your application at {RPX}[http://rpxnow.com/]. A free "Basic" account is available, in addition to paid enhanced versions. All work with Authlogic_RPX.
5
+ Authlogic_RPX is an Authlogic extension library that provides support for authentication using the RPX multi-authentication service offered by JanRain. To use RPX, you must first register your application at {RPX}[http://rpxnow.com/]. A free "Basic" account is available, in addition to paid enhanced versions. All work with Authlogic_RPX.
6
6
 
7
7
  Key features and capabilities:
8
8
  * Auto-registration by default following RPX authentication (can be disabled if required)
9
9
  * Can allow users to enable RPX authentication for their existing password-enabled accounts
10
10
  * View helpers to assist with inserting login fragments in pages
11
11
  * Can co-exist with standard password authentication
12
+ * Supports identity mapping and merging (allowing users to have multiple logins associated with one member record on your site)
12
13
 
13
14
 
14
15
  == Authlogic_RPX References
@@ -29,14 +30,14 @@ The demonstration Rails application is where you can see Authlogic_RPX in action
29
30
  * <b>RPX_now gem repo:</b> [http://github.com/grosser/rpx_now]
30
31
 
31
32
 
32
- == Installing Authlogic RPX gem
33
+ == Installing Authlogic_RPX gem
33
34
 
34
- Three gems are required: authlogic, grosser-rpx_now, and authlogic_rpx. Install these as appropriate to your environment and preferences.
35
+ Three gems are required: authlogic, rpx_now, and authlogic_rpx. Install these as appropriate to your environment and preferences.
35
36
 
36
37
  Currently tested versions:
37
- * authlogic 2.1.2,2.1.1
38
- * rpx_now 0.6.6
39
- * authlogic_rpx 1.0.4
38
+ * authlogic 2.1.3,2.1.2,2.1.1
39
+ * rpx_now 0.6.11,0.6.6
40
+ * authlogic_rpx 1.1.0
40
41
 
41
42
 
42
43
  === 1. Direct gem installation
@@ -50,9 +51,9 @@ Currently tested versions:
50
51
 
51
52
  Include in config/environment.rb:
52
53
 
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'
54
+ config.gem 'authlogic', :version => '>= 2.1.3'
55
+ config.gem 'rpx_now', :version => '>= 0.6.11', :source => 'http://gemcutter.org'
56
+ config.gem 'authlogic_rpx', :version => '>= 1.1.0', :source => 'http://gemcutter.org'
56
57
 
57
58
  Then to install, run from the command line:
58
59
 
@@ -63,20 +64,69 @@ Then to install, run from the command line:
63
64
 
64
65
  Include in RAILS_ROOT/.gems:
65
66
 
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
67
+ authlogic --version '>= 2.1.3'
68
+ rpx_now --version '>= 0.6.11' --source gemcutter.org
69
+ authlogic_rpx --version '>= 1.1.0' --source gemcutter.org
69
70
 
70
71
 
71
- == Using Authlogic RPX
72
+ == About Authlogic_RPX
72
73
 
73
- <i>Note: in what follows, the user model is called User and the session controller takes the name UserSession (the authlogic convention). You are not restricted to these names - could be Member and MemberSession for example - but for simplicity, this documentation will stick to using the "User" convention.</i>
74
-
75
- Using Authlogic RPX is very similar to using standard authlogic, with the addition of just a few configuration options. So if you already have a project setup with authlogic, adding RPX support will be trivial.
74
+ Using Authlogic_RPX is very similar to using standard authlogic, with the addition of just a few configuration options. So if you already have a project setup with authlogic, adding RPX support will be trivial.
76
75
 
77
76
  An important capability to be aware of is "auto registration". This means that when a user has logged in with RPX, if an account does not already exist in your application, it will be automatically created. That is, there is no separate/special "register" step for users to go through before just signing in. You can disable this if you need, but for most sites that use RPX as a primary authentication mechanism, this is probably what you want to happen.
78
77
 
79
- The main steps for enabling Authlogic RPX:
78
+ One of the main limitations of Authlogic_RPX versions up to 1.0.4 was that it did not include any specific support for identity mapping. This means that if a user signs in with twitter one day, and facebook the next, then your application would see these as tow distinct users (NB: RPX provides some protection for this by trying to remember the last authentication method your users used. It's not always perfect however).
79
+
80
+ From Authlogic_RPX version 1.1.0 we have added built-in identity mapping and merging support. This is what we call 'internal' mapping. The legacy approach from 1.0.4 and earlier is still supported as an option. This mapping mode is called 'none'.
81
+
82
+ The JanRain RPXnow service has its own identity mapping implementation, but only available for paid accounts. This is still not supported directly by Authlogic_RPX, but is something we'd like to get into a future version.
83
+
84
+ === Chosing Your Mapping Mode
85
+
86
+ When you configure Authlogic_RPX, you will need to decide which mapping mode to use.
87
+
88
+ The options are:
89
+ * :none - will use legacy/1.0.4 identity management with no mapping support. RPX identifiers are stored as a new attribute of your User model
90
+ * :internal - uses Authlogic_RPX-based mapping. RPX identifiers are stored in a new model called RPXIdentifier. This model is completely private to Authlogic_RPX and you will not need to code anything specifically for it.
91
+ * :rpxnow - currently not implemented; reserved for future use
92
+
93
+
94
+ ==== Upgrading from Authlogic_RPX 1.0.4 or earlier
95
+
96
+ In Authlogic_RPX v1.0.4 and earlier, the rpx_identifier was stored in the user model, and identity mapping was not supported.
97
+
98
+ If you are upgrading to 1.1.0 or later and wish to start using internal mapping:
99
+ * Use the add_authlogic_rpx_migration generator to create the migration to support the new RPXIdentifiers model
100
+ * It is NOT necessary to migrate the rpx_identifiers.
101
+ * DO NOT remove the legacy rpx_identifier column from your existing user model. The Authlogic_RPX code will migrate users to the new database structure as and when they login.
102
+ * You may wish to explicitly set account_mapping_mode to :internal in the User model (it saves a few cycles over the default :auto).
103
+
104
+ e.g.
105
+
106
+ class User < ActiveRecord::Base
107
+ acts_as_authentic do |c|
108
+ c.account_mapping_mode :internal
109
+ end
110
+ end
111
+
112
+ If you are upgrading to 1.1.0 or later and wish to continue using the legacy/1.0.4 approach (i.e. no mapping):
113
+ * You will already have the rpx_identifier in your user model. DO NOT create any new migrations.
114
+ * Just upgrade the gem and all should continue to work as before
115
+ * You may wish to explicitly set account_mapping_mode to :none in the User model (it saves a few cycles over the default :auto).
116
+
117
+ e.g.
118
+
119
+ class User < ActiveRecord::Base
120
+ acts_as_authentic do |c|
121
+ c.account_mapping_mode :none
122
+ end
123
+ end
124
+
125
+ == The Step-by-Step Guide to Using Authlogic_RPX
126
+
127
+ <i>Note: in what follows, the user model is called User and the session controller takes the name UserSession (the authlogic convention). You are not restricted to these names - could be Member and MemberSession for example - but for simplicity, this documentation will stick to using the "User" convention.</i>
128
+
129
+ The main steps for enabling Authlogic_RPX:
80
130
  * 1. Enable RPX for your user model
81
131
  * 2. Add RPX configuration for the Authlogic session model
82
132
  * 3. Add custom user profile mapping (optional)
@@ -85,46 +135,153 @@ The main steps for enabling Authlogic RPX:
85
135
  * 6. Setup the Authlogic user controller
86
136
  * 7. Use view helpers to provide login links
87
137
  * 8. Allow users to "Add RPX" to existing accounts (optional)
138
+ * 9. Customise Account Merge Behaviour (optional)
88
139
 
89
140
 
90
141
  === 1. Enable RPX for your user model
91
142
 
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).
143
+ The user model will have a has_many relationship with a new model, called RPXIdentifier.
144
+ A generator is provider to create the necessary migration:
94
145
 
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")
146
+ ruby script/generate add_authlogic_rpx_migration [mapping:mapping_mode] [user_model:model_name]
147
+
148
+ The generator takes two optional parameters: mapping and user_model.
96
149
 
97
- class AddUsersRpxIdentifier < ActiveRecord::Migration
98
- def self.up
99
- add_column :users, :rpx_identifier, :string
100
- add_index :users, :rpx_identifier
150
+ The mapping_mode parameter indicates which style of Authlogic_RPX-supported identity mapping should be used. The default mapping_mode is 'internal' Allowed values for mapping_mode are:
151
+ * none (disables authlogic_rpx identity mapping. This is the same behaviour as in authlogic_rpx version 1.0.4 and earlier)
152
+ * internal (enables authlogic_rpx internal identity mapping. This behaviour was introduced in version 1.1.0)
153
+
154
+ The user_model parameter specifies the name of the user/member model in your application. The default model_name is 'User'. e.g. to generate the RPX migration where the user model is called 'Member' and you do not want to support identity mapping:
155
+
156
+ ruby script/generate add_authlogic_rpx_migration mapping:none user_model:member
157
+
158
+ You may need to customise the migration file to remove database constraints on other fields if they will be unused in the RPX case
159
+ (e.g. crypted_password and password_salt to make password authentication optional).
101
160
 
102
- change_column :users, :crypted_password, :string, :default => nil, :null => true
103
- change_column :users, :password_salt, :string, :default => nil, :null => true
161
+ If you are using auto-registration, you must also remove any database constraints for fields that will be automatically mapped
162
+ (see notes in "3. Add custom user profile mapping during auto-registration")
163
+
164
+ ==== Sample Migration Generated Script (using internal mapping)
165
+
166
+ The following command will generate a migration for the case where you want to use authlogic_rpx internal mapping and your user model is called 'User':
167
+
168
+ ruby script/generate add_authlogic_rpx_migration mapping:internal user_model:user
169
+
170
+ The migration script will appear like this:
171
+
172
+ class AddAuthlogicRpxMigration < ActiveRecord::Migration
173
+ def self.up
174
+ create_table :rpx_identifiers do |t|
175
+ t.string :identifier, :null => false
176
+ t.string :provider_name
177
+ t.integer :user_id, :null => false
178
+ t.timestamps
179
+ end
180
+ add_index :rpx_identifiers, :identifier, :unique => true, :null => false
181
+ add_index :rpx_identifiers, :user_id, :unique => false, :null => false
182
+
183
+ # == Customisation may be required here ==
184
+ # You may need to remove database constraints on other fields if they will be unused in the RPX case
185
+ # (e.g. crypted_password and password_salt to make password authentication optional).
186
+ # If you are using auto-registration, you must also remove any database constraints for fields that will be automatically mapped
187
+ # e.g.:
188
+ #change_column :users, :crypted_password, :string, :default => nil, :null => true
189
+ #change_column :users, :password_salt, :string, :default => nil, :null => true
104
190
 
105
191
  end
106
-
192
+
107
193
  def self.down
108
- remove_column :users, :openid_identifier
194
+ drop_table :rpx_identifiers
195
+
196
+ # == Customisation may be required here ==
197
+ # Restore user model database constraints as appropriate
198
+ # e.g.:
199
+ #[:crypted_password, :password_salt].each do |field|
200
+ # User.all(:conditions => "#{field} is NULL").each { |user| user.update_attribute(field, "") if user.send(field).nil? }
201
+ # change_column :users, field, :string, :default => "", :null => false
202
+ #end
203
+
204
+ end
205
+ end
109
206
 
110
- [:crypted_password, :password_salt].each do |field|
111
- User.all(:conditions => "#{field} is NULL").each { |user| user.update_attribute(field, "") if user.send(field).nil? }
112
- change_column :users, field, :string, :default => "", :null => false
113
- end
207
+ {See the source for the sample 20091227051253_add_authlogic_rpx_migration.rb}[http://github.com/tardate/rails-authlogic-rpx-sample/blob/master/db/migrate/20091227051253_add_authlogic_rpx_migration.rb].
208
+
209
+ ==== Sample Migration Generated Script (using no mapping)
210
+
211
+ The following command will generate a migration for the case where you don't want to use authlogic_rpx mapping and your user model is called 'Member':
212
+
213
+ ruby script/generate add_authlogic_rpx_migration mapping:none user_model:member
214
+
215
+ The migration script will appear like this:
216
+
217
+ class AddAuthlogicRpxMigration < ActiveRecord::Migration
218
+
219
+ def self.up
220
+ add_column :members, :rpx_identifier, :string
221
+ add_index :members, :rpx_identifier
222
+
223
+ # == Customisation may be required here ==
224
+ # You may need to remove database constraints on other fields if they will be unused in the RPX case
225
+ # (e.g. crypted_password and password_salt to make password authentication optional).
226
+ # If you are using auto-registration, you must also remove any database constraints for fields that will be automatically mapped
227
+
228
+ # e.g.:
229
+ #change_column :members, :crypted_password, :string, :default => nil, :null => true
230
+ #change_column :members, :password_salt, :string, :default => nil, :null => true
231
+
114
232
  end
233
+
234
+ def self.down
235
+ remove_column :members, :rpx_identifier
236
+
237
+ # == Customisation may be required here ==
238
+ # Restore user model database constraints as appropriate
239
+ # e.g.:
240
+ #[:crypted_password, :password_salt].each do |field|
241
+ # Member.all(:conditions => "#{field} is NULL").each { |user| user.update_attribute(field, "") if user.send(field).nil? }
242
+ # change_column :members, field, :string, :default => "", :null => false
243
+ #end
244
+
245
+ end
246
+ end
247
+
248
+ ==== Configuring the User model
249
+
250
+ The user model then needs to be tagged with "acts_as_authentic". This is the minimal configuration:
251
+
252
+ class User < ActiveRecord::Base
253
+ acts_as_authentic
115
254
  end
116
255
 
117
- The user model then needs to be tagged with "acts_as_authentic", and you must add rpx_identifier to the attr_accessible configuration (if you are using it)
256
+ Two RPX-specific user configuration options are available.
257
+ * account_merge_enabled: true/false. Enables/disables user auto-registration (disabled by default)
258
+ * account_mapping_mode: :auto/:none/:internal. Sets the Authlogic_RPX identity mapping mode (:auto by default)
259
+
260
+ The account_mapping_mode options are defined as follows:
261
+ * :auto - will select the correct mapping mode based on the table structures you have provisioned in the application
262
+ * :none - will use legacy/1.0.4 identity management with no mapping support. RPX identifiers are stored as a new attribute of your User model
263
+ * :internal - uses Authlogic_RPX-based mapping. RPX identifiers are stored in a new model called RPXIdentifier. This model is completely private to Authlogic_RPX and you will not need to code anything specifically for it.
264
+ * :rpxnow - currently not implemented; reserved for future use.
265
+
266
+ For example, the following shows how to set standard Authlogic configurations (validations_scope), enables RPX account merging, and specifies :internal account mapping:
118
267
 
119
268
  class User < ActiveRecord::Base
120
269
  acts_as_authentic do |c|
121
- c.my_config_option = my_value # for available options see documentation in: Authlogic::ActsAsAuthentic
270
+ c.validations_scope = :company_id # for available Authlogic options see documentation in the various Config modules of Authlogic::ActsAsAuthentic
271
+
272
+ # enable Authlogic_RPX account merging (false by default, if this statement is not present)
273
+ c.account_merge_enabled true
274
+
275
+ # set Authlogic_RPX account mapping mode
276
+ c.account_mapping_mode :internal
277
+
122
278
  end # block optional
123
- attr_accessible :username, :email, :password, :password_confirmation, :rpx_identifier
279
+
124
280
  end
125
281
 
126
282
  {See the source for the sample user.rb}[http://github.com/tardate/rails-authlogic-rpx-sample/blob/master/app/models/user.rb].
127
283
 
284
+ NB: The RPXIdentifier model is included in the authlogic_rpx gem and does not need to be added to your project.
128
285
 
129
286
  === 2. Add RPX configuration for the Authlogic session model
130
287
 
@@ -168,7 +325,7 @@ Authlogic_rpx provides three hooks for mapping information from the RPX profile
168
325
 
169
326
  See https://rpxnow.com/docs#profile_data for the definition of available attributes in the RPX profile.
170
327
 
171
- === 3a. map_rpx_data: user profile mapping during auto-registration
328
+ ==== 3a. map_rpx_data: user profile mapping during auto-registration
172
329
 
173
330
  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.
174
331
 
@@ -193,13 +350,12 @@ If you have other fields you want to map, you can provide your own implementatio
193
350
  self.attempted_record.fullname = @rpx_data['profile']['displayName'] if attempted_record.fullname.blank?
194
351
 
195
352
  if rpx_extended_info?
196
- # map some extended attributes
353
+ # map some extended attributes
197
354
  end
198
355
  end
199
356
 
200
357
  end
201
358
 
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
359
 
204
360
  WARNING: if you are using auto-registration, any fields you map should NOT have constraints enforced at the database level.
205
361
  Authlogic_rpx will optimistically attempt to save the user record during registration, and violating a database constraint will cause the authentication/registration to fail.
@@ -216,6 +372,7 @@ If it is not acceptable in your application to have user records created with po
216
372
  * automatically "uniquify" certain fields like username
217
373
  * save conflicting profile information to "pending user review" columns or a seperate table
218
374
 
375
+ {See the source for the sample user_session.rb}[http://github.com/tardate/rails-authlogic-rpx-sample/blob/master/app/models/user_session.rb].
219
376
 
220
377
  ==== 3b. map_rpx_data_each_login: user profile mapping during login
221
378
 
@@ -227,10 +384,10 @@ This would mainly be used to update relatively volatile information that you are
227
384
 
228
385
  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
386
 
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
387
+ def map_rpx_data_each_login
388
+ # we'll always update photo_url
389
+ self.attempted_record.photo_url = @rpx_data['profile']['photo']
390
+ end
234
391
 
235
392
  {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
393
 
@@ -239,15 +396,12 @@ In the map_rpx_data_each_login procedure, you will be writing to fields of the "
239
396
 
240
397
  map_added_rpx_data maps additional fields from the RPX response into the user object during the "add RPX to existing account" process.
241
398
 
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.
399
+ Override this in your user model to perform field mapping as may be desired.
400
+ 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).
245
401
 
246
402
  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
403
 
248
404
  def map_added_rpx_data( rpx_data )
249
- self.rpx_identifier = rpx_data['profile']['identifier']
250
-
251
405
  # map some additional fields, e.g. photo_url
252
406
  self.photo_url = rpx_data['profile']['photo'] if photo_url.blank?
253
407
  end
@@ -430,15 +584,15 @@ Each takes an options hash:
430
584
 
431
585
  For example, to insert a login link in a navigation bar is as simple as this:
432
586
 
433
- &lt;div id="user_nav"&gt;
434
- &lt;%= link_to "Home", root_path %&gt; |
435
- &lt;% if current_user %&gt;
436
- &lt;%= link_to "Profile", user_path(:current) %&gt; |
437
- &lt;%= link_to "Sign out", signout_path %&gt;
438
- &lt;% else %&gt;
439
- &lt;%= rpx_popup( :link_text => "Register/Sign in with RPX..", :app_name => "rails-authlogic-rpx-sample", :return_url => user_sessions_url, :unobtrusive => false ) %>&gt;
440
- &lt;% end %&gt;
441
- &lt;/div&gt;
587
+ <div id="user_nav">
588
+ <%= link_to "Home", root_path %> |
589
+ <% if current_user %>
590
+ <%= link_to "Profile", user_path(:current) %> |
591
+ <%= link_to "Sign out", signout_path %>
592
+ <% else %>
593
+ <%= rpx_popup( :link_text => "Register/Sign in with RPX..", :app_name => "rails-authlogic-rpx-sample", :return_url => user_sessions_url, :unobtrusive => false ) %>>
594
+ <% end %>
595
+ </div>
442
596
 
443
597
  === 8. Allow users to "Add RPX" to existing accounts (optional)
444
598
 
@@ -448,18 +602,18 @@ However, if you support other authentication methods (e.g. by password), you pro
448
602
 
449
603
  The route may be called anything you like. Let's use "addrpxauth" for example.
450
604
 
451
- # This action has the special purpose of receiving an update of the RPX identity information
452
- # for current user - to add RPX authentication to an existing non-RPX account.
453
- # RPX only supports :post, so this cannot simply go to update method (:put)
454
- def addrpxauth
455
- @user = current_user
456
- if @user.save
457
- flash[:notice] = "Successfully added RPX authentication for this account."
458
- render :action => 'show'
459
- else
460
- render :action => 'edit'
461
- end
462
- end
605
+ # This action has the special purpose of receiving an update of the RPX identity information
606
+ # for current user - to add RPX authentication to an existing non-RPX account.
607
+ # RPX only supports :post, so this cannot simply go to update method (:put)
608
+ def addrpxauth
609
+ @user = current_user
610
+ if @user.save
611
+ flash[:notice] = "Successfully added RPX authentication for this account."
612
+ render :action => 'show'
613
+ else
614
+ render :action => 'edit'
615
+ end
616
+ end
463
617
 
464
618
  {This is demonstrated in the sample users_controller.rb}[http://github.com/tardate/rails-authlogic-rpx-sample/blob/master/app/controllers/users_controller.rb].
465
619
 
@@ -469,10 +623,66 @@ You'll note this is almost identical to the "update". The main difference is tha
469
623
 
470
624
  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
625
 
472
- &lt;%= rpx_popup( :link_text =&gt; "Add RPX authentication for this account..", :app_name =&gt; RPX_APP_NAME, :return_url =&gt; addrpxauth_url, :add_rpx =&gt; true, :unobtrusive =&gt; false ) %&gt;
626
+ <%= rpx_popup( :link_text => "Add RPX authentication for this account..", :app_name => RPX_APP_NAME, :return_url => addrpxauth_url, :add_rpx => true, :unobtrusive => false ) %>
627
+
628
+
629
+ === 9. Customise Account Merge Behaviour (optional)
630
+
631
+ Account merging is disabled by default. It is enabled by setting account_merge_enabled to true in the User model:
473
632
 
633
+ class User < ActiveRecord::Base
634
+ acts_as_authentic do |c|
635
+ c.account_merge_enabled true
636
+ end
637
+ end
638
+
639
+
640
+ Account merging is applicable if you have allowed users to add RPX to an existing accounts (see 8. Allow users to "Add RPX" to existing accounts). When merging is enabled, Authlogic_RPX will migrate the RPX login identifier(s) from other users who had previously claimed the identifiers now being used.
641
+
642
+ For example, take the following scenario:
643
+ * Joe registers and creates an account using RPX identifier A (say, a twitter account)
644
+ * Joseph registers and creates an account using RPX identifier B (say, an OpenID account)
645
+ * It so happens that Joe and Joseph are the same person...
646
+ * Joseph signs in with RPX identifier B, and uses the "Add RPX" feature to attempt to add RPX identifier A to his account
647
+ * At this point, if you have account_merge_enabled disabled (the default), it will fail since the id is already used by Joe
648
+ * If you have account_merge_enabled enabled, Authlogic_RPX will transfer the RPX identifier A to Joseph's account
649
+ * If you are using account mapping = :none, RPX identifier A will just replace RPX identifier B for Joseph
650
+ * If you are using account mapping = :internal, RPX identifier A will be added to Joseph's account (he can now login with both A and B)
651
+ * The default behaviour of account mapping will leave Joe's account in place (but with no way to login via RPX). Authlogic_RPX does not merge any other details (e.g. application data ownership)
652
+
653
+ Authlogic_rpx provides two hooks for customising the account merge behaviour to handle things like migration of application objects and cleaning up old accounts:
654
+
655
+ * before_merge_rpx_data: called before the RPX identifiers are transfered. It provides a hook for application developers to perform data migration prior to the merging of user accounts.
656
+ * after_merge_rpx_data: called after the RPX identifiers are transfered. It provides a hook for application developers to perform account clean-up after (perhaps delete or disable to account merged from)
474
657
 
475
- === 9. There is no 9
658
+
659
+ The Authlogic_RPX sample application provides an example of migrating application objects and cleaning up obsolete accounts. From the user model:
660
+
661
+ # before_merge_rpx_data provides a hook for application developers to perform data migration prior to the merging of user accounts.
662
+ # This method is called just before authlogic_rpx merges the user registration for 'from_user' into 'to_user'
663
+ # Authlogic_RPX is responsible for merging registration data.
664
+ #
665
+ # By default, it does not merge any other details (e.g. application data ownership)
666
+ #
667
+ def before_merge_rpx_data( from_user, to_user )
668
+ RAILS_DEFAULT_LOGGER.info "in before_merge_rpx_data: migrate articles and comments from #{from_user.username} to #{to_user.username}"
669
+ to_user.articles << from_user.articles
670
+ to_user.comments << from_user.comments
671
+ end
672
+
673
+ # after_merge_rpx_data provides a hook for application developers to perform account clean-up after authlogic_rpx has
674
+ # migrated registration details.
675
+ #
676
+ # By default, does nothing. It could, for example, be used to delete or disable the 'from_user' account
677
+ #
678
+ def after_merge_rpx_data( from_user, to_user )
679
+ RAILS_DEFAULT_LOGGER.info "in after_merge_rpx_data: destroy #{from_user.inspect}"
680
+ from_user.destroy
681
+ end
682
+
683
+ {See the sample user.rb}[http://github.com/tardate/rails-authlogic-rpx-sample/blob/master/app/models/user.rb].
684
+
685
+ === Ready to try it?
476
686
 
477
687
  That's all there is. To see Authlogic_RPX in action, check out the demonstration Rails application:
478
688
  * <b>Live Demonstration Site:</b> [http://rails-authlogic-rpx-sample.heroku.com]
@@ -486,7 +696,6 @@ Authlogic_RPX is open source and hosted on {github}[http://github.com/tardate/au
486
696
  If you have issues or feedback, please log them in the {issues list on github}[http://github.com/tardate/authlogic_rpx/issues]
487
697
 
488
698
  Some of the improvements currently on the radar:
489
- * Still figuring out how to write some good automated tests
490
699
  * Implement/verify support for RPX "paid" service features of their "Plus" and "Pro" accounts (to date, only tested with free RPX "Basic" account)
491
700
 
492
701
 
@@ -514,6 +723,8 @@ Some design principles:
514
723
  * update gem version refs in README.rdoc
515
724
  * update CHANGELOG.rdoc
516
725
 
726
+ Build and distribute (the gemcutter way):
727
+
517
728
  # update manifest file
518
729
  $ rake manifest
519
730
  # update gemspec
@@ -533,3 +744,4 @@ The idea of adding RPX support to authlogic is not new. Some early ideas were fo
533
744
  * <b>http://github.com/gampleman/authlogic_rpx/</b> similar, but including an implementation of the RPX api
534
745
 
535
746
  authlogic_rpx was created by Paul Gallagher (tardate.com) and released under the MIT license.
747
+ Big thanks for contributions from {John}[http://gitub.com/jjb] and {Damir}[http://gitub.com/sidonath]