authlogic_rpx 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc ADDED
@@ -0,0 +1,13 @@
1
+ == 1.0.2 released 2009-09-27
2
+
3
+ * Fixed issue with rpx_popup that was causing an error on some webkit-based browsers (incl chrome)
4
+
5
+ == 1.0.1 released 2009-09-26
6
+
7
+ * Initial public release
8
+ * RPX profile mappings switched to use indirect Authlogic field naming
9
+ * Documentation updated
10
+
11
+ == 1.0.0 released 2009-09-25
12
+
13
+ * Initial release
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Paul Gallagher (tardate.com)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest ADDED
@@ -0,0 +1,20 @@
1
+ CHANGELOG.rdoc
2
+ MIT-LICENSE
3
+ Manifest
4
+ README.rdoc
5
+ Rakefile
6
+ authlogic_rpx.gemspec
7
+ init.rb
8
+ lib/authlogic_rpx.rb
9
+ lib/authlogic_rpx/acts_as_authentic.rb
10
+ lib/authlogic_rpx/helper.rb
11
+ lib/authlogic_rpx/session.rb
12
+ lib/authlogic_rpx/version.rb
13
+ rails/init.rb
14
+ test/acts_as_authentic_test.rb
15
+ test/fixtures/users.yml
16
+ test/libs/rails_trickery.rb
17
+ test/libs/user.rb
18
+ test/libs/user_session.rb
19
+ test/session_test.rb
20
+ test/test_helper.rb
data/README.rdoc ADDED
@@ -0,0 +1,436 @@
1
+ = Authlogic RPX
2
+
3
+ == Purpose
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.
6
+
7
+ Key features and capabilities:
8
+ * Auto-registration by default following RPX authentication (can be disabled if required)
9
+ * Can allow users to enable RPX authentication for their existing password-enabled accounts
10
+ * View helpers to assist with inserting login fragments in pages
11
+ * Can co-exist with standard password authentication
12
+
13
+
14
+ == Authlogic_RPX References
15
+
16
+ * <b>Authlogic_RPX gem repo:</b> [http://github.com/tardate/authlogic_rpx]
17
+ * <b>Authlogic_RPX issues and feedback:</b> [http://github.com/tardate/authlogic_rpx/issues]
18
+
19
+ The demonstration Rails application is where you can see Authlogic_RPX in action:
20
+ * <b>Live Demonstration Site:</b> [http://rails-authlogic-rpx-sample.heroku.com]
21
+ * <b>Demonstration site source repository:</b> [http://github.com/tardate/rails-authlogic-rpx-sample]
22
+
23
+ == Authlogic and RPX References
24
+
25
+ * <b>Authlogic documentation:</b> [http://rdoc.info/projects/binarylogic/authlogic]
26
+ * <b>Authlogic repo:</b> [http://github.com/binarylogic/authlogic]
27
+ * <b>RPX documentation:</b> [https://rpxnow.com/docs]
28
+ * <b>RPX_now gem repo:</b> [http://github.com/grosser/rpx_now]
29
+
30
+
31
+ == Installing Authlogic RPX gem
32
+
33
+ Three gems are required: authlogic, grosser-rpx_now, and tardate-authlogic_rpx. Install these as appropriate to your environment and preferences.
34
+
35
+ Currently tested versions:
36
+ * authlogic 2.1.1
37
+ * grosser-rpx_now 0.5.10
38
+ * tardate-authlogic_rpx 1.0.2
39
+
40
+
41
+ === 1. Direct gem installation
42
+
43
+ sudo gem install authlogic
44
+ sudo gem install grosser-rpx_now --source http://gems.github.com
45
+ sudo gem install tardate-authlogic_rpx --source http://gems.github.com
46
+
47
+
48
+ === 2. Using Rails config.gems
49
+
50
+ Include in config/environment.rb:
51
+
52
+ config.gem "authlogic"
53
+ config.gem "grosser-rpx_now", :lib => "rpx_now", :source => 'http://gems.github.com'
54
+ config.gem "tardate-authlogic_rpx", :lib => "authlogic_rpx", :source => 'http://gems.github.com'
55
+
56
+ Then to install, run from the command line:
57
+
58
+ sudo rake gems:install
59
+
60
+
61
+ === 3. Using .gems file (e.g for heroku.com deployments)
62
+
63
+ Include in RAILS_ROOT/.gems:
64
+
65
+ authlogic
66
+ grosser-rpx_now --source gems.github.com
67
+ tardate-authlogic_rpx --source gems.github.com
68
+
69
+
70
+ == Using Authlogic RPX
71
+
72
+ <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>
73
+
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.
75
+
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.
77
+
78
+ The main steps for enabling Authlogic RPX:
79
+ * 1. Enable RPX for your user model
80
+ * 2. Add RPX configuration for the Authlogic session model
81
+ * 3 Add custom user profile mapping (optional)
82
+ * 4. Add application controller helpers: current_user, current_user_session
83
+ * 5. Setup the Authlogic session controller
84
+ * 6. Setup the Authlogic user controller
85
+ * 7. Use view helpers to provide login links
86
+ * 8. Allow users to "Add RPX" to existing accounts (optional)
87
+
88
+
89
+ === 1. Enable RPX for your user model
90
+
91
+ The user model requires an additional field called "rpx_identifier". Creat a migration to add this.
92
+ 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
+
94
+ class AddUsersRpxIdentifier < ActiveRecord::Migration
95
+ def self.up
96
+ add_column :users, :rpx_identifier, :string
97
+ add_index :users, :rpx_identifier
98
+
99
+ change_column :users, :crypted_password, :string, :default => nil, :null => true
100
+ change_column :users, :password_salt, :string, :default => nil, :null => true
101
+
102
+ end
103
+
104
+ def self.down
105
+ remove_column :users, :openid_identifier
106
+
107
+ [:crypted_password, :password_salt].each do |field|
108
+ User.all(:conditions => "#{field} is NULL").each { |user| user.update_attribute(field, "") if user.send(field).nil? }
109
+ change_column :users, field, :string, :default => "", :null => false
110
+ end
111
+ end
112
+ end
113
+
114
+ 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)
115
+
116
+ class User < ActiveRecord::Base
117
+ acts_as_authentic do |c|
118
+ c.my_config_option = my_value # for available options see documentation in: Authlogic::ActsAsAuthentic
119
+ end # block optional
120
+ attr_accessible :username, :email, :password, :password_confirmation, :rpx_identifier
121
+ end
122
+
123
+ {See the source for the sample user.rb}[http://github.com/tardate/rails-authlogic-rpx-sample/blob/master/app/models/user.rb].
124
+
125
+
126
+ === 2. Add RPX configuration for the Authlogic session model
127
+
128
+ Authlogic provides a helper to create the session model:
129
+
130
+ script/generate session user_session
131
+
132
+ The minimum configuration required is to add your RPX_API_KEY:
133
+
134
+ class UserSession < Authlogic::Session::Base
135
+ rpx_key RPX_API_KEY
136
+ end
137
+
138
+ Get an API key by registering your application at {RPX}[http://rpxnow.com/]. A free "Basic" account is available, in addition to paid enhanced versions. All work with Authlogic_RPX.
139
+
140
+ You probably don't want to put your API key in directly. A recommended approach is to set the key as an environment variable, and then set it as a constant in config/environment.rb:
141
+
142
+ RPX_API_KEY = ENV['RPX_API_KEY']
143
+
144
+ Two additional RPX-specific session configuration options are available.
145
+ * auto_register: enable/disable user auto-registration (enabled by default)
146
+ * rpx_extended_info: enable/disable extended profile information in the RPX authentication (disabled by default)
147
+
148
+ For example, to disable auto-registration and enable extended info:
149
+
150
+ class UserSession < Authlogic::Session::Base
151
+ rpx_key RPX_API_KEY
152
+ auto_register false
153
+ rpx_extended_info
154
+ end
155
+
156
+ {See the source for the sample user_session.rb}[http://github.com/tardate/rails-authlogic-rpx-sample/blob/master/app/models/user_session.rb].
157
+
158
+ === 3. Add custom user profile mapping (optional)
159
+ 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.
160
+
161
+ 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.
162
+
163
+ class UserSession < Authlogic::Session::Base
164
+ rpx_key RPX_API_KEY
165
+ rpx_extended_info
166
+
167
+ private
168
+
169
+ # map_rpx_data maps additional fields from the RPX response into the user object
170
+ # override this in your session controller to change the field mapping
171
+ # see https://rpxnow.com/docs#profile_data for the definition of available attributes
172
+ #
173
+ def map_rpx_data
174
+ # map core profile data using authlogic indirect column names
175
+ self.attempted_record.send("#{klass.login_field}=", @rpx_data['profile']['preferredUsername'] ) if attempted_record.send(klass.login_field).blank?
176
+ self.attempted_record.send("#{klass.email_field}=", @rpx_data['profile']['email'] ) if attempted_record.send(klass.email_field).blank?
177
+
178
+ # map some other columns explicityl
179
+ self.attempted_record.fullname = @rpx_data['profile']['displayName'] if attempted_record.fullname.blank?
180
+
181
+ if rpx_extended_info?
182
+ # map some extended attributes
183
+ end
184
+ end
185
+
186
+ end
187
+
188
+ === 4. Add application controller helpers: current_user, current_user_session
189
+
190
+ 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.
191
+
192
+ class ApplicationController < ActionController::Base
193
+ helper :all # include all helpers, all the time
194
+ protect_from_forgery # See ActionController::RequestForgeryProtection for details
195
+
196
+ # Scrub sensitive parameters from your log
197
+ filter_parameter_logging :password, :password_confirmation
198
+
199
+ helper_method :current_user, :current_user_session
200
+
201
+ private
202
+
203
+ def current_user_session
204
+ return @current_user_session if defined?(@current_user_session)
205
+ @current_user_session = UserSession.find
206
+ end
207
+
208
+ def current_user
209
+ return @current_user if defined?(@current_user)
210
+ @current_user = current_user_session && current_user_session.record
211
+ end
212
+ end
213
+
214
+ {See the source for the sample user_session_controller.rb}[http://github.com/tardate/rails-authlogic-rpx-sample/blob/master/app/controllers/application_controller.rb].
215
+
216
+
217
+ === 5. Setup the Authlogic session controller
218
+
219
+ If you don't already have a user session controller, create one. There are four actions of significance for authlogic_rpx:
220
+
221
+ $ script/generate controller user_sessions index new create destroy
222
+
223
+ {See the source for the sample user_session_controller.rb}[http://github.com/tardate/rails-authlogic-rpx-sample/blob/master/app/controllers/user_sessions_controller.rb].
224
+
225
+ In config/routes.rb we can define the standard routes for this controller and two named routes for the main login/out (or singin/out if you prefer that terminology):
226
+
227
+ map.signin "signin", :controller => "user_sessions", :action => "new"
228
+ map.signout "signout", :controller => "user_sessions", :action => "destroy"
229
+ map.resources :user_sessions
230
+
231
+ ==== index
232
+ This is where RPX will return to if the user cancelled the login process, so it needs to be handled. You probably just want to redirect the user to an appropriate alternative:
233
+
234
+ def index
235
+ redirect_to current_user ? root_url : new_user_session_url
236
+ end
237
+
238
+ ==== new
239
+ Typically used to render a login form
240
+
241
+ def new
242
+ @user_session = UserSession.new
243
+ end
244
+
245
+ ==== create
246
+ This is where the magic happens for authentication. Authlogic hides all the underlying wiring, and you just need to "save" the session!
247
+
248
+ Authlogic_rpx provides two additional methods that you might want to use to tailor you application behaviour:
249
+ * new_registration? - if a new registration, e.g. force them to go via a registration follow-up page
250
+ * registration_complete? - if registration details not complete, e.g. bounce the user over the profile editing page
251
+
252
+ def create
253
+ @user_session = UserSession.new(params[:user_session])
254
+ if @user_session.save
255
+ if @user_session.new_registration?
256
+ flash[:notice] = "Welcome! As a new user, please review your registration details before continuing.."
257
+ redirect_to edit_user_path( :current )
258
+ else
259
+ if @user_session.registration_complete?
260
+ flash[:notice] = "Successfully signed in."
261
+ redirect_back_or_default articles_path
262
+ else
263
+ flash[:notice] = "Welcome back! Please complete required registration details before continuing.."
264
+ redirect_to edit_user_path( :current )
265
+ end
266
+ end
267
+ else
268
+ flash[:error] = "Failed to login or register."
269
+ redirect_to new_user_session_path
270
+ end
271
+ end
272
+
273
+ ==== destroy
274
+ The logout action..
275
+
276
+ def destroy
277
+ @user_session = current_user_session
278
+ @user_session.destroy if @user_session
279
+ flash[:notice] = "Successfully signed out."
280
+ redirect_to articles_path
281
+ end
282
+
283
+
284
+ === 6. Setup the Authlogic user controller
285
+
286
+ The users controller handles the actual user creation and editing actions. In it's standard form, it looks like any other controller with an underlying ActiveRecord model.
287
+
288
+ There are five basic actions to consider. If you don't already have a controller, create it:
289
+
290
+ $ script/generate controller users new create edit show update
291
+
292
+ {See the source for the sample users_controller.rb}[http://github.com/tardate/rails-authlogic-rpx-sample/blob/master/app/controllers/users_controller.rb].
293
+
294
+ The users controller just needs standard routes defined in config/routes.rb:
295
+
296
+ map.resources :users
297
+
298
+ ==== new
299
+ Stock standard form for a user to register on the site. Only required if you will allow users to register without using RPX auto-registration (using standard password authentication).
300
+
301
+ def new
302
+ @user = User.new
303
+ end
304
+
305
+ ==== create
306
+ As for new, stock standard and only required if you will allow users to register without using RPX auto-registration.
307
+
308
+ def create
309
+ @user = User.new(params[:user])
310
+ if @user.save
311
+ flash[:notice] = "Successfully registered user."
312
+ redirect_to articles_path
313
+ else
314
+ render :action => 'new'
315
+ end
316
+ end
317
+
318
+ ==== show
319
+ Display's the user's profile. Uses the current_user helper that we'll include in the application controller.
320
+
321
+ def show
322
+ @user = current_user
323
+ end
324
+
325
+ ==== edit
326
+ Allows the user to edit their profile. Calling valid? will ensure any validation errors are highlighted. This can be relevant with RPX since auto-registration may not include all the profile data you want to make "mandatory" for normal users.
327
+
328
+ def edit
329
+ @user = current_user
330
+ @user.valid?
331
+ end
332
+
333
+ ==== update
334
+ Handles the submission of the edit form. Again, uses the current_user helper that we'll include in the application controller.
335
+
336
+ def update
337
+ @user = current_user
338
+ @user.attributes = params[:user]
339
+ if @user.save
340
+ flash[:notice] = "Successfully updated user."
341
+ redirect_back_or_default articles_path
342
+ else
343
+ render :action => 'edit'
344
+ end
345
+ end
346
+
347
+
348
+ === 7. Use view helpers to provide login links
349
+
350
+ So how to put a "login" link on your page? Two helper methods are provided:
351
+ * <b>rpx_popup</b> helper to insert a link to pop-up RPX login
352
+ * <b>rpx_embed</b> helper to insert an embedded iframe RPX login form
353
+
354
+ Each takes an options hash:
355
+ * <tt>link_text:</tt> text to use in the link (only used by rpx_popup)
356
+ * <tt>app_name:</tt> name of the application (will be prepended to RPX domain and used in RPX dialogues)
357
+ * <tt>return_url:</tt> url for the RPX callback (e.g. user_sessions_url)
358
+ * <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"
359
+
360
+ For example, to insert a login link in a navigation bar is as simple as this:
361
+
362
+ &lt;div id="user_nav"&gt;
363
+ &lt;%= link_to "Home", root_path %&gt; |
364
+ &lt;% if current_user %&gt;
365
+ &lt;%= link_to "Profile", user_path(:current) %&gt; |
366
+ &lt;%= link_to "Sign out", signout_path %&gt;
367
+ &lt;% else %&gt;
368
+ &lt;%= rpx_popup( :link_text => "Register/Sign in with RPX..", :app_name => "rails-authlogic-rpx-sample", :return_url => user_sessions_url ) %>&gt;
369
+ &lt;% end %&gt;
370
+ &lt;/div&gt;
371
+
372
+ === 8. Allow users to "Add RPX" to existing accounts (optional)
373
+
374
+ If you got this far and have a working application, you are ready to go, especially if you only plan to support RPX authentication.
375
+
376
+ However, if you support other authentication methods (e.g. by password), you probably want the ability to let user's add RPX to an existing account. This is not possible by default, however adding it is simply a matter of providing another method on your user controller.
377
+
378
+ The route may be called anything you like. Let's use "addrpxauth" for example.
379
+
380
+ # This action has the special purpose of receiving an update of the RPX identity information
381
+ # for current user - to add RPX authentication to an existing non-RPX account.
382
+ # RPX only supports :post, so this cannot simply go to update method (:put)
383
+ def addrpxauth
384
+ @user = current_user
385
+ if @user.save
386
+ flash[:notice] = "Successfully added RPX authentication for this account."
387
+ render :action => 'show'
388
+ else
389
+ render :action => 'edit'
390
+ end
391
+ end
392
+
393
+ {This is demonstrated in the sample users_controller.rb}[http://github.com/tardate/rails-authlogic-rpx-sample/blob/master/app/controllers/users_controller.rb].
394
+
395
+ You'll note this is almost identical to the "update". The main difference is that it needs to be enabled for :post by RPX. In config/routes.rb:
396
+
397
+ map.addrpxauth "addrpxauth", :controller => "users", :action => "addrpxauth", :method => :post
398
+
399
+ === 9. There is no 9
400
+
401
+ That's all there is. To see Authlogic_RPX in action, check out the demonstration Rails application:
402
+ * <b>Live Demonstration Site:</b> [http://rails-authlogic-rpx-sample.heroku.com]
403
+ * <b>Demonstration site source repository:</b> [http://github.com/tardate/rails-authlogic-rpx-sample]
404
+
405
+
406
+ == Improving Authlogic_RPX: next steps; how to help
407
+
408
+ Authlogic_RPX is open source and hosted on {github}[http://github.com/tardate/authlogic_rpx]. Developer's are welcome to fork and play - if you have improvements or bug fixes, just send a request to pull from your fork.
409
+
410
+ If you have issues or feedback, please log them in the {issues list on github}[http://github.com/tardate/authlogic_rpx/issues]
411
+
412
+ Some of the improvements currently on the radar:
413
+ * Still figuring out how to write some good automated tests
414
+ * Implement/verify support for RPX "paid" service features of their "Plus" and "Pro" accounts (to date, only tested with free RPX "Basic" account)
415
+ * Add support for proxy/direct authentication (i.e. so you can programmatically "authenticate" as an existing user based on the RPX id)
416
+
417
+
418
+
419
+ == Internals
420
+
421
+ Some design principles:
422
+ * Attempted to stay as close to binarylogic's "unobtrusive authentication" sensibility in Authlogic design
423
+ * All direct RPX processing is handled in the AuthlogicRpx::Session class (not in the ActiveRecord model)
424
+ * It uses the plug-in architecture introduced in Authlogic v2.0.
425
+
426
+
427
+
428
+ == Kudos and Kopywrite
429
+
430
+ 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.
431
+
432
+ The idea of adding RPX support to authlogic is not new. Some early ideas were found in the following projects, although it was decided not to base this implementation on a fork of these, since the approaches varied considerably:
433
+ * <b>http://github.com/hunter/authlogic_rpx</b> an initial start, based on authlogic_openid and using rpx_now
434
+ * <b>http://github.com/gampleman/authlogic_rpx/</b> similar, but including an implementation of the RPX api
435
+
436
+ authlogic_rpx was created by Paul Gallagher (tardate.com) and released under the MIT license.
data/Rakefile ADDED
@@ -0,0 +1,20 @@
1
+ ENV['RDOCOPT'] = "-S -f html -T hanna"
2
+
3
+ require "rubygems"
4
+ require "echoe"
5
+ require File.dirname(__FILE__) << "/lib/authlogic_rpx/version"
6
+
7
+ Echoe.new("authlogic_rpx") do |p|
8
+ p.version = AuthlogicRpx::Version::STRING
9
+ p.url = "http://github.com/tardate/authlogic_rpx"
10
+ p.summary = "Authlogic plug-in for RPX support"
11
+ p.description = "Authlogic extension/plugin that provides RPX (rpxnow.com) authentication support"
12
+
13
+ p.runtime_dependencies = ["authlogic >=2.1.1", "grosser-rpx_now >=0.5.10" ]
14
+ p.development_dependencies = []
15
+
16
+ p.author = "Paul Gallagher / tardate"
17
+ p.email = 'gallagher.paul@gmail.com'
18
+
19
+ p.extra_deps = %w(authlogic >= 0)
20
+ end
@@ -0,0 +1,37 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{authlogic_rpx}
5
+ s.version = "1.0.2"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Paul Gallagher / tardate"]
9
+ s.date = %q{2009-10-02}
10
+ s.description = %q{Authlogic extension/plugin that provides RPX (rpxnow.com) authentication support}
11
+ s.email = %q{gallagher.paul@gmail.com}
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
+ 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
+ s.homepage = %q{http://github.com/tardate/authlogic_rpx}
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Authlogic_rpx", "--main", "README.rdoc"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = %q{authlogic_rpx}
18
+ s.rubygems_version = %q{1.3.5}
19
+ s.summary = %q{Authlogic plug-in for RPX support}
20
+ s.test_files = ["test/acts_as_authentic_test.rb", "test/session_test.rb", "test/test_helper.rb"]
21
+
22
+ if s.respond_to? :specification_version then
23
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
24
+ s.specification_version = 3
25
+
26
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
+ s.add_runtime_dependency(%q<authlogic>, [">= 2.1.1"])
28
+ s.add_runtime_dependency(%q<grosser-rpx_now>, [">= 0.5.10"])
29
+ else
30
+ s.add_dependency(%q<authlogic>, [">= 2.1.1"])
31
+ s.add_dependency(%q<grosser-rpx_now>, [">= 0.5.10"])
32
+ end
33
+ else
34
+ s.add_dependency(%q<authlogic>, [">= 2.1.1"])
35
+ s.add_dependency(%q<grosser-rpx_now>, [">= 0.5.10"])
36
+ end
37
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require File.dirname(__FILE__) + "/rails/init.rb"
@@ -0,0 +1,8 @@
1
+ require "authlogic_rpx/version"
2
+ require "authlogic_rpx/acts_as_authentic"
3
+ require "authlogic_rpx/session"
4
+ require "authlogic_rpx/helper"
5
+
6
+ ActiveRecord::Base.send(:include, AuthlogicRpx::ActsAsAuthentic)
7
+ Authlogic::Session::Base.send(:include, AuthlogicRpx::Session)
8
+ ActionController::Base.helper AuthlogicRpx::Helper
@@ -0,0 +1,94 @@
1
+ # This module is responsible for adding RPX functionality to Authlogic. Checkout the README for more info and please
2
+ # see the sub modules for detailed documentation.
3
+ module AuthlogicRpx
4
+ # This module is responsible for adding in the RPX functionality to your models. It hooks itself into the
5
+ # acts_as_authentic method provided by Authlogic.
6
+ module ActsAsAuthentic
7
+ # Adds in the neccesary modules for acts_as_authentic to include and also disabled password validation if
8
+ # RPX is being used.
9
+ def self.included(klass)
10
+ klass.class_eval do
11
+ extend Config
12
+ add_acts_as_authentic_module(Methods, :prepend)
13
+ end
14
+ end
15
+
16
+ module Config
17
+
18
+ # map_id is used to enable RPX identity mapping
19
+ # experimental - a feature of RPX paid accounts and not properly developed/tested yet
20
+ #
21
+ # * <tt>Default:</tt> false
22
+ # * <tt>Accepts:</tt> boolean
23
+ def map_id(value = false)
24
+ rw_config(:map_id, value, false)
25
+ end
26
+ alias_method :map_id=, :map_id
27
+
28
+ end
29
+
30
+ module Methods
31
+
32
+ # Set up some simple validations
33
+ def self.included(klass)
34
+ klass.class_eval do
35
+ validates_uniqueness_of :rpx_identifier, :scope => validations_scope, :if => :using_rpx?
36
+ validates_length_of_password_field_options validates_length_of_password_field_options.merge(:if => :validate_password_with_rpx?)
37
+ validates_confirmation_of_password_field_options validates_confirmation_of_password_field_options.merge(:if => :validate_password_with_rpx?)
38
+ validates_length_of_password_confirmation_field_options validates_length_of_password_confirmation_field_options.merge(:if => :validate_password_with_rpx?)
39
+ before_validation :adding_rpx_identifier
40
+ after_create :map_rpx_identifier
41
+ end
42
+ end
43
+
44
+ # support a block given to the save
45
+ def save(perform_validation = true, &block)
46
+ result = super perform_validation
47
+ yield(result) if block_given?
48
+ result
49
+ end
50
+
51
+ # test if account it using RPX authentication
52
+ def using_rpx?
53
+ !rpx_identifier.blank?
54
+ end
55
+
56
+ # test if account it using normal password authentication
57
+ def using_password?
58
+ !send(crypted_password_field).blank?
59
+ end
60
+
61
+ private
62
+
63
+ def validate_password_with_rpx?
64
+ !using_rpx? && require_password?
65
+ end
66
+
67
+ def adding_rpx_identifier
68
+ return true unless session_class && session_class.controller
69
+ new_rpx_id = session_class.controller.session['added_rpx_identifier']
70
+ unless new_rpx_id.blank?
71
+ session_class.controller.session['added_rpx_identifier'] = nil
72
+ self.rpx_identifier = new_rpx_id
73
+ end
74
+ return true
75
+ end
76
+
77
+ # experimental - a feature of RPX paid accounts and not properly developed/tested yet
78
+ def map_id?
79
+ self.class.map_id
80
+ end
81
+
82
+ # experimental - a feature of RPX paid accounts and not properly developed/tested yet
83
+ def map_rpx_identifier
84
+ RPXNow.map(rpx_identifier, id) if using_rpx? && map_id?
85
+ end
86
+
87
+ # experimental - a feature of RPX paid accounts and not properly developed/tested yet
88
+ def unmap_rpx_identifer
89
+ RPXNow.unmap(rpx_identifier, id) if using_rpx? && map_id?
90
+ end
91
+
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,36 @@
1
+ module AuthlogicRpx
2
+ module Helper
3
+
4
+ # helper to insert an embedded iframe RPX login
5
+ # takes options hash:
6
+ # * <tt>app_name:</tt> name of the application (will be prepended to RPX domain and used in RPX dialogues)
7
+ # * <tt>return_url:</tt> url for the RPX callback (e.g. user_sessions_url)
8
+ # * <tt>add_rpx:</tt> if true, requests RPX callback to add to current session. Else runs normal authentication process (default)
9
+ def rpx_embed(options = {})
10
+ params = (
11
+ { :authenticity_token => form_authenticity_token, :add_rpx => options[:add_rpx] }.collect { |n| "#{n[0]}=#{ u(n[1]) }" if n[1] }
12
+ ).compact.join('&')
13
+ RPXNow.embed_code(options[:app_name], u( options[:return_url] + '?' + params ) )
14
+ end
15
+
16
+ # helper to insert a link to pop-up RPX login
17
+ # takes options hash:
18
+ # * <tt>link_text:</tt> text to use in the link
19
+ # * <tt>app_name:</tt> name of the application (will be prepended to RPX domain and used in RPX dialogues)
20
+ # * <tt>return_url:</tt> url for the RPX callback (e.g. user_sessions_url)
21
+ # * <tt>add_rpx:</tt> if true, requests RPX callback to add to current session. Else runs normal authentication process (default)
22
+ def rpx_popup(options = {})
23
+ params = (
24
+ { :authenticity_token => form_authenticity_token, :add_rpx => options[:add_rpx] }.collect { |n| "#{n[0]}=#{ u(n[1]) }" if n[1] }
25
+ ).compact.join('&')
26
+ RPXNow.popup_code(
27
+ options[:link_text],
28
+ options[:app_name],
29
+ u( options[:return_url] + '?' + params ),
30
+ :unobtrusive=>true
31
+ )
32
+ # NB: i18n considerations? supports a :language parameter (not tested)
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,177 @@
1
+ module AuthlogicRpx
2
+ # This module is responsible for adding all of the RPX goodness to the Authlogic::Session::Base class.
3
+ module Session
4
+ # Add a simple rpx_identifier attribute and some validations for the field.
5
+ def self.included(klass)
6
+ klass.class_eval do
7
+ extend Config
8
+ include Methods
9
+ end
10
+ end
11
+
12
+ module Config
13
+
14
+ def find_by_rpx_identifier_method(value = nil)
15
+ rw_config(:find_by_rpx_identifier_method, value, :find_by_rpx_identifier)
16
+ end
17
+ alias_method :find_by_rpx_identifier_method=, :find_by_rpx_identifier_method
18
+
19
+ # Auto Register is enabled by default.
20
+ # Add this in your Session object if you need to disable auto-registration via rpx
21
+ #
22
+ def auto_register(value=true)
23
+ auto_register_value(value)
24
+ end
25
+ def auto_register_value(value=nil)
26
+ rw_config(:auto_register,value,true)
27
+ end
28
+ alias_method :auto_register=,:auto_register
29
+
30
+ # Add this in your Session object to set the RPX API key
31
+ # RPX won't work without the API key. Set it here if not already set in your app configuration.
32
+ #
33
+ def rpx_key(value=nil)
34
+ rpx_key_value(value)
35
+ end
36
+ def rpx_key_value(value=nil)
37
+ if ! inheritable_attributes.include?(:rpx_key)
38
+ RPXNow.api_key = value
39
+ end
40
+ rw_config(:rpx_key,value,false)
41
+ end
42
+ alias_method :rpx_key=,:rpx_key
43
+
44
+ # Add this in your Session object to set whether RPX returns extended user info
45
+ # By default, it will not, which is enough to get username, name, email and the rpx identified
46
+ # if you want to map additional information into your user details, you can request extended
47
+ # attributes (though not all providers give them - see the RPX docs)
48
+ #
49
+ def rpx_extended_info(value=true)
50
+ rpx_extended_info_value(value)
51
+ end
52
+ def rpx_extended_info_value(value=nil)
53
+ rw_config(:rpx_extended_info,value,false)
54
+ end
55
+ alias_method :rpx_extended_info=,:rpx_extended_info
56
+
57
+ end
58
+
59
+ module Methods
60
+
61
+ def self.included(klass)
62
+ klass.class_eval do
63
+ attr_accessor :new_registration
64
+ attr_accessor :rpx_identifier
65
+ attr_accessor :rpx_data
66
+ after_persisting :add_rpx_identifier, :if => :adding_rpx_identifier?
67
+ validate :validate_by_rpx, :if => :authenticating_with_rpx?
68
+ end
69
+ end
70
+
71
+ # Determines if the authenticated user is also a new registration.
72
+ # For use in the session controller to help direct the most appropriate action to follow.
73
+ #
74
+ def new_registration?
75
+ new_registration
76
+ end
77
+
78
+ # Determines if the authenticated user has a complete registration (no validation errors)
79
+ # For use in the session controller to help direct the most appropriate action to follow.
80
+ #
81
+ def registration_complete?
82
+ attempted_record && attempted_record.valid?
83
+ end
84
+
85
+ private
86
+ def authenticating_with_rpx?
87
+ controller.params[:token] && !controller.params[:add_rpx]
88
+ end
89
+
90
+ def find_by_rpx_identifier_method
91
+ self.class.find_by_rpx_identifier_method
92
+ end
93
+
94
+ # Tests if auto_registration is enabled (on by default)
95
+ #
96
+ def auto_register?
97
+ self.class.auto_register_value
98
+ end
99
+
100
+ # Tests if rpx_extended_info is enabled (off by default)
101
+ #
102
+ def rpx_extended_info?
103
+ self.class.rpx_extended_info_value
104
+ end
105
+
106
+ def adding_rpx_identifier?
107
+ controller.params[:token] && controller.params[:add_rpx]
108
+ end
109
+
110
+ # the main RPX magic. At this pont, a session is being validated and we know RPX identifier
111
+ # has been provided. We'll callback to RPX to verify the token, and authenticate the matching
112
+ # user.
113
+ # If no user is found, and we have auto_register enabled (default) this method will also
114
+ # create the user registration stub.
115
+ #
116
+ # On return to the controller, you can test for new_registration? and registration_complete?
117
+ # to determine the most appropriate action
118
+ #
119
+ def add_rpx_identifier
120
+ data = RPXNow.user_data(controller.params[:token])
121
+ controller.session['added_rpx_identifier'] = data[:identifier] if data
122
+ end
123
+
124
+ # the main RPX magic. At this pont, a session is being validated and we know RPX identifier
125
+ # has been provided. We'll callback to RPX to verify the token, and authenticate the matching
126
+ # user.
127
+ # If no user is found, and we have auto_register enabled (default) this method will also
128
+ # create the user registration stub.
129
+ #
130
+ # On return to the controller, you can test for new_registration? and registration_complete?
131
+ # to determine the most appropriate action
132
+ #
133
+ def validate_by_rpx
134
+ @rpx_data = RPXNow.user_data(controller.params[:token], :extended=> rpx_extended_info? ) {|raw| raw }
135
+ # If we don't have a valid sign-in, give-up at this point
136
+ if @rpx_data.nil?
137
+ errors.add_to_base("Authentication failed. Please try again.")
138
+ return false
139
+ end
140
+ rpx_id = @rpx_data['profile']['identifier']
141
+ if rpx_id.blank?
142
+ errors.add_to_base("Authentication failed. Please try again.")
143
+ return false
144
+ end
145
+
146
+ self.attempted_record = klass.send(find_by_rpx_identifier_method, rpx_id)
147
+
148
+ # so what do we do if we can't find an existing user matching the RPX authentication..
149
+ if !attempted_record
150
+ if auto_register?
151
+ self.attempted_record = klass.new( :rpx_identifier=> rpx_id )
152
+ map_rpx_data
153
+ # save the new user record - without session maintenance else we get caught in a self-referential hell,
154
+ # since both session and user objects invoke each other upon save
155
+ self.new_registration=true
156
+ self.attempted_record.save_without_session_maintenance
157
+ else
158
+ errors.add_to_base("We did not find any accounts with that login. Enter your details and create an account.")
159
+ return false
160
+ end
161
+ end
162
+
163
+ end
164
+
165
+ # map_rpx_data maps additional fields from the RPX response into the user object
166
+ # override this in your session controller to change the field mapping
167
+ # see https://rpxnow.com/docs#profile_data for the definition of available attributes
168
+ #
169
+ def map_rpx_data
170
+ self.attempted_record.send("#{klass.login_field}=", @rpx_data['profile']['preferredUsername'] ) if attempted_record.send(klass.login_field).blank?
171
+ self.attempted_record.send("#{klass.email_field}=", @rpx_data['profile']['email'] ) if attempted_record.send(klass.email_field).blank?
172
+ end
173
+
174
+ end
175
+
176
+ end
177
+ end
@@ -0,0 +1,51 @@
1
+ module AuthlogicRpx
2
+ # A class for describing the current version of a library. The version
3
+ # consists of three parts: the +major+ number, the +minor+ number, and the
4
+ # +tiny+ (or +patch+) number.
5
+ class Version
6
+ include Comparable
7
+
8
+ # A convenience method for instantiating a new Version instance with the
9
+ # given +major+, +minor+, and +tiny+ components.
10
+ def self.[](major, minor, tiny)
11
+ new(major, minor, tiny)
12
+ end
13
+
14
+ attr_reader :major, :minor, :tiny
15
+
16
+ # Create a new Version object with the given components.
17
+ def initialize(major, minor, tiny)
18
+ @major, @minor, @tiny = major, minor, tiny
19
+ end
20
+
21
+ # Compare this version to the given +version+ object.
22
+ def <=>(version)
23
+ to_i <=> version.to_i
24
+ end
25
+
26
+ # Converts this version object to a string, where each of the three
27
+ # version components are joined by the '.' character. E.g., 2.0.0.
28
+ def to_s
29
+ @to_s ||= [@major, @minor, @tiny].join(".")
30
+ end
31
+
32
+ # Converts this version to a canonical integer that may be compared
33
+ # against other version objects.
34
+ def to_i
35
+ @to_i ||= @major * 1_000_000 + @minor * 1_000 + @tiny
36
+ end
37
+
38
+ def to_a
39
+ [@major, @minor, @tiny]
40
+ end
41
+
42
+ MAJOR = 1
43
+ MINOR = 0
44
+ TINY = 2
45
+
46
+ # The current version as a Version instance
47
+ CURRENT = new(MAJOR, MINOR, TINY)
48
+ # The current version as a String
49
+ STRING = CURRENT.to_s
50
+ end
51
+ end
data/rails/init.rb ADDED
@@ -0,0 +1 @@
1
+ require "authlogic_rpx"
@@ -0,0 +1,5 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class ActsAsAuthenticTest < ActiveSupport::TestCase
4
+
5
+ end
File without changes
@@ -0,0 +1,41 @@
1
+ # The only reason I am doing all of this non sense is becuase the openid_authentication requires that
2
+ # these constants be present. The only other alternative is to use an entire rails application for testing
3
+ # which is a little too overboard for this, I think.
4
+
5
+ RAILS_ROOT = ''
6
+
7
+ class ActionController < Authlogic::TestCase::MockController
8
+ class Request < Authlogic::TestCase::MockRequest
9
+ def request_method
10
+ ""
11
+ end
12
+ end
13
+
14
+ def root_url
15
+ ''
16
+ end
17
+
18
+ def request
19
+ return @request if defined?(@request)
20
+ super
21
+ # Rails does some crazy s#!t with the "method" method. If I don't do this I get a "wrong arguments (0 for 1) error"
22
+ @request.class.class_eval do
23
+ def method
24
+ nil
25
+ end
26
+ end
27
+ @request
28
+ end
29
+
30
+ def url_for(*args)
31
+ ''
32
+ end
33
+
34
+ def redirecting_to
35
+ @redirect_to
36
+ end
37
+
38
+ def redirect_to(*args)
39
+ @redirect_to = args
40
+ end
41
+ end
data/test/libs/user.rb ADDED
@@ -0,0 +1,3 @@
1
+ class User < ActiveRecord::Base
2
+ acts_as_authentic
3
+ end
@@ -0,0 +1,2 @@
1
+ class UserSession < Authlogic::Session::Base
2
+ end
@@ -0,0 +1,5 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class SessionTest < ActiveSupport::TestCase
4
+
5
+ end
@@ -0,0 +1,61 @@
1
+ require "test/unit"
2
+ require "rubygems"
3
+ require "ruby-debug"
4
+ require "active_record"
5
+
6
+ ActiveRecord::Schema.verbose = false
7
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :dbfile => ":memory:")
8
+ ActiveRecord::Base.configurations = true
9
+ ActiveRecord::Schema.define(:version => 1) do
10
+
11
+ create_table :users do |t|
12
+ t.datetime :created_at
13
+ t.datetime :updated_at
14
+ t.integer :lock_version, :default => 0
15
+ t.string :login
16
+ t.string :crypted_password
17
+ t.string :password_salt
18
+ t.string :persistence_token
19
+ t.string :single_access_token
20
+ t.string :perishable_token
21
+ t.string :rpx_identifier
22
+ t.string :email
23
+ t.string :first_name
24
+ t.string :last_name
25
+ t.integer :login_count, :default => 0, :null => false
26
+ t.integer :failed_login_count, :default => 0, :null => false
27
+ t.datetime :last_request_at
28
+ t.datetime :current_login_at
29
+ t.datetime :last_login_at
30
+ t.string :current_login_ip
31
+ t.string :last_login_ip
32
+ end
33
+ end
34
+
35
+ require "active_record/fixtures"
36
+ require "openid"
37
+ require File.dirname(__FILE__) + "/../../authlogic/lib/authlogic"
38
+ require File.dirname(__FILE__) + "/../../authlogic/lib/authlogic/test_case"
39
+ require File.dirname(__FILE__) + "/libs/rails_trickery"
40
+ require File.dirname(__FILE__) + '/libs/user'
41
+ require File.dirname(__FILE__) + '/libs/user_session'
42
+
43
+ class ActiveSupport::TestCase
44
+ include ActiveRecord::TestFixtures
45
+ self.fixture_path = File.dirname(__FILE__) + "/fixtures"
46
+ self.use_transactional_fixtures = false
47
+ self.use_instantiated_fixtures = false
48
+ self.pre_loaded_fixtures = false
49
+ fixtures :all
50
+ setup :activate_authlogic
51
+
52
+ private
53
+ def activate_authlogic
54
+ Authlogic::Session::Base.controller = controller
55
+ end
56
+
57
+ def controller
58
+ @controller ||= Authlogic::TestCase::ControllerAdapter.new(ActionController.new)
59
+ end
60
+
61
+ end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: authlogic_rpx
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Paul Gallagher / tardate
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-02 00:00:00 +08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: authlogic
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 2.1.1
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: grosser-rpx_now
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.5.10
34
+ version:
35
+ description: Authlogic extension/plugin that provides RPX (rpxnow.com) authentication support
36
+ email: gallagher.paul@gmail.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - CHANGELOG.rdoc
43
+ - README.rdoc
44
+ - lib/authlogic_rpx.rb
45
+ - lib/authlogic_rpx/acts_as_authentic.rb
46
+ - lib/authlogic_rpx/helper.rb
47
+ - lib/authlogic_rpx/session.rb
48
+ - lib/authlogic_rpx/version.rb
49
+ files:
50
+ - CHANGELOG.rdoc
51
+ - MIT-LICENSE
52
+ - Manifest
53
+ - README.rdoc
54
+ - Rakefile
55
+ - authlogic_rpx.gemspec
56
+ - init.rb
57
+ - lib/authlogic_rpx.rb
58
+ - lib/authlogic_rpx/acts_as_authentic.rb
59
+ - lib/authlogic_rpx/helper.rb
60
+ - lib/authlogic_rpx/session.rb
61
+ - lib/authlogic_rpx/version.rb
62
+ - rails/init.rb
63
+ - test/acts_as_authentic_test.rb
64
+ - test/fixtures/users.yml
65
+ - test/libs/rails_trickery.rb
66
+ - test/libs/user.rb
67
+ - test/libs/user_session.rb
68
+ - test/session_test.rb
69
+ - test/test_helper.rb
70
+ has_rdoc: true
71
+ homepage: http://github.com/tardate/authlogic_rpx
72
+ licenses: []
73
+
74
+ post_install_message:
75
+ rdoc_options:
76
+ - --line-numbers
77
+ - --inline-source
78
+ - --title
79
+ - Authlogic_rpx
80
+ - --main
81
+ - README.rdoc
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: "0"
89
+ version:
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: "1.2"
95
+ version:
96
+ requirements: []
97
+
98
+ rubyforge_project: authlogic_rpx
99
+ rubygems_version: 1.3.5
100
+ signing_key:
101
+ specification_version: 3
102
+ summary: Authlogic plug-in for RPX support
103
+ test_files:
104
+ - test/acts_as_authentic_test.rb
105
+ - test/session_test.rb
106
+ - test/test_helper.rb