tfe-authlogic_openid 0.1.0

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.
Files changed (39) hide show
  1. data/CHANGELOG.rdoc +25 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Manifest.txt +38 -0
  4. data/README.rdoc +93 -0
  5. data/Rakefile +137 -0
  6. data/init.rb +1 -0
  7. data/lib/authlogic_openid.rb +6 -0
  8. data/lib/authlogic_openid/acts_as_authentic.rb +174 -0
  9. data/lib/authlogic_openid/session.rb +125 -0
  10. data/lib/authlogic_openid/version.rb +51 -0
  11. data/test/acts_as_authentic_test.rb +105 -0
  12. data/test/fixtures/users.yml +9 -0
  13. data/test/libs/open_id_authentication/CHANGELOG +35 -0
  14. data/test/libs/open_id_authentication/README +231 -0
  15. data/test/libs/open_id_authentication/Rakefile +22 -0
  16. data/test/libs/open_id_authentication/generators/open_id_authentication_tables/open_id_authentication_tables_generator.rb +11 -0
  17. data/test/libs/open_id_authentication/generators/open_id_authentication_tables/templates/migration.rb +20 -0
  18. data/test/libs/open_id_authentication/generators/upgrade_open_id_authentication_tables/templates/migration.rb +26 -0
  19. data/test/libs/open_id_authentication/generators/upgrade_open_id_authentication_tables/upgrade_open_id_authentication_tables_generator.rb +11 -0
  20. data/test/libs/open_id_authentication/init.rb +18 -0
  21. data/test/libs/open_id_authentication/lib/open_id_authentication.rb +244 -0
  22. data/test/libs/open_id_authentication/lib/open_id_authentication/association.rb +9 -0
  23. data/test/libs/open_id_authentication/lib/open_id_authentication/db_store.rb +55 -0
  24. data/test/libs/open_id_authentication/lib/open_id_authentication/mem_cache_store.rb +73 -0
  25. data/test/libs/open_id_authentication/lib/open_id_authentication/nonce.rb +5 -0
  26. data/test/libs/open_id_authentication/lib/open_id_authentication/request.rb +23 -0
  27. data/test/libs/open_id_authentication/lib/open_id_authentication/timeout_fixes.rb +20 -0
  28. data/test/libs/open_id_authentication/tasks/open_id_authentication_tasks.rake +30 -0
  29. data/test/libs/open_id_authentication/test/mem_cache_store_test.rb +151 -0
  30. data/test/libs/open_id_authentication/test/normalize_test.rb +32 -0
  31. data/test/libs/open_id_authentication/test/open_id_authentication_test.rb +46 -0
  32. data/test/libs/open_id_authentication/test/status_test.rb +14 -0
  33. data/test/libs/open_id_authentication/test/test_helper.rb +17 -0
  34. data/test/libs/rails_trickery.rb +41 -0
  35. data/test/libs/user.rb +3 -0
  36. data/test/libs/user_session.rb +2 -0
  37. data/test/session_test.rb +32 -0
  38. data/test/test_helper.rb +78 -0
  39. metadata +107 -0
@@ -0,0 +1,125 @@
1
+ module AuthlogicOpenid
2
+ # This module is responsible for adding all of the OpenID goodness to the Authlogic::Session::Base class.
3
+ module Session
4
+ # Add a simple openid_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
+ # What method should we call to find a record by the openid_identifier?
14
+ # This is useful if you want to store multiple openid_identifiers for a single record.
15
+ # You could do something like:
16
+ #
17
+ # class User < ActiveRecord::Base
18
+ # def self.find_by_openid_identifier(identifier)
19
+ # user.first(:conditions => {:openid_identifiers => {:identifier => identifier}})
20
+ # end
21
+ # end
22
+ #
23
+ # Obviously the above depends on what you are calling your assocition, etc. But you get the point.
24
+ #
25
+ # * <tt>Default:</tt> :find_by_openid_identifier
26
+ # * <tt>Accepts:</tt> Symbol
27
+ def find_by_openid_identifier_method(value = nil)
28
+ rw_config(:find_by_openid_identifier_method, value, :find_by_openid_identifier)
29
+ end
30
+ alias_method :find_by_openid_identifier_method=, :find_by_openid_identifier_method
31
+
32
+ # Add this in your Session object to Auto Register a new user using openid via sreg
33
+ def auto_register(value=true)
34
+ auto_register_value(value)
35
+ end
36
+
37
+ def auto_register_value(value=nil)
38
+ rw_config(:auto_register,value,false)
39
+ end
40
+
41
+ alias_method :auto_register=,:auto_register
42
+ end
43
+
44
+ module Methods
45
+ def self.included(klass)
46
+ klass.class_eval do
47
+ attr_reader :openid_identifier
48
+ validate :validate_openid_error
49
+ validate :validate_by_openid, :if => :authenticating_with_openid?
50
+ end
51
+ end
52
+
53
+ # Hooks into credentials so that you can pass an :openid_identifier key.
54
+ def credentials=(value)
55
+ super
56
+ values = value.is_a?(Array) ? value : [value]
57
+ hash = values.first.is_a?(Hash) ? values.first.with_indifferent_access : nil
58
+ self.openid_identifier = hash[:openid_identifier] if !hash.nil? && hash.key?(:openid_identifier)
59
+ end
60
+
61
+ def openid_identifier=(value)
62
+ @openid_identifier = value.blank? ? nil : OpenIdAuthentication.normalize_identifier(value)
63
+ @openid_error = nil
64
+ rescue OpenIdAuthentication::InvalidOpenId => e
65
+ @openid_identifier = nil
66
+ @openid_error = e.message
67
+ end
68
+
69
+ # Cleaers out the block if we are authenticating with OpenID, so that we can redirect without a DoubleRender
70
+ # error.
71
+ def save(&block)
72
+ block = nil if !openid_identifier.blank?
73
+ super(&block)
74
+ end
75
+
76
+ private
77
+ def authenticating_with_openid?
78
+ attempted_record.nil? && errors.empty? && (!openid_identifier.blank? || (controller.params[:open_id_complete] && controller.params[:for_session]))
79
+ end
80
+
81
+ def find_by_openid_identifier_method
82
+ self.class.find_by_openid_identifier_method
83
+ end
84
+
85
+ def find_by_openid_identifier_method
86
+ self.class.find_by_openid_identifier_method
87
+ end
88
+
89
+ def auto_register?
90
+ self.class.auto_register_value
91
+ end
92
+
93
+ def validate_by_openid
94
+ self.remember_me = controller.params[:remember_me] == "true" if controller.params.key?(:remember_me)
95
+ self.attempted_record = klass.send(find_by_openid_identifier_method, openid_identifier)
96
+ if !attempted_record
97
+ if auto_register?
98
+ self.attempted_record = klass.new :openid_identifier=>openid_identifier
99
+ attempted_record.save do |result|
100
+ if result
101
+ true
102
+ else
103
+ false
104
+ end
105
+ end
106
+ else
107
+ errors.add(:openid_identifier, "did not match any users in our database, have you set up your account to use OpenID?")
108
+ end
109
+ return
110
+ end
111
+ controller.send(:authenticate_with_open_id, openid_identifier, :return_to => controller.url_for(:for_session => "1", :remember_me => remember_me?)) do |result, openid_identifier|
112
+ if result.unsuccessful?
113
+ errors.add_to_base(result.message)
114
+ return
115
+ end
116
+
117
+ end
118
+ end
119
+
120
+ def validate_openid_error
121
+ errors.add(:openid_identifier, @openid_error) if @openid_error
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,51 @@
1
+ module AuthlogicOpenid
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 = 5
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
@@ -0,0 +1,105 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class ActsAsAuthenticTest < ActiveSupport::TestCase
4
+ def test_included
5
+ assert User.send(:acts_as_authentic_modules).include?(AuthlogicOpenid::ActsAsAuthentic::Methods)
6
+ assert_equal :validate_password_with_openid?, User.validates_length_of_password_field_options[:if]
7
+ assert_equal :validate_password_with_openid?, User.validates_confirmation_of_password_field_options[:if]
8
+ assert_equal :validate_password_with_openid?, User.validates_length_of_password_confirmation_field_options[:if]
9
+ end
10
+
11
+ def test_password_not_required_on_create
12
+ user = User.new
13
+ user.login = "sweet"
14
+ user.email = "a@a.com"
15
+ user.openid_identifier = "https://me.yahoo.com/a/9W0FJjRj0o981TMSs0vqVxPdmMUVOQ--"
16
+ assert !user.save {} # because we are redirecting, the user was NOT saved
17
+ assert redirecting_to_yahoo?
18
+ end
19
+
20
+ def test_password_required_on_create
21
+ user = User.new
22
+ user.login = "sweet"
23
+ user.email = "a@a.com"
24
+ assert !user.save
25
+ assert user.errors.on(:password)
26
+ assert user.errors.on(:password_confirmation)
27
+ end
28
+
29
+ def test_password_not_required_on_update
30
+ ben = users(:ben)
31
+ assert_nil ben.crypted_password
32
+ assert ben.save
33
+ end
34
+
35
+ def test_password_required_on_update
36
+ ben = users(:ben)
37
+ ben.openid_identifier = nil
38
+ assert_nil ben.crypted_password
39
+ assert !ben.save
40
+ assert ben.errors.on(:password)
41
+ assert ben.errors.on(:password_confirmation)
42
+ end
43
+
44
+ def test_validates_uniqueness_of_openid_identifier
45
+ u = User.new(:openid_identifier => "bens_identifier")
46
+ assert !u.valid?
47
+ assert u.errors.on(:openid_identifier)
48
+ end
49
+
50
+ def test_setting_openid_identifier_changed_persistence_token
51
+ ben = users(:ben)
52
+ old_persistence_token = ben.persistence_token
53
+ ben.openid_identifier = "new"
54
+ assert_not_equal old_persistence_token, ben.persistence_token
55
+ end
56
+
57
+ def test_invalid_openid_identifier
58
+ u = User.new(:openid_identifier => "%")
59
+ assert !u.valid?
60
+ assert u.errors.on(:openid_identifier)
61
+ end
62
+
63
+ def test_blank_openid_identifer_gets_set_to_nil
64
+ u = User.new(:openid_identifier => "")
65
+ assert_nil u.openid_identifier
66
+ end
67
+
68
+ def test_updating_with_openid
69
+ ben = users(:ben)
70
+ ben.openid_identifier = "https://me.yahoo.com/a/9W0FJjRj0o981TMSs0vqVxPdmMUVOQ--"
71
+ assert !ben.save {} # because we are redirecting
72
+ assert redirecting_to_yahoo?
73
+ end
74
+
75
+ def test_updating_without_openid
76
+ ben = users(:ben)
77
+ ben.openid_identifier = nil
78
+ ben.password = "test"
79
+ ben.password_confirmation = "test"
80
+ assert ben.save
81
+ assert !redirecting_to_yahoo?
82
+ end
83
+
84
+ def test_updating_without_validation
85
+ ben = users(:ben)
86
+ ben.openid_identifier = "https://me.yahoo.com/a/9W0FJjRj0o981TMSs0vqVxPdmMUVOQ--"
87
+ assert ben.save(false)
88
+ assert !redirecting_to_yahoo?
89
+ end
90
+
91
+ def test_updating_without_a_block
92
+ ben = users(:ben)
93
+ ben.openid_identifier = "https://me.yahoo.com/a/9W0FJjRj0o981TMSs0vqVxPdmMUVOQ--"
94
+ assert ben.save
95
+ ben.reload
96
+ assert_equal "https://me.yahoo.com/a/9W0FJjRj0o981TMSs0vqVxPdmMUVOQ--", ben.openid_identifier
97
+ end
98
+
99
+ def test_updating_while_not_activated
100
+ UserSession.controller = nil
101
+ ben = users(:ben)
102
+ ben.openid_identifier = "https://me.yahoo.com/a/9W0FJjRj0o981TMSs0vqVxPdmMUVOQ--"
103
+ assert ben.save {}
104
+ end
105
+ end
@@ -0,0 +1,9 @@
1
+ ben:
2
+ login: bjohnson
3
+ persistence_token: 6cde0674657a8a313ce952df979de2830309aa4c11ca65805dd00bfdc65dbcc2f5e36718660a1d2e68c1a08c276d996763985d2f06fd3d076eb7bc4d97b1e317
4
+ single_access_token: <%= Authlogic::Random.friendly_token %>
5
+ perishable_token: <%= Authlogic::Random.friendly_token %>
6
+ openid_identifier: bens_identifier
7
+ email: bjohnson@binarylogic.com
8
+ first_name: Ben
9
+ last_name: Johnson
@@ -0,0 +1,35 @@
1
+ * Fake HTTP method from OpenID server since they only support a GET. Eliminates the need to set an extra route to match the server's reply. [Josh Peek]
2
+
3
+ * OpenID 2.0 recommends that forms should use the field name "openid_identifier" rather than "openid_url" [Josh Peek]
4
+
5
+ * Return open_id_response.display_identifier to the application instead of .endpoints.claimed_id. [nbibler]
6
+
7
+ * Add Timeout protection [Rick]
8
+
9
+ * An invalid identity url passed through authenticate_with_open_id will no longer raise an InvalidOpenId exception. Instead it will return Result[:missing] to the completion block.
10
+
11
+ * Allow a return_to option to be used instead of the requested url [Josh Peek]
12
+
13
+ * Updated plugin to use Ruby OpenID 2.x.x [Josh Peek]
14
+
15
+ * Tied plugin to ruby-openid 1.1.4 gem until we can make it compatible with 2.x [DHH]
16
+
17
+ * Use URI instead of regexps to normalize the URL and gain free, better matching #8136 [dkubb]
18
+
19
+ * Allow -'s in #normalize_url [Rick]
20
+
21
+ * remove instance of mattr_accessor, it was breaking tests since they don't load ActiveSupport. Fix Timeout test [Rick]
22
+
23
+ * Throw a InvalidOpenId exception instead of just a RuntimeError when the URL can't be normalized [DHH]
24
+
25
+ * Just use the path for the return URL, so extra query parameters don't interfere [DHH]
26
+
27
+ * Added a new default database-backed store after experiencing trouble with the filestore on NFS. The file store is still available as an option [DHH]
28
+
29
+ * Added normalize_url and applied it to all operations going through the plugin [DHH]
30
+
31
+ * Removed open_id? as the idea of using the same input box for both OpenID and username has died -- use using_open_id? instead (which checks for the presence of params[:openid_url] by default) [DHH]
32
+
33
+ * Added OpenIdAuthentication::Result to make it easier to deal with default situations where you don't care to do something particular for each error state [DHH]
34
+
35
+ * Stop relying on root_url being defined, we can just grab the current url instead [DHH]
@@ -0,0 +1,231 @@
1
+ OpenIdAuthentication
2
+ ====================
3
+
4
+ Provides a thin wrapper around the excellent ruby-openid gem from JanRan. Be sure to install that first:
5
+
6
+ gem install ruby-openid
7
+
8
+ To understand what OpenID is about and how it works, it helps to read the documentation for lib/openid/consumer.rb
9
+ from that gem.
10
+
11
+ The specification used is http://openid.net/specs/openid-authentication-2_0.html.
12
+
13
+
14
+ Prerequisites
15
+ =============
16
+
17
+ OpenID authentication uses the session, so be sure that you haven't turned that off. It also relies on a number of
18
+ database tables to store the authentication keys. So you'll have to run the migration to create these before you get started:
19
+
20
+ rake open_id_authentication:db:create
21
+
22
+ Or, use the included generators to install or upgrade:
23
+
24
+ ./script/generate open_id_authentication_tables MigrationName
25
+ ./script/generate upgrade_open_id_authentication_tables MigrationName
26
+
27
+ Alternatively, you can use the file-based store, which just relies on on tmp/openids being present in RAILS_ROOT. But be aware that this store only works if you have a single application server. And it's not safe to use across NFS. It's recommended that you use the database store if at all possible. To use the file-based store, you'll also have to add this line to your config/environment.rb:
28
+
29
+ OpenIdAuthentication.store = :file
30
+
31
+ This particular plugin also relies on the fact that the authentication action allows for both POST and GET operations.
32
+ If you're using RESTful authentication, you'll need to explicitly allow for this in your routes.rb.
33
+
34
+ The plugin also expects to find a root_url method that points to the home page of your site. You can accomplish this by using a root route in config/routes.rb:
35
+
36
+ map.root :controller => 'articles'
37
+
38
+ This plugin relies on Rails Edge revision 6317 or newer.
39
+
40
+
41
+ Example
42
+ =======
43
+
44
+ This example is just to meant to demonstrate how you could use OpenID authentication. You might well want to add
45
+ salted hash logins instead of plain text passwords and other requirements on top of this. Treat it as a starting point,
46
+ not a destination.
47
+
48
+ Note that the User model referenced in the simple example below has an 'identity_url' attribute. You will want to add the same or similar field to whatever
49
+ model you are using for authentication.
50
+
51
+ Also of note is the following code block used in the example below:
52
+
53
+ authenticate_with_open_id do |result, identity_url|
54
+ ...
55
+ end
56
+
57
+ In the above code block, 'identity_url' will need to match user.identity_url exactly. 'identity_url' will be a string in the form of 'http://example.com' -
58
+ If you are storing just 'example.com' with your user, the lookup will fail.
59
+
60
+ There is a handy method in this plugin called 'normalize_url' that will help with validating OpenID URLs.
61
+
62
+ OpenIdAuthentication.normalize_url(user.identity_url)
63
+
64
+ The above will return a standardized version of the OpenID URL - the above called with 'example.com' will return 'http://example.com/'
65
+ It will also raise an InvalidOpenId exception if the URL is determined to not be valid.
66
+ Use the above code in your User model and validate OpenID URLs before saving them.
67
+
68
+ config/routes.rb
69
+
70
+ map.root :controller => 'articles'
71
+ map.resource :session
72
+
73
+
74
+ app/views/sessions/new.erb
75
+
76
+ <% form_tag(session_url) do %>
77
+ <p>
78
+ <label for="name">Username:</label>
79
+ <%= text_field_tag "name" %>
80
+ </p>
81
+
82
+ <p>
83
+ <label for="password">Password:</label>
84
+ <%= password_field_tag %>
85
+ </p>
86
+
87
+ <p>
88
+ ...or use:
89
+ </p>
90
+
91
+ <p>
92
+ <label for="openid_identifier">OpenID:</label>
93
+ <%= text_field_tag "openid_identifier" %>
94
+ </p>
95
+
96
+ <p>
97
+ <%= submit_tag 'Sign in', :disable_with => "Signing in&hellip;" %>
98
+ </p>
99
+ <% end %>
100
+
101
+ app/controllers/sessions_controller.rb
102
+ class SessionsController < ApplicationController
103
+ def create
104
+ if using_open_id?
105
+ open_id_authentication
106
+ else
107
+ password_authentication(params[:name], params[:password])
108
+ end
109
+ end
110
+
111
+
112
+ protected
113
+ def password_authentication(name, password)
114
+ if @current_user = @account.users.authenticate(params[:name], params[:password])
115
+ successful_login
116
+ else
117
+ failed_login "Sorry, that username/password doesn't work"
118
+ end
119
+ end
120
+
121
+ def open_id_authentication
122
+ authenticate_with_open_id do |result, identity_url|
123
+ if result.successful?
124
+ if @current_user = @account.users.find_by_identity_url(identity_url)
125
+ successful_login
126
+ else
127
+ failed_login "Sorry, no user by that identity URL exists (#{identity_url})"
128
+ end
129
+ else
130
+ failed_login result.message
131
+ end
132
+ end
133
+ end
134
+
135
+
136
+ private
137
+ def successful_login
138
+ session[:user_id] = @current_user.id
139
+ redirect_to(root_url)
140
+ end
141
+
142
+ def failed_login(message)
143
+ flash[:error] = message
144
+ redirect_to(new_session_url)
145
+ end
146
+ end
147
+
148
+
149
+
150
+ If you're fine with the result messages above and don't need individual logic on a per-failure basis,
151
+ you can collapse the case into a mere boolean:
152
+
153
+ def open_id_authentication
154
+ authenticate_with_open_id do |result, identity_url|
155
+ if result.successful? && @current_user = @account.users.find_by_identity_url(identity_url)
156
+ successful_login
157
+ else
158
+ failed_login(result.message || "Sorry, no user by that identity URL exists (#{identity_url})")
159
+ end
160
+ end
161
+ end
162
+
163
+
164
+ Simple Registration OpenID Extension
165
+ ====================================
166
+
167
+ Some OpenID Providers support this lightweight profile exchange protocol. See more: http://www.openidenabled.com/openid/simple-registration-extension
168
+
169
+ You can support it in your app by changing #open_id_authentication
170
+
171
+ def open_id_authentication(identity_url)
172
+ # Pass optional :required and :optional keys to specify what sreg fields you want.
173
+ # Be sure to yield registration, a third argument in the #authenticate_with_open_id block.
174
+ authenticate_with_open_id(identity_url,
175
+ :required => [ :nickname, :email ],
176
+ :optional => :fullname) do |result, identity_url, registration|
177
+ case result.status
178
+ when :missing
179
+ failed_login "Sorry, the OpenID server couldn't be found"
180
+ when :invalid
181
+ failed_login "Sorry, but this does not appear to be a valid OpenID"
182
+ when :canceled
183
+ failed_login "OpenID verification was canceled"
184
+ when :failed
185
+ failed_login "Sorry, the OpenID verification failed"
186
+ when :successful
187
+ if @current_user = @account.users.find_by_identity_url(identity_url)
188
+ assign_registration_attributes!(registration)
189
+
190
+ if current_user.save
191
+ successful_login
192
+ else
193
+ failed_login "Your OpenID profile registration failed: " +
194
+ @current_user.errors.full_messages.to_sentence
195
+ end
196
+ else
197
+ failed_login "Sorry, no user by that identity URL exists"
198
+ end
199
+ end
200
+ end
201
+ end
202
+
203
+ # registration is a hash containing the valid sreg keys given above
204
+ # use this to map them to fields of your user model
205
+ def assign_registration_attributes!(registration)
206
+ model_to_registration_mapping.each do |model_attribute, registration_attribute|
207
+ unless registration[registration_attribute].blank?
208
+ @current_user.send("#{model_attribute}=", registration[registration_attribute])
209
+ end
210
+ end
211
+ end
212
+
213
+ def model_to_registration_mapping
214
+ { :login => 'nickname', :email => 'email', :display_name => 'fullname' }
215
+ end
216
+
217
+ Attribute Exchange OpenID Extension
218
+ ===================================
219
+
220
+ Some OpenID providers also support the OpenID AX (attribute exchange) protocol for exchanging identity information between endpoints. See more: http://openid.net/specs/openid-attribute-exchange-1_0.html
221
+
222
+ Accessing AX data is very similar to the Simple Registration process, described above -- just add the URI identifier for the AX field to your :optional or :required parameters. For example:
223
+
224
+ authenticate_with_open_id(identity_url,
225
+ :required => [ :email, 'http://schema.openid.net/birthDate' ]) do |result, identity_url, registration|
226
+
227
+ This would provide the sreg data for :email, and the AX data for 'http://schema.openid.net/birthDate'
228
+
229
+
230
+
231
+ Copyright (c) 2007 David Heinemeier Hansson, released under the MIT license