authlogic-oid 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/CHANGELOG.rdoc +3 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Manifest.txt +38 -0
  4. data/README.rdoc +87 -0
  5. data/Rakefile +20 -0
  6. data/init.rb +1 -0
  7. data/lib/authlogic_openid/acts_as_authentic.rb +117 -0
  8. data/lib/authlogic_openid/session.rb +61 -0
  9. data/lib/authlogic_openid/version.rb +51 -0
  10. data/lib/authlogic_openid.rb +6 -0
  11. data/test/acts_as_authentic_test.rb +90 -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/association.rb +9 -0
  22. data/test/libs/open_id_authentication/lib/open_id_authentication/db_store.rb +55 -0
  23. data/test/libs/open_id_authentication/lib/open_id_authentication/mem_cache_store.rb +73 -0
  24. data/test/libs/open_id_authentication/lib/open_id_authentication/nonce.rb +5 -0
  25. data/test/libs/open_id_authentication/lib/open_id_authentication/request.rb +23 -0
  26. data/test/libs/open_id_authentication/lib/open_id_authentication/timeout_fixes.rb +20 -0
  27. data/test/libs/open_id_authentication/lib/open_id_authentication.rb +244 -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 +113 -0
data/CHANGELOG.rdoc ADDED
@@ -0,0 +1,3 @@
1
+ == 1.0.0
2
+
3
+ * Initial release
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Ben Johnson of Binary Logic (binarylogic.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.txt ADDED
@@ -0,0 +1,38 @@
1
+ CHANGELOG.rdoc
2
+ MIT-LICENSE
3
+ Manifest.txt
4
+ README.rdoc
5
+ Rakefile
6
+ init.rb
7
+ lib/authlogic_openid.rb
8
+ lib/authlogic_openid/acts_as_authentic.rb
9
+ lib/authlogic_openid/session.rb
10
+ lib/authlogic_openid/version.rb
11
+ test/acts_as_authentic_test.rb
12
+ test/fixtures/users.yml
13
+ test/libs/open_id_authentication/CHANGELOG
14
+ test/libs/open_id_authentication/README
15
+ test/libs/open_id_authentication/Rakefile
16
+ test/libs/open_id_authentication/generators/open_id_authentication_tables/open_id_authentication_tables_generator.rb
17
+ test/libs/open_id_authentication/generators/open_id_authentication_tables/templates/migration.rb
18
+ test/libs/open_id_authentication/generators/upgrade_open_id_authentication_tables/templates/migration.rb
19
+ test/libs/open_id_authentication/generators/upgrade_open_id_authentication_tables/upgrade_open_id_authentication_tables_generator.rb
20
+ test/libs/open_id_authentication/init.rb
21
+ test/libs/open_id_authentication/lib/open_id_authentication.rb
22
+ test/libs/open_id_authentication/lib/open_id_authentication/association.rb
23
+ test/libs/open_id_authentication/lib/open_id_authentication/db_store.rb
24
+ test/libs/open_id_authentication/lib/open_id_authentication/mem_cache_store.rb
25
+ test/libs/open_id_authentication/lib/open_id_authentication/nonce.rb
26
+ test/libs/open_id_authentication/lib/open_id_authentication/request.rb
27
+ test/libs/open_id_authentication/lib/open_id_authentication/timeout_fixes.rb
28
+ test/libs/open_id_authentication/tasks/open_id_authentication_tasks.rake
29
+ test/libs/open_id_authentication/test/mem_cache_store_test.rb
30
+ test/libs/open_id_authentication/test/normalize_test.rb
31
+ test/libs/open_id_authentication/test/open_id_authentication_test.rb
32
+ test/libs/open_id_authentication/test/status_test.rb
33
+ test/libs/open_id_authentication/test/test_helper.rb
34
+ test/libs/rails_trickery.rb
35
+ test/libs/user.rb
36
+ test/libs/user_session.rb
37
+ test/session_test.rb
38
+ test/test_helper.rb
data/README.rdoc ADDED
@@ -0,0 +1,87 @@
1
+ = Authlogic OpenID
2
+
3
+ Authlogic OpenID is an extension of the Authlogic library to add OpenID support. Authlogic v2.0 introduced an enhanced API that makes "plugging in" alternate authentication methods as easy as installing a gem.
4
+
5
+ == Install and use
6
+
7
+ === 1. Make some simple changes to your database:
8
+
9
+ class AddUsersOpenidField < ActiveRecord::Migration
10
+ def self.up
11
+ add_column :users, :openid_identifier, :string
12
+ add_index :users, :openid_identifier
13
+
14
+ change_column :users, :login, :string, :default => nil, :null => true
15
+ change_column :users, :crypted_password, :string, :default => nil, :null => true
16
+ change_column :users, :password_salt, :string, :default => nil, :null => true
17
+ end
18
+
19
+ def self.down
20
+ remove_column :users, :openid_identifier
21
+
22
+ [:login, :crypted_password, :password_salt].each do |field|
23
+ User.all(:conditions => "#{field} is NULL").each { |user| user.update_attribute(field, "") if user.send(field).nil? }
24
+ change_column :users, field, :string, :default => "", :null => false
25
+ end
26
+ end
27
+ end
28
+
29
+ === 2. Install the openid_authentication plugin
30
+
31
+ $ script/plugin install git://github.com/rails/open_id_authentication.git
32
+ $ rake open_id_authentication:db:create
33
+
34
+ For more information on how to configure the plugin, checkout it's README: http://github.com/rails/open_id_authentication/tree/master
35
+
36
+ === 3. Install the Authlogic Openid gem
37
+
38
+ $ sudo gem install authlogic-oid
39
+
40
+ Now add the gem dependency in your config:
41
+
42
+ config.gem "authlogic-oid", :lib => "authlogic_openid"
43
+
44
+ Or for older version of rails, install it as a plugin:
45
+
46
+ $ script/plugin install git://github.com/binarylogic/authlogic_openid.git
47
+
48
+ === 4. Make sure you save your objects properly
49
+
50
+ You only need to save your objects this way if you want the user to authenticate with their OpenID provider.
51
+
52
+ That being said, you probably want to do this in your controllers. You should do this for BOTH your User objects and UserSession objects (assuming you are authenticating users). It should look something like this:
53
+
54
+ @user_session.save do |result|
55
+ if result
56
+ flash[:notice] = "Login successful!"
57
+ redirect_back_or_default account_url
58
+ else
59
+ render :action => :new
60
+ end
61
+ end
62
+
63
+ You should save your @user objects this way as well, because you also want the user to verify that they own the OpenID identifier that they supplied.
64
+
65
+ Notice we are saving with a block. Why? Because we need to redirect the user to their OpenID provider so that they can authenticate. When we do this, we don't want to execute that block of code, because if we do, we will get a DoubleRender error. This lets us skip that entire block and send the user along their way without any problems.
66
+
67
+ That's it! The rest is taken care of for you.
68
+
69
+ == Redirecting from the models?
70
+
71
+ If you are interested, I explain myself below. Regardless, you don't have to use this library. As you saw in the setup instructions, this library leverages the open_id_authentication rails plugin. You can EASILY use this in your controllers and do your traditional OpenID authentication yourself. After the user has been authenticated just do this:
72
+
73
+ UserSession.create(@user)
74
+
75
+ It's that simple. For more information there is a great OpenID tutorial at: http://railscasts.com/episodes/68-openid-authentication
76
+
77
+ Now, here are my thoughts on the subject:
78
+
79
+ You are probably thinking: "Ben, you can't handle controller responsibilities in models". I agree with you on that comment, but my personal opinion is that these are not controller responsibilities. The fact that OpenID authentication requires a redirect should not effect the location of the logic / code. It's all part of the authentication process, which is the entire purpose of this library. The logic that handles this process should be in it's own domain, which is the definition of the "M" in MVC. The "M" doesn't have to just be a data access layer, it's a place for domain logic.
80
+
81
+ What if you wanted to authenticate with OpenID in multiple controllers in your application? You would probably pull out the common code into a module and include it in the respective controllers. Even better, you might create a class that elegantly handles this process and then place it in your lib directory. That's exactly what this is.
82
+
83
+ The last thing I will leave you with, to get you thinking, is... where do sweepers lie in the MVC pattern?
84
+
85
+ Regardless, if I still haven't convinced you, I hope this library is of some benefit to you. At the very least an example of how to extend Authlogic.
86
+
87
+ Copyright (c) 2009 Ben Johnson of [Binary Logic](http://www.binarylogic.com), 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 "hoe"
5
+ require File.dirname(__FILE__) << "/lib/authlogic_openid/version"
6
+
7
+ Hoe.new("Authlogic OpenID", AuthlogicOpenid::Version::STRING) do |p|
8
+ p.name = "authlogic-oid"
9
+ p.rubyforge_name = "authlogic-oid"
10
+ p.author = "Ben Johnson of Binary Logic"
11
+ p.email = 'bjohnson@binarylogic.com'
12
+ p.summary = "Extension of the Authlogic library to add OpenID support."
13
+ p.description = "Extension of the Authlogic library to add OpenID support."
14
+ p.url = "http://github.com/binarylogic/authlogic_openid"
15
+ p.history_file = "CHANGELOG.rdoc"
16
+ p.readme_file = "README.rdoc"
17
+ p.extra_rdoc_files = ["CHANGELOG.rdoc", "README.rdoc"]
18
+ p.test_globs = ["test/*/test_*.rb", "test/*_test.rb", "test/*/*_test.rb"]
19
+ p.extra_deps = %w(authlogic)
20
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require "authlogic_openid"
@@ -0,0 +1,117 @@
1
+ # This module is responsible for adding OpenID functionality to Authlogic. Checkout the README for more info and please
2
+ # see the sub modules for detailed documentation.
3
+ module AuthlogicOpenid
4
+ # This module is responsible for adding in the OpenID 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
+ # OpenID is being used.
9
+ def self.included(klass)
10
+ klass.class_eval do
11
+ add_acts_as_authentic_module(Methods)
12
+ validates_length_of_password_field_options validates_length_of_password_field_options.merge(:if => :validate_password_with_openid?)
13
+ validates_confirmation_of_password_field_options validates_confirmation_of_password_field_options.merge(:if => :validate_password_with_openid?)
14
+ validates_length_of_password_confirmation_field_options validates_length_of_password_confirmation_field_options.merge(:if => :validate_password_with_openid?)
15
+ end
16
+ end
17
+
18
+ module Methods
19
+ # Set up some simple validations
20
+ def self.included(klass)
21
+ klass.class_eval do
22
+ validates_uniqueness_of :openid_identifier, :scope => validations_scope, :if => :using_openid?
23
+ validate :validate_openid
24
+ end
25
+ end
26
+
27
+ # Set the openid_identifier field and also resets the persistence_token if this value changes.
28
+ def openid_identifier=(value)
29
+ write_attribute(:openid_identifier, value.blank? ? nil : OpenIdAuthentication.normalize_identifier(value))
30
+ reset_persistence_token if openid_identifier_changed?
31
+ rescue OpenIdAuthentication::InvalidOpenId => e
32
+ @openid_error = e.message
33
+ end
34
+
35
+ # This is where all of the magic happens. This is where we hook in and add all of the OpenID sweetness.
36
+ #
37
+ # I had to take this approach because when authenticating with OpenID nonces and what not are stored in database
38
+ # tables. That being said, the whole save process for ActiveRecord is wrapped in a transaction. Trying to authenticate
39
+ # with OpenID in a transaction is not good because that transaction be get rolled back, thus reversing all of the OpenID
40
+ # inserts and making OpenID authentication fail every time. So We need to step outside of the transaction and do our OpenID
41
+ # madness.
42
+ #
43
+ # Another advantage of taking this approach is that we can set fields from their OpenID profile before we save the record,
44
+ # if their OpenID provider supports it.
45
+ def save(perform_validation = true, &block)
46
+ if !perform_validation || !authenticate_with_openid? || (authenticate_with_openid? && authenticate_with_openid)
47
+ result = super
48
+ yield(result) if block_given?
49
+ result
50
+ else
51
+ false
52
+ end
53
+ end
54
+
55
+ private
56
+ def authenticate_with_openid
57
+ @openid_error = nil
58
+
59
+ if !openid_complete?
60
+ attrs_to_persist = attributes.delete_if do |k, v|
61
+ [:password, crypted_password_field, password_salt_field, :persistence_token, :perishable_token, :single_access_token, :login_count,
62
+ :failed_login_count, :last_request_at, :current_login_at, :last_login_at, :current_login_ip, :last_login_ip, :created_at,
63
+ :updated_at, :lock_version].include?(k.to_sym)
64
+ end
65
+ attrs_to_persist.merge!(:password => password, :password_confirmation => password_confirmation)
66
+ session_class.controller.session[:openid_attributes] = attrs_to_persist
67
+ else
68
+ self.attributes = session_class.controller.session[:openid_attributes]
69
+ session_class.controller.session[:openid_attributes] = nil
70
+ end
71
+
72
+ options = {}
73
+ options[:required_field] = [self.class.login_field, self.class.email_field].compact
74
+ options[:optional_fields] = [:fullname]
75
+ options[:return_to] = session_class.controller.url_for(:for_model => "1")
76
+
77
+ session_class.controller.send(:authenticate_with_open_id, openid_identifier, options) do |result, openid_identifier, registration|
78
+ if result.unsuccessful?
79
+ @openid_error = result.message
80
+ else
81
+ map_openid_registration(registration)
82
+ end
83
+
84
+ return true
85
+ end
86
+
87
+ return false
88
+ end
89
+
90
+ def map_openid_registration(registration)
91
+ self.name ||= registration[:fullname] if respond_to?(:name) && !registration[:fullname].blank?
92
+ self.first_name ||= registration[:fullname].split(" ").first if respond_to?(:first_name) && !registration[:fullname].blank?
93
+ self.first_name ||= registration[:fullname].split(" ").last if respond_to?(:last_name) && !registration[:last_name].blank?
94
+ end
95
+
96
+ def validate_openid
97
+ errors.add(:openid_identifier, "had the following error: #{@openid_error}") if @openid_error
98
+ end
99
+
100
+ def using_openid?
101
+ !openid_identifier.blank?
102
+ end
103
+
104
+ def openid_complete?
105
+ session_class.controller.params[:open_id_complete] && session_class.controller.params[:for_model]
106
+ end
107
+
108
+ def authenticate_with_openid?
109
+ session_class.activated? && ((using_openid? && openid_identifier_changed?) || openid_complete?)
110
+ end
111
+
112
+ def validate_password_with_openid?
113
+ !using_openid? && require_password?
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,61 @@
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
+ attr_reader :openid_identifier
8
+ validate :validate_openid_error
9
+ validate :validate_by_openid, :if => :authenticating_with_openid?
10
+ end
11
+ end
12
+
13
+ # Hooks into credentials so that you can pass an :openid_identifier key.
14
+ def credentials=(value)
15
+ super
16
+ values = value.is_a?(Array) ? value : [value]
17
+ hash = values.first.is_a?(Hash) ? values.first.with_indifferent_access : nil
18
+ self.openid_identifier = hash[:openid_identifier] if !hash.nil? && hash.key?(:openid_identifier)
19
+ end
20
+
21
+ def openid_identifier=(value)
22
+ @openid_identifier = value.blank? ? nil : OpenIdAuthentication.normalize_identifier(value)
23
+ @openid_error = nil
24
+ rescue OpenIdAuthentication::InvalidOpenId => e
25
+ @openid_identifier = nil
26
+ @openid_error = e.message
27
+ end
28
+
29
+ # Cleaers out the block if we are authenticating with OpenID, so that we can redirect without a DoubleRender
30
+ # error.
31
+ def save(&block)
32
+ block = nil if !openid_identifier.blank?
33
+ super(&block)
34
+ end
35
+
36
+ private
37
+ def authenticating_with_openid?
38
+ !openid_identifier.blank? || (controller.params[:open_id_complete] && controller.params[:for_session])
39
+ end
40
+
41
+ def validate_by_openid
42
+ controller.send(:authenticate_with_open_id, openid_identifier, :return_to => controller.url_for(:for_session => "1")) do |result, openid_identifier|
43
+ if result.unsuccessful?
44
+ errors.add_to_base(result.message)
45
+ return
46
+ end
47
+
48
+ self.attempted_record = klass.find_by_openid_identifier(openid_identifier)
49
+
50
+ if !attempted_record
51
+ errors.add(:openid_identifier, "did not match any users in our database, have you set up your account to use OpenID?")
52
+ return
53
+ end
54
+ end
55
+ end
56
+
57
+ def validate_openid_error
58
+ errors.add(:openid_identifier, @openid_error) if @openid_error
59
+ end
60
+ end
61
+ 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 = 0
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,6 @@
1
+ require "authlogic_openid/version"
2
+ require "authlogic_openid/acts_as_authentic"
3
+ require "authlogic_openid/session"
4
+
5
+ ActiveRecord::Base.send(:include, AuthlogicOpenid::ActsAsAuthentic)
6
+ Authlogic::Session::Base.send(:include, AuthlogicOpenid::Session)
@@ -0,0 +1,90 @@
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
+ 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]