sidonath-authlogic_rpx 1.0.4b → 1.0.4em

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Manifest CHANGED
@@ -3,11 +3,14 @@ MIT-LICENSE
3
3
  Manifest
4
4
  README.rdoc
5
5
  Rakefile
6
- authlogic_rpx.gemspec
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.4
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.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'
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.1'
67
- rpx_now --version '>= 0.6.6' --source gemcutter.org
68
- authlogic_rpx --version '>= 1.0.4' --source gemcutter.org
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. Create a migration which creates a table for this model.
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
- 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).
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 (see notes in "3. Add custom user profile mapping during auto-registration")
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 CreateRPXIdentifiers < ActiveRecord::Migration
103
+ class AddAuthlogicRpxMigration < ActiveRecord::Migration
99
104
  def self.up
100
105
  create_table :rpx_identifiers do |t|
101
- t.string :identifier
102
- t.integer :user_id
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
- [:crypted_password, :password_salt].each do |field|
119
- User.all(:conditions => "#{field} is NULL").each { |user| user.update_attribute(field, "") if user.send(field).nil? }
120
- change_column :users, field, :string, :default => "", :null => false
121
- end
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 should look like this
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
- 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).
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
- return nil if identifier.nil?
33
- identifier.user
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
- # By default, it only creates a new RPXIdentifier for the user.
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
- self.rpx_identifiers.create( :identifier => rpx_data['profile']['identifier'] )
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.")
@@ -40,8 +40,8 @@ module AuthlogicRpx
40
40
  end
41
41
 
42
42
  MAJOR = 1
43
- MINOR = 0
44
- TINY = 4
43
+ MINOR = 1
44
+ TINY = 0
45
45
 
46
46
  # The current version as a Version instance
47
47
  CURRENT = new(MAJOR, MINOR, TINY)
@@ -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.4b"
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"]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidonath-authlogic_rpx
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4b
4
+ version: 1.0.4em
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Gallagher / tardate