czak-authlogic-oid 1.0.4

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 +21 -0
  6. data/init.rb +1 -0
  7. data/lib/authlogic_openid/acts_as_authentic.rb +169 -0
  8. data/lib/authlogic_openid/session.rb +96 -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 +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/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 +115 -0
@@ -0,0 +1,244 @@
1
+ require 'uri'
2
+ require 'openid/extensions/sreg'
3
+ require 'openid/extensions/ax'
4
+ require 'openid/store/filesystem'
5
+
6
+ require File.dirname(__FILE__) + '/open_id_authentication/association'
7
+ require File.dirname(__FILE__) + '/open_id_authentication/nonce'
8
+ require File.dirname(__FILE__) + '/open_id_authentication/db_store'
9
+ require File.dirname(__FILE__) + '/open_id_authentication/mem_cache_store'
10
+ require File.dirname(__FILE__) + '/open_id_authentication/request'
11
+ require File.dirname(__FILE__) + '/open_id_authentication/timeout_fixes' if OpenID::VERSION == "2.0.4"
12
+
13
+ module OpenIdAuthentication
14
+ OPEN_ID_AUTHENTICATION_DIR = RAILS_ROOT + "/tmp/openids"
15
+
16
+ def self.store
17
+ @@store
18
+ end
19
+
20
+ def self.store=(*store_option)
21
+ store, *parameters = *([ store_option ].flatten)
22
+
23
+ @@store = case store
24
+ when :db
25
+ OpenIdAuthentication::DbStore.new
26
+ when :mem_cache
27
+ OpenIdAuthentication::MemCacheStore.new(*parameters)
28
+ when :file
29
+ OpenID::Store::Filesystem.new(OPEN_ID_AUTHENTICATION_DIR)
30
+ else
31
+ raise "Unknown store: #{store}"
32
+ end
33
+ end
34
+
35
+ self.store = :db
36
+
37
+ class InvalidOpenId < StandardError
38
+ end
39
+
40
+ class Result
41
+ ERROR_MESSAGES = {
42
+ :missing => "Sorry, the OpenID server couldn't be found",
43
+ :invalid => "Sorry, but this does not appear to be a valid OpenID",
44
+ :canceled => "OpenID verification was canceled",
45
+ :failed => "OpenID verification failed",
46
+ :setup_needed => "OpenID verification needs setup"
47
+ }
48
+
49
+ def self.[](code)
50
+ new(code)
51
+ end
52
+
53
+ def initialize(code)
54
+ @code = code
55
+ end
56
+
57
+ def status
58
+ @code
59
+ end
60
+
61
+ ERROR_MESSAGES.keys.each { |state| define_method("#{state}?") { @code == state } }
62
+
63
+ def successful?
64
+ @code == :successful
65
+ end
66
+
67
+ def unsuccessful?
68
+ ERROR_MESSAGES.keys.include?(@code)
69
+ end
70
+
71
+ def message
72
+ ERROR_MESSAGES[@code]
73
+ end
74
+ end
75
+
76
+ # normalizes an OpenID according to http://openid.net/specs/openid-authentication-2_0.html#normalization
77
+ def self.normalize_identifier(identifier)
78
+ # clean up whitespace
79
+ identifier = identifier.to_s.strip
80
+
81
+ # if an XRI has a prefix, strip it.
82
+ identifier.gsub!(/xri:\/\//i, '')
83
+
84
+ # dodge XRIs -- TODO: validate, don't just skip.
85
+ unless ['=', '@', '+', '$', '!', '('].include?(identifier.at(0))
86
+ # does it begin with http? if not, add it.
87
+ identifier = "http://#{identifier}" unless identifier =~ /^http/i
88
+
89
+ # strip any fragments
90
+ identifier.gsub!(/\#(.*)$/, '')
91
+
92
+ begin
93
+ uri = URI.parse(identifier)
94
+ uri.scheme = uri.scheme.downcase # URI should do this
95
+ identifier = uri.normalize.to_s
96
+ rescue URI::InvalidURIError
97
+ raise InvalidOpenId.new("#{identifier} is not an OpenID identifier")
98
+ end
99
+ end
100
+
101
+ return identifier
102
+ end
103
+
104
+ # deprecated for OpenID 2.0, where not all OpenIDs are URLs
105
+ def self.normalize_url(url)
106
+ ActiveSupport::Deprecation.warn "normalize_url has been deprecated, use normalize_identifier instead"
107
+ self.normalize_identifier(url)
108
+ end
109
+
110
+ protected
111
+ def normalize_url(url)
112
+ OpenIdAuthentication.normalize_url(url)
113
+ end
114
+
115
+ def normalize_identifier(url)
116
+ OpenIdAuthentication.normalize_identifier(url)
117
+ end
118
+
119
+ # The parameter name of "openid_identifier" is used rather than the Rails convention "open_id_identifier"
120
+ # because that's what the specification dictates in order to get browser auto-complete working across sites
121
+ def using_open_id?(identity_url = nil) #:doc:
122
+ identity_url ||= params[:openid_identifier] || params[:openid_url]
123
+ !identity_url.blank? || params[:open_id_complete]
124
+ end
125
+
126
+ def authenticate_with_open_id(identity_url = nil, options = {}, &block) #:doc:
127
+ identity_url ||= params[:openid_identifier] || params[:openid_url]
128
+
129
+ if params[:open_id_complete].nil?
130
+ begin_open_id_authentication(identity_url, options, &block)
131
+ else
132
+ complete_open_id_authentication(&block)
133
+ end
134
+ end
135
+
136
+ private
137
+ def begin_open_id_authentication(identity_url, options = {})
138
+ identity_url = normalize_identifier(identity_url)
139
+ return_to = options.delete(:return_to)
140
+ method = options.delete(:method)
141
+
142
+ options[:required] ||= [] # reduces validation later
143
+ options[:optional] ||= []
144
+
145
+ open_id_request = open_id_consumer.begin(identity_url)
146
+ add_simple_registration_fields(open_id_request, options)
147
+ add_ax_fields(open_id_request, options)
148
+
149
+ redirect_to(open_id_redirect_url(open_id_request, return_to, method))
150
+ rescue OpenIdAuthentication::InvalidOpenId => e
151
+ yield Result[:invalid], identity_url, nil
152
+ rescue OpenID::OpenIDError, Timeout::Error => e
153
+ logger.error("[OPENID] #{e}")
154
+ yield Result[:missing], identity_url, nil
155
+ end
156
+
157
+ def complete_open_id_authentication
158
+ params_with_path = params.reject { |key, value| request.path_parameters[key] }
159
+ params_with_path.delete(:format)
160
+ open_id_response = timeout_protection_from_identity_server { open_id_consumer.complete(params_with_path, requested_url) }
161
+ identity_url = normalize_identifier(open_id_response.display_identifier) if open_id_response.display_identifier
162
+
163
+ case open_id_response.status
164
+ when OpenID::Consumer::SUCCESS
165
+ profile_data = {}
166
+
167
+ # merge the SReg data and the AX data into a single hash of profile data
168
+ [ OpenID::SReg::Response, OpenID::AX::FetchResponse ].each do |data_response|
169
+ if data_response.from_success_response( open_id_response )
170
+ profile_data.merge! data_response.from_success_response( open_id_response ).data
171
+ end
172
+ end
173
+
174
+ yield Result[:successful], identity_url, profile_data
175
+ when OpenID::Consumer::CANCEL
176
+ yield Result[:canceled], identity_url, nil
177
+ when OpenID::Consumer::FAILURE
178
+ yield Result[:failed], identity_url, nil
179
+ when OpenID::Consumer::SETUP_NEEDED
180
+ yield Result[:setup_needed], open_id_response.setup_url, nil
181
+ end
182
+ end
183
+
184
+ def open_id_consumer
185
+ OpenID::Consumer.new(session, OpenIdAuthentication.store)
186
+ end
187
+
188
+ def add_simple_registration_fields(open_id_request, fields)
189
+ sreg_request = OpenID::SReg::Request.new
190
+
191
+ # filter out AX identifiers (URIs)
192
+ required_fields = fields[:required].collect { |f| f.to_s unless f =~ /^https?:\/\// }.compact
193
+ optional_fields = fields[:optional].collect { |f| f.to_s unless f =~ /^https?:\/\// }.compact
194
+
195
+ sreg_request.request_fields(required_fields, true) unless required_fields.blank?
196
+ sreg_request.request_fields(optional_fields, false) unless optional_fields.blank?
197
+ sreg_request.policy_url = fields[:policy_url] if fields[:policy_url]
198
+ open_id_request.add_extension(sreg_request)
199
+ end
200
+
201
+ def add_ax_fields( open_id_request, fields )
202
+ ax_request = OpenID::AX::FetchRequest.new
203
+
204
+ # look through the :required and :optional fields for URIs (AX identifiers)
205
+ fields[:required].each do |f|
206
+ next unless f =~ /^https?:\/\//
207
+ ax_request.add( OpenID::AX::AttrInfo.new( f, nil, true ) )
208
+ end
209
+
210
+ fields[:optional].each do |f|
211
+ next unless f =~ /^https?:\/\//
212
+ ax_request.add( OpenID::AX::AttrInfo.new( f, nil, false ) )
213
+ end
214
+
215
+ open_id_request.add_extension( ax_request )
216
+ end
217
+
218
+ def open_id_redirect_url(open_id_request, return_to = nil, method = nil)
219
+ open_id_request.return_to_args['_method'] = (method || request.method).to_s
220
+ open_id_request.return_to_args['open_id_complete'] = '1'
221
+ open_id_request.redirect_url(root_url, return_to || requested_url)
222
+ end
223
+
224
+ def requested_url
225
+ relative_url_root = self.class.respond_to?(:relative_url_root) ?
226
+ self.class.relative_url_root.to_s :
227
+ request.relative_url_root
228
+ "#{request.protocol}#{request.host_with_port}#{ActionController::Base.relative_url_root}#{request.path}"
229
+ end
230
+
231
+ def timeout_protection_from_identity_server
232
+ yield
233
+ rescue Timeout::Error
234
+ Class.new do
235
+ def status
236
+ OpenID::FAILURE
237
+ end
238
+
239
+ def msg
240
+ "Identity server timed out"
241
+ end
242
+ end.new
243
+ end
244
+ end
@@ -0,0 +1,30 @@
1
+ namespace :open_id_authentication do
2
+ namespace :db do
3
+ desc "Creates authentication tables for use with OpenIdAuthentication"
4
+ task :create => :environment do
5
+ generate_migration(["open_id_authentication_tables", "add_open_id_authentication_tables"])
6
+ end
7
+
8
+ desc "Upgrade authentication tables from ruby-openid 1.x.x to 2.x.x"
9
+ task :upgrade => :environment do
10
+ generate_migration(["upgrade_open_id_authentication_tables", "upgrade_open_id_authentication_tables"])
11
+ end
12
+
13
+ def generate_migration(args)
14
+ require 'rails_generator'
15
+ require 'rails_generator/scripts/generate'
16
+
17
+ if ActiveRecord::Base.connection.supports_migrations?
18
+ Rails::Generator::Scripts::Generate.new.run(args)
19
+ else
20
+ raise "Task unavailable to this database (no migration support)"
21
+ end
22
+ end
23
+
24
+ desc "Clear the authentication tables"
25
+ task :clear => :environment do
26
+ OpenIdAuthentication::DbStore.cleanup_nonces
27
+ OpenIdAuthentication::DbStore.cleanup_associations
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,151 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+ require File.dirname(__FILE__) + '/../lib/open_id_authentication/mem_cache_store'
3
+
4
+ # Mock MemCacheStore with MemoryStore for testing
5
+ class OpenIdAuthentication::MemCacheStore < OpenID::Store::Interface
6
+ def initialize(*addresses)
7
+ @connection = ActiveSupport::Cache::MemoryStore.new
8
+ end
9
+ end
10
+
11
+ class MemCacheStoreTest < Test::Unit::TestCase
12
+ ALLOWED_HANDLE = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
13
+
14
+ def setup
15
+ @store = OpenIdAuthentication::MemCacheStore.new
16
+ end
17
+
18
+ def test_store
19
+ server_url = "http://www.myopenid.com/openid"
20
+ assoc = gen_assoc(0)
21
+
22
+ # Make sure that a missing association returns no result
23
+ assert_retrieve(server_url)
24
+
25
+ # Check that after storage, getting returns the same result
26
+ @store.store_association(server_url, assoc)
27
+ assert_retrieve(server_url, nil, assoc)
28
+
29
+ # more than once
30
+ assert_retrieve(server_url, nil, assoc)
31
+
32
+ # Storing more than once has no ill effect
33
+ @store.store_association(server_url, assoc)
34
+ assert_retrieve(server_url, nil, assoc)
35
+
36
+ # Removing an association that does not exist returns not present
37
+ assert_remove(server_url, assoc.handle + 'x', false)
38
+
39
+ # Removing an association that does not exist returns not present
40
+ assert_remove(server_url + 'x', assoc.handle, false)
41
+
42
+ # Removing an association that is present returns present
43
+ assert_remove(server_url, assoc.handle, true)
44
+
45
+ # but not present on subsequent calls
46
+ assert_remove(server_url, assoc.handle, false)
47
+
48
+ # Put assoc back in the store
49
+ @store.store_association(server_url, assoc)
50
+
51
+ # More recent and expires after assoc
52
+ assoc2 = gen_assoc(1)
53
+ @store.store_association(server_url, assoc2)
54
+
55
+ # After storing an association with a different handle, but the
56
+ # same server_url, the handle with the later expiration is returned.
57
+ assert_retrieve(server_url, nil, assoc2)
58
+
59
+ # We can still retrieve the older association
60
+ assert_retrieve(server_url, assoc.handle, assoc)
61
+
62
+ # Plus we can retrieve the association with the later expiration
63
+ # explicitly
64
+ assert_retrieve(server_url, assoc2.handle, assoc2)
65
+
66
+ # More recent, and expires earlier than assoc2 or assoc. Make sure
67
+ # that we're picking the one with the latest issued date and not
68
+ # taking into account the expiration.
69
+ assoc3 = gen_assoc(2, 100)
70
+ @store.store_association(server_url, assoc3)
71
+
72
+ assert_retrieve(server_url, nil, assoc3)
73
+ assert_retrieve(server_url, assoc.handle, assoc)
74
+ assert_retrieve(server_url, assoc2.handle, assoc2)
75
+ assert_retrieve(server_url, assoc3.handle, assoc3)
76
+
77
+ assert_remove(server_url, assoc2.handle, true)
78
+
79
+ assert_retrieve(server_url, nil, assoc3)
80
+ assert_retrieve(server_url, assoc.handle, assoc)
81
+ assert_retrieve(server_url, assoc2.handle, nil)
82
+ assert_retrieve(server_url, assoc3.handle, assoc3)
83
+
84
+ assert_remove(server_url, assoc2.handle, false)
85
+ assert_remove(server_url, assoc3.handle, true)
86
+
87
+ assert_retrieve(server_url, nil, assoc)
88
+ assert_retrieve(server_url, assoc.handle, assoc)
89
+ assert_retrieve(server_url, assoc2.handle, nil)
90
+ assert_retrieve(server_url, assoc3.handle, nil)
91
+
92
+ assert_remove(server_url, assoc2.handle, false)
93
+ assert_remove(server_url, assoc.handle, true)
94
+ assert_remove(server_url, assoc3.handle, false)
95
+
96
+ assert_retrieve(server_url, nil, nil)
97
+ assert_retrieve(server_url, assoc.handle, nil)
98
+ assert_retrieve(server_url, assoc2.handle, nil)
99
+ assert_retrieve(server_url, assoc3.handle, nil)
100
+
101
+ assert_remove(server_url, assoc2.handle, false)
102
+ assert_remove(server_url, assoc.handle, false)
103
+ assert_remove(server_url, assoc3.handle, false)
104
+ end
105
+
106
+ def test_nonce
107
+ server_url = "http://www.myopenid.com/openid"
108
+
109
+ [server_url, ''].each do |url|
110
+ nonce1 = OpenID::Nonce::mk_nonce
111
+
112
+ assert_nonce(nonce1, true, url, "#{url}: nonce allowed by default")
113
+ assert_nonce(nonce1, false, url, "#{url}: nonce not allowed twice")
114
+ assert_nonce(nonce1, false, url, "#{url}: nonce not allowed third time")
115
+
116
+ # old nonces shouldn't pass
117
+ old_nonce = OpenID::Nonce::mk_nonce(3600)
118
+ assert_nonce(old_nonce, false, url, "Old nonce #{old_nonce.inspect} passed")
119
+ end
120
+ end
121
+
122
+ private
123
+ def gen_assoc(issued, lifetime = 600)
124
+ secret = OpenID::CryptUtil.random_string(20, nil)
125
+ handle = OpenID::CryptUtil.random_string(128, ALLOWED_HANDLE)
126
+ OpenID::Association.new(handle, secret, Time.now + issued, lifetime, 'HMAC-SHA1')
127
+ end
128
+
129
+ def assert_retrieve(url, handle = nil, expected = nil)
130
+ assoc = @store.get_association(url, handle)
131
+
132
+ if expected.nil?
133
+ assert_nil(assoc)
134
+ else
135
+ assert_equal(expected, assoc)
136
+ assert_equal(expected.handle, assoc.handle)
137
+ assert_equal(expected.secret, assoc.secret)
138
+ end
139
+ end
140
+
141
+ def assert_remove(url, handle, expected)
142
+ present = @store.remove_association(url, handle)
143
+ assert_equal(expected, present)
144
+ end
145
+
146
+ def assert_nonce(nonce, expected, server_url, msg = "")
147
+ stamp, salt = OpenID::Nonce::split_nonce(nonce)
148
+ actual = @store.use_nonce(server_url, stamp, salt)
149
+ assert_equal(expected, actual, msg)
150
+ end
151
+ end
@@ -0,0 +1,32 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class NormalizeTest < Test::Unit::TestCase
4
+ include OpenIdAuthentication
5
+
6
+ NORMALIZATIONS = {
7
+ "openid.aol.com/nextangler" => "http://openid.aol.com/nextangler",
8
+ "http://openid.aol.com/nextangler" => "http://openid.aol.com/nextangler",
9
+ "https://openid.aol.com/nextangler" => "https://openid.aol.com/nextangler",
10
+ "HTTP://OPENID.AOL.COM/NEXTANGLER" => "http://openid.aol.com/NEXTANGLER",
11
+ "HTTPS://OPENID.AOL.COM/NEXTANGLER" => "https://openid.aol.com/NEXTANGLER",
12
+ "loudthinking.com" => "http://loudthinking.com/",
13
+ "http://loudthinking.com" => "http://loudthinking.com/",
14
+ "http://loudthinking.com:80" => "http://loudthinking.com/",
15
+ "https://loudthinking.com:443" => "https://loudthinking.com/",
16
+ "http://loudthinking.com:8080" => "http://loudthinking.com:8080/",
17
+ "techno-weenie.net" => "http://techno-weenie.net/",
18
+ "http://techno-weenie.net" => "http://techno-weenie.net/",
19
+ "http://techno-weenie.net " => "http://techno-weenie.net/",
20
+ "=name" => "=name"
21
+ }
22
+
23
+ def test_normalizations
24
+ NORMALIZATIONS.each do |from, to|
25
+ assert_equal to, normalize_identifier(from)
26
+ end
27
+ end
28
+
29
+ def test_broken_open_id
30
+ assert_raises(InvalidOpenId) { normalize_identifier(nil) }
31
+ end
32
+ end
@@ -0,0 +1,46 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class OpenIdAuthenticationTest < Test::Unit::TestCase
4
+ def setup
5
+ @controller = Class.new do
6
+ include OpenIdAuthentication
7
+ def params() {} end
8
+ end.new
9
+ end
10
+
11
+ def test_authentication_should_fail_when_the_identity_server_is_missing
12
+ open_id_consumer = mock()
13
+ open_id_consumer.expects(:begin).raises(OpenID::OpenIDError)
14
+ @controller.expects(:open_id_consumer).returns(open_id_consumer)
15
+ @controller.expects(:logger).returns(mock(:error => true))
16
+
17
+ @controller.send(:authenticate_with_open_id, "http://someone.example.com") do |result, identity_url|
18
+ assert result.missing?
19
+ assert_equal "Sorry, the OpenID server couldn't be found", result.message
20
+ end
21
+ end
22
+
23
+ def test_authentication_should_be_invalid_when_the_identity_url_is_invalid
24
+ @controller.send(:authenticate_with_open_id, "!") do |result, identity_url|
25
+ assert result.invalid?, "Result expected to be invalid but was not"
26
+ assert_equal "Sorry, but this does not appear to be a valid OpenID", result.message
27
+ end
28
+ end
29
+
30
+ def test_authentication_should_fail_when_the_identity_server_times_out
31
+ open_id_consumer = mock()
32
+ open_id_consumer.expects(:begin).raises(Timeout::Error, "Identity Server took too long.")
33
+ @controller.expects(:open_id_consumer).returns(open_id_consumer)
34
+ @controller.expects(:logger).returns(mock(:error => true))
35
+
36
+ @controller.send(:authenticate_with_open_id, "http://someone.example.com") do |result, identity_url|
37
+ assert result.missing?
38
+ assert_equal "Sorry, the OpenID server couldn't be found", result.message
39
+ end
40
+ end
41
+
42
+ def test_authentication_should_begin_when_the_identity_server_is_present
43
+ @controller.expects(:begin_open_id_authentication)
44
+ @controller.send(:authenticate_with_open_id, "http://someone.example.com")
45
+ end
46
+ end
@@ -0,0 +1,14 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class StatusTest < Test::Unit::TestCase
4
+ include OpenIdAuthentication
5
+
6
+ def test_state_conditional
7
+ assert Result[:missing].missing?
8
+ assert Result[:missing].unsuccessful?
9
+ assert !Result[:missing].successful?
10
+
11
+ assert Result[:successful].successful?
12
+ assert !Result[:successful].unsuccessful?
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+
4
+ gem 'activesupport'
5
+ require 'active_support'
6
+
7
+ gem 'actionpack'
8
+ require 'action_controller'
9
+
10
+ gem 'mocha'
11
+ require 'mocha'
12
+
13
+ gem 'ruby-openid'
14
+ require 'openid'
15
+
16
+ RAILS_ROOT = File.dirname(__FILE__) unless defined? RAILS_ROOT
17
+ require File.dirname(__FILE__) + "/../lib/open_id_authentication"
@@ -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,32 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class SessionTest < ActiveSupport::TestCase
4
+ def test_openid_identifier
5
+ session = UserSession.new
6
+ assert session.respond_to?(:openid_identifier)
7
+ session.openid_identifier = "test"
8
+ assert_equal "http://test/", session.openid_identifier
9
+ end
10
+
11
+ def test_validate_openid_error
12
+ session = UserSession.new
13
+ session.openid_identifier = "yes"
14
+ session.openid_identifier = "%"
15
+ assert_nil session.openid_identifier
16
+ assert !session.save
17
+ assert session.errors.on(:openid_identifier)
18
+ end
19
+
20
+ def test_validate_by_nil_openid_identifier
21
+ session = UserSession.new
22
+ assert !session.save
23
+ assert !redirecting_to_yahoo?
24
+ end
25
+
26
+ def test_validate_by_correct_openid_identifier
27
+ session = UserSession.new
28
+ session.openid_identifier = "https://me.yahoo.com/a/9W0FJjRj0o981TMSs0vqVxPdmMUVOQ--"
29
+ assert !session.save
30
+ assert redirecting_to_yahoo?
31
+ end
32
+ end