sidonath-authlogic_rpx 1.0.4b → 1.0.4em
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest +4 -1
- data/README.rdoc +57 -42
- data/lib/authlogic_rpx.rb +1 -0
- data/lib/authlogic_rpx/acts_as_authentic.rb +79 -8
- data/lib/authlogic_rpx/session.rb +2 -1
- data/lib/authlogic_rpx/version.rb +2 -2
- data/sidonath-authlogic_rpx.gemspec +1 -1
- metadata +1 -1
data/Manifest
CHANGED
@@ -3,11 +3,14 @@ MIT-LICENSE
|
|
3
3
|
Manifest
|
4
4
|
README.rdoc
|
5
5
|
Rakefile
|
6
|
-
|
6
|
+
generators/add_authlogic_rpx_migration/USAGE
|
7
|
+
generators/add_authlogic_rpx_migration/add_authlogic_rpx_migration_generator.rb
|
8
|
+
generators/add_authlogic_rpx_migration/templates/migration.rb
|
7
9
|
init.rb
|
8
10
|
lib/authlogic_rpx.rb
|
9
11
|
lib/authlogic_rpx/acts_as_authentic.rb
|
10
12
|
lib/authlogic_rpx/helper.rb
|
13
|
+
lib/authlogic_rpx/rpx_identifier.rb
|
11
14
|
lib/authlogic_rpx/session.rb
|
12
15
|
lib/authlogic_rpx/version.rb
|
13
16
|
rails/init.rb
|
data/README.rdoc
CHANGED
@@ -34,9 +34,9 @@ The demonstration Rails application is where you can see Authlogic_RPX in action
|
|
34
34
|
Three gems are required: authlogic, grosser-rpx_now, and authlogic_rpx. Install these as appropriate to your environment and preferences.
|
35
35
|
|
36
36
|
Currently tested versions:
|
37
|
-
* authlogic 2.1.2,2.1.1
|
38
|
-
* rpx_now 0.6.6
|
39
|
-
* authlogic_rpx 1.0
|
37
|
+
* authlogic 2.1.3,2.1.2,2.1.1
|
38
|
+
* rpx_now 0.6.11,0.6.6
|
39
|
+
* authlogic_rpx 1.1.0
|
40
40
|
|
41
41
|
|
42
42
|
=== 1. Direct gem installation
|
@@ -50,9 +50,9 @@ Currently tested versions:
|
|
50
50
|
|
51
51
|
Include in config/environment.rb:
|
52
52
|
|
53
|
-
config.gem 'authlogic', :version => '>= 2.1.
|
54
|
-
config.gem 'rpx_now', :version => '>= 0.6.
|
55
|
-
config.gem 'authlogic_rpx', :version => '>= 1.0
|
53
|
+
config.gem 'authlogic', :version => '>= 2.1.3'
|
54
|
+
config.gem 'rpx_now', :version => '>= 0.6.11', :source => 'http://gemcutter.org'
|
55
|
+
config.gem 'authlogic_rpx', :version => '>= 1.1.0', :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 --version '>= 2.1.
|
67
|
-
rpx_now --version '>= 0.6.
|
68
|
-
authlogic_rpx --version '>= 1.0
|
66
|
+
authlogic --version '>= 2.1.3'
|
67
|
+
rpx_now --version '>= 0.6.11' --source gemcutter.org
|
68
|
+
authlogic_rpx --version '>= 1.1.0' --source gemcutter.org
|
69
69
|
|
70
70
|
|
71
71
|
== Using Authlogic RPX
|
@@ -89,47 +89,52 @@ The main steps for enabling Authlogic RPX:
|
|
89
89
|
|
90
90
|
=== 1. Enable RPX for your user model
|
91
91
|
|
92
|
-
The user model will have a has_many relationship with a new model, called RPXIdentifier.
|
92
|
+
The user model will have a has_many relationship with a new model, called RPXIdentifier.
|
93
|
+
A generator is provider to create the necessary migration:
|
93
94
|
|
94
|
-
|
95
|
+
ruby script/generate add_authlogic_rpx_migration
|
96
|
+
|
97
|
+
You may need to customise the migration file to remove database constraints on other fields if they will be unused in the RPX case
|
98
|
+
(e.g. crypted_password and password_salt to make password authentication optional).
|
95
99
|
|
96
|
-
If you are using auto-registration, you must also remove any database constraints for fields that will be automatically mapped
|
100
|
+
If you are using auto-registration, you must also remove any database constraints for fields that will be automatically mapped
|
101
|
+
(see notes in "3. Add custom user profile mapping during auto-registration")
|
97
102
|
|
98
|
-
class
|
103
|
+
class AddAuthlogicRpxMigration < ActiveRecord::Migration
|
99
104
|
def self.up
|
100
105
|
create_table :rpx_identifiers do |t|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
t.index :identifier, :user_id
|
105
|
-
t.index :user_id, :identifier
|
106
|
-
|
107
|
-
t.timestamps
|
108
|
-
end
|
109
|
-
|
110
|
-
[:crypted_password, :password_salt].each do |field|
|
111
|
-
change_column :users, field, :string, :default => nil, :null => true
|
106
|
+
t.string :identifier
|
107
|
+
t.integer :user_id
|
108
|
+
t.timestamps
|
112
109
|
end
|
110
|
+
add_index :rpx_identifiers, :identifier, :unique => true, :null => false
|
111
|
+
add_index :rpx_identifiers, :user_id, :unique => false, :null => false
|
112
|
+
|
113
|
+
# == Customisation may be required here ==
|
114
|
+
# You may need to remove database constraints on other fields if they will be unused in the RPX case
|
115
|
+
# (e.g. crypted_password and password_salt to make password authentication optional).
|
116
|
+
# If you are using auto-registration, you must also remove any database constraints for fields that will be automatically mapped
|
117
|
+
# e.g.:
|
118
|
+
#change_column :users, :crypted_password, :string, :default => nil, :null => true
|
119
|
+
#change_column :users, :password_salt, :string, :default => nil, :null => true
|
120
|
+
|
113
121
|
end
|
114
|
-
|
122
|
+
|
115
123
|
def self.down
|
116
124
|
drop_table :rpx_identifiers
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
125
|
+
|
126
|
+
# == Customisation may be required here ==
|
127
|
+
# Restore user model database constraints as appropriate
|
128
|
+
# e.g.:
|
129
|
+
#[:crypted_password, :password_salt].each do |field|
|
130
|
+
# User.all(:conditions => "#{field} is NULL").each { |user| user.update_attribute(field, "") if user.send(field).nil? }
|
131
|
+
# change_column :users, field, :string, :default => "", :null => false
|
132
|
+
#end
|
133
|
+
|
122
134
|
end
|
123
135
|
end
|
124
136
|
|
125
|
-
The RPXIdentifier model
|
126
|
-
|
127
|
-
class RPXIdentifier < ActiveRecord::Base
|
128
|
-
belongs_to :user
|
129
|
-
validates_presence_of :identifier
|
130
|
-
validates_presence_of :user_id
|
131
|
-
end
|
132
|
-
|
137
|
+
NB: The RPXIdentifier model is included in the authlogic_rpx gem and does not need to be added to your project.
|
133
138
|
|
134
139
|
The user model then needs to be tagged with "acts_as_authentic". authlogic_rpx automatically adds to the user model the relationship with RPXIdentifiers.
|
135
140
|
|
@@ -137,6 +142,9 @@ The user model then needs to be tagged with "acts_as_authentic". authlogic_rpx a
|
|
137
142
|
acts_as_authentic do |c|
|
138
143
|
c.my_config_option = my_value # for available options see documentation in: Authlogic::ActsAsAuthentic
|
139
144
|
end # block optional
|
145
|
+
|
146
|
+
# enable Authlogic_RPX account merging (false by default, if this statement is not present)
|
147
|
+
account_merge_enabled true
|
140
148
|
|
141
149
|
# not needed -- this relationship is automatically added by authlogic_rpx
|
142
150
|
# has_many :rpx_identifiers, :class_name => 'RPXIdentifier'
|
@@ -177,6 +185,15 @@ For example, to disable auto-registration and enable extended info:
|
|
177
185
|
|
178
186
|
{See the source for the sample user_session.rb}[http://github.com/tardate/rails-authlogic-rpx-sample/blob/master/app/models/user_session.rb].
|
179
187
|
|
188
|
+
==== Upgrading from Authlogic_RPX v1.0.4 or earlier
|
189
|
+
|
190
|
+
In Authlogic_RPX v1.0.4 and earlier, the rpx_identifier was stored in the user model.
|
191
|
+
From 1.1.0, this has been extracted to a separate table (rpx_identifiers).
|
192
|
+
|
193
|
+
When upgrading an application using 1.0.4 or earlier to 1.1.0, it is NOT necessary to migrate the rpx_identifiers.
|
194
|
+
Also DO NOT remove the legacy rpx_identifier column from your existing user model.
|
195
|
+
The Authlogic_RPX code will migrate users to the new database structure as and when they login.
|
196
|
+
|
180
197
|
=== 3. Add custom user profile mapping (optional)
|
181
198
|
|
182
199
|
Authlogic_rpx provides three hooks for mapping information from the RPX profile into your application's user model:
|
@@ -258,14 +275,12 @@ In the map_rpx_data_each_login procedure, you will be writing to fields of the "
|
|
258
275
|
|
259
276
|
map_added_rpx_data maps additional fields from the RPX response into the user object during the "add RPX to existing account" process.
|
260
277
|
|
261
|
-
|
262
|
-
|
263
|
-
NB: If you override this method, you will be responsible for also mapping the rpx_identifier.
|
278
|
+
Override this in your user model to perform field mapping as may be desired.
|
279
|
+
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).
|
264
280
|
|
265
281
|
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:
|
266
282
|
|
267
283
|
def map_added_rpx_data( rpx_data )
|
268
|
-
self.rpx_identifiers.create( :identifier => rpx_data['profile']['identifier'] )
|
269
284
|
|
270
285
|
# map some additional fields, e.g. photo_url
|
271
286
|
self.photo_url = rpx_data['profile']['photo'] if photo_url.blank?
|
data/lib/authlogic_rpx.rb
CHANGED
@@ -2,6 +2,7 @@ require "authlogic_rpx/version"
|
|
2
2
|
require "authlogic_rpx/acts_as_authentic"
|
3
3
|
require "authlogic_rpx/session"
|
4
4
|
require "authlogic_rpx/helper"
|
5
|
+
require "authlogic_rpx/rpx_identifier"
|
5
6
|
|
6
7
|
ActiveRecord::Base.send(:include, AuthlogicRpx::ActsAsAuthentic)
|
7
8
|
Authlogic::Session::Base.send(:include, AuthlogicRpx::Session)
|
@@ -24,13 +24,39 @@ module AuthlogicRpx
|
|
24
24
|
rw_config(:map_id, value, false)
|
25
25
|
end
|
26
26
|
alias_method :map_id=, :map_id
|
27
|
+
|
28
|
+
# account_merge_enabled is used to enable merging of accounts.
|
29
|
+
#
|
30
|
+
# * <tt>Default:</tt> false
|
31
|
+
# * <tt>Accepts:</tt> boolean
|
32
|
+
def account_merge_enabled(value=false)
|
33
|
+
account_merge_enabled_value(value)
|
34
|
+
end
|
35
|
+
def account_merge_enabled_value(value=nil)
|
36
|
+
rw_config(:account_merge_enabled,value,false)
|
37
|
+
end
|
38
|
+
alias_method :account_merge_enabled=,:account_merge_enabled
|
39
|
+
|
27
40
|
|
41
|
+
|
28
42
|
# Name of this method is defined in find_by_rpx_identifier_method
|
29
43
|
# method in session.rb
|
30
44
|
def find_by_rpx_identifier(id)
|
31
45
|
identifier = RPXIdentifier.find_by_identifier(id)
|
32
|
-
|
33
|
-
|
46
|
+
if identifier.nil?
|
47
|
+
if self.column_names.include? 'rpx_identifier'
|
48
|
+
# check for authentication using <=1.0.4, migrate identifier to rpx_identifiers table
|
49
|
+
user = self.find( :first, :conditions => [ "rpx_identifier = ?", id ] )
|
50
|
+
unless user.nil?
|
51
|
+
user.rpx_identifiers.create( :identifier => id )
|
52
|
+
end
|
53
|
+
return user
|
54
|
+
else
|
55
|
+
return nil
|
56
|
+
end
|
57
|
+
else
|
58
|
+
identifier.user
|
59
|
+
end
|
34
60
|
end
|
35
61
|
|
36
62
|
end
|
@@ -40,7 +66,7 @@ module AuthlogicRpx
|
|
40
66
|
# Set up some simple validations
|
41
67
|
def self.included(klass)
|
42
68
|
klass.class_eval do
|
43
|
-
has_many :rpx_identifiers, :class_name => 'RPXIdentifier'
|
69
|
+
has_many :rpx_identifiers, :class_name => 'RPXIdentifier', :dependent => :destroy
|
44
70
|
|
45
71
|
validates_length_of_password_field_options validates_length_of_password_field_options.merge(:if => :validate_password_with_rpx?)
|
46
72
|
validates_confirmation_of_password_field_options validates_confirmation_of_password_field_options.merge(:if => :validate_password_with_rpx?)
|
@@ -49,6 +75,10 @@ module AuthlogicRpx
|
|
49
75
|
after_create :map_rpx_identifier
|
50
76
|
attr_writer :creating_new_record_from_rpx
|
51
77
|
end
|
78
|
+
|
79
|
+
RPXIdentifier.class_eval do
|
80
|
+
belongs_to klass.name.downcase.to_sym
|
81
|
+
end
|
52
82
|
end
|
53
83
|
|
54
84
|
# support a block given to the save
|
@@ -88,24 +118,65 @@ module AuthlogicRpx
|
|
88
118
|
#
|
89
119
|
def adding_rpx_identifier
|
90
120
|
return true unless session_class && session_class.controller
|
91
|
-
added_rpx_data = session_class.controller.session['added_rpx_data']
|
121
|
+
added_rpx_data = session_class.controller.session['added_rpx_data']
|
92
122
|
unless added_rpx_data.blank?
|
93
123
|
session_class.controller.session['added_rpx_data'] = nil
|
124
|
+
rpx_id = added_rpx_data['profile']['identifier']
|
125
|
+
rpx_provider_name = added_rpx_data['profile']['providerName']
|
126
|
+
unless self.rpx_identifiers.find_by_identifier( rpx_id )
|
127
|
+
RAILS_DEFAULT_LOGGER.info "account_merge_enabled? = #{account_merge_enabled?}"
|
128
|
+
# identifier not already set for this user
|
129
|
+
another_user = self.class.find_by_rpx_identifier( rpx_id )
|
130
|
+
if another_user
|
131
|
+
return false unless account_merge_enabled?
|
132
|
+
# another user already has this id registered
|
133
|
+
# merge all IDs from another_user to self, with application callbacks before/after
|
134
|
+
before_merge_rpx_data( another_user, self )
|
135
|
+
self.rpx_identifiers << another_user.rpx_identifiers
|
136
|
+
after_merge_rpx_data( another_user, self )
|
137
|
+
else
|
138
|
+
self.rpx_identifiers.create( :identifier => rpx_id, :provider_name => rpx_provider_name )
|
139
|
+
end
|
140
|
+
end
|
94
141
|
map_added_rpx_data( added_rpx_data )
|
95
142
|
end
|
96
143
|
return true
|
97
|
-
end
|
98
|
-
|
144
|
+
end
|
145
|
+
|
99
146
|
# map_added_rpx_data maps additional fields from the RPX response into the user object during the "add RPX to existing account" process.
|
100
147
|
# Override this in your user model to perform field mapping as may be desired
|
101
148
|
# See https://rpxnow.com/docs#profile_data for the definition of available attributes
|
102
149
|
#
|
103
|
-
#
|
150
|
+
# "self" at this point is the user model. Map details as appropriate from the rpx_data structure provided.
|
104
151
|
#
|
105
152
|
def map_added_rpx_data( rpx_data )
|
106
|
-
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
# determines if account merging is enabled
|
157
|
+
def account_merge_enabled?
|
158
|
+
self.class.account_merge_enabled_value
|
107
159
|
end
|
160
|
+
|
161
|
+
# before_merge_rpx_data provides a hook for application developers to perform data migration prior to the merging of user accounts.
|
162
|
+
# This method is called just before authlogic_rpx merges the user registration for 'from_user' into 'to_user'
|
163
|
+
# Authlogic_RPX is responsible for merging registration data.
|
164
|
+
#
|
165
|
+
# By default, it does not merge any other details (e.g. application data ownership)
|
166
|
+
#
|
167
|
+
def before_merge_rpx_data( from_user, to_user )
|
108
168
|
|
169
|
+
end
|
170
|
+
|
171
|
+
# after_merge_rpx_data provides a hook for application developers to perform account clean-up after authlogic_rpx has
|
172
|
+
# migrated registration details.
|
173
|
+
#
|
174
|
+
# By default, does nothing. It could, for example, be used to delete or disable the 'from_user' account
|
175
|
+
#
|
176
|
+
def after_merge_rpx_data( from_user, to_user )
|
177
|
+
|
178
|
+
end
|
179
|
+
|
109
180
|
# experimental - a feature of RPX paid accounts and not properly developed/tested yet
|
110
181
|
def map_id?
|
111
182
|
self.class.map_id
|
@@ -144,6 +144,7 @@ module AuthlogicRpx
|
|
144
144
|
end
|
145
145
|
|
146
146
|
rpx_id = @rpx_data['profile']['identifier']
|
147
|
+
rpx_provider_name = @rpx_data['profile']['providerName']
|
147
148
|
if rpx_id.blank?
|
148
149
|
errors.add_to_base("Authentication failed. Please try again.")
|
149
150
|
return false
|
@@ -162,7 +163,7 @@ module AuthlogicRpx
|
|
162
163
|
# user objects invoke each other upon save
|
163
164
|
self.new_registration = true
|
164
165
|
self.attempted_record.creating_new_record_from_rpx = true
|
165
|
-
self.attempted_record.rpx_identifiers.build(:identifier => rpx_id)
|
166
|
+
self.attempted_record.rpx_identifiers.build(:identifier => rpx_id, :provider_name => rpx_provider_name )
|
166
167
|
self.attempted_record.save_without_session_maintenance
|
167
168
|
else
|
168
169
|
errors.add_to_base("We did not find any accounts with that login. Enter your details and create an account.")
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{sidonath-authlogic_rpx}
|
5
|
-
s.version = "1.0.
|
5
|
+
s.version = "1.0.4em"
|
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", "John J. Bachir / jjb", "Damir Zekic / sidonath"]
|