ruby-openid 2.0.4 → 2.1.2

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.

Potentially problematic release.


This version of ruby-openid might be problematic. Click here for more details.

Files changed (58) hide show
  1. data/CHANGELOG +65 -28
  2. data/LICENSE +4 -1
  3. data/README +19 -12
  4. data/UPGRADE +5 -0
  5. data/examples/README +8 -22
  6. data/examples/active_record_openid_store/XXX_add_open_id_store_to_db.rb +6 -6
  7. data/examples/active_record_openid_store/lib/association.rb +2 -1
  8. data/examples/active_record_openid_store/lib/openid_ar_store.rb +3 -3
  9. data/examples/rails_openid/app/controllers/consumer_controller.rb +11 -5
  10. data/lib/openid.rb +4 -0
  11. data/lib/openid/association.rb +7 -7
  12. data/lib/openid/consumer/checkid_request.rb +11 -0
  13. data/lib/openid/consumer/discovery.rb +12 -3
  14. data/lib/openid/consumer/idres.rb +35 -43
  15. data/lib/openid/extension.rb +9 -1
  16. data/lib/openid/extensions/pape.rb +22 -25
  17. data/lib/openid/extensions/sreg.rb +1 -0
  18. data/lib/openid/fetchers.rb +25 -5
  19. data/lib/openid/kvform.rb +8 -5
  20. data/lib/openid/kvpost.rb +6 -5
  21. data/lib/openid/message.rb +53 -34
  22. data/lib/openid/server.rb +87 -52
  23. data/lib/openid/trustroot.rb +25 -17
  24. data/lib/openid/util.rb +19 -4
  25. data/lib/openid/yadis/discovery.rb +3 -3
  26. data/lib/openid/yadis/htmltokenizer.rb +8 -5
  27. data/lib/openid/yadis/parsehtml.rb +22 -14
  28. data/lib/openid/yadis/xrds.rb +6 -9
  29. data/test/data/linkparse.txt +1 -1
  30. data/test/data/test1-parsehtml.txt +24 -0
  31. data/test/data/trustroot.txt +8 -2
  32. data/test/test_association.rb +7 -7
  33. data/test/test_associationmanager.rb +1 -1
  34. data/test/test_extension.rb +46 -0
  35. data/test/test_idres.rb +81 -21
  36. data/test/test_kvform.rb +5 -5
  37. data/test/test_message.rb +61 -3
  38. data/test/test_pape.rb +36 -22
  39. data/test/test_server.rb +190 -12
  40. data/test/test_sreg.rb +0 -1
  41. data/test/test_trustroot.rb +1 -0
  42. data/test/test_yadis_discovery.rb +13 -0
  43. metadata +3 -19
  44. data/examples/rails_openid/app/views/consumer/start.rhtml +0 -8
  45. data/examples/rails_openid_login_generator/USAGE +0 -23
  46. data/examples/rails_openid_login_generator/gemspec +0 -13
  47. data/examples/rails_openid_login_generator/openid_login_generator.rb +0 -36
  48. data/examples/rails_openid_login_generator/templates/README +0 -116
  49. data/examples/rails_openid_login_generator/templates/controller.rb +0 -113
  50. data/examples/rails_openid_login_generator/templates/controller_test.rb +0 -0
  51. data/examples/rails_openid_login_generator/templates/helper.rb +0 -2
  52. data/examples/rails_openid_login_generator/templates/openid_login_system.rb +0 -87
  53. data/examples/rails_openid_login_generator/templates/user.rb +0 -14
  54. data/examples/rails_openid_login_generator/templates/user_test.rb +0 -0
  55. data/examples/rails_openid_login_generator/templates/users.yml +0 -0
  56. data/examples/rails_openid_login_generator/templates/view_login.rhtml +0 -15
  57. data/examples/rails_openid_login_generator/templates/view_logout.rhtml +0 -10
  58. data/examples/rails_openid_login_generator/templates/view_welcome.rhtml +0 -9
@@ -78,7 +78,7 @@ module OpenID
78
78
  rescue Exception
79
79
  raise DiscoveryFailure.new("Failed to fetch identity URL #{uri} : #{$!}", $!)
80
80
  end
81
- if resp.code != "200"
81
+ if resp.code != "200" and resp.code != "206"
82
82
  raise DiscoveryFailure.new(
83
83
  "HTTP Response status from identity URL host is not \"200\"."\
84
84
  "Got status #{resp.code.inspect} for #{resp.final_url}", resp)
@@ -99,7 +99,7 @@ module OpenID
99
99
  rescue
100
100
  raise DiscoveryFailure.new("Failed to fetch Yadis URL #{result.xrds_uri} : #{$!}", $!)
101
101
  end
102
- if resp.code != "200"
102
+ if resp.code != "200" and resp.code != "206"
103
103
  exc = DiscoveryFailure.new(
104
104
  "HTTP Response status from Yadis host is not \"200\". " +
105
105
  "Got status #{resp.code.inspect} for #{resp.final_url}", resp)
@@ -128,7 +128,7 @@ module OpenID
128
128
 
129
129
  # According to the spec, the content-type header must be an
130
130
  # exact match, or else we have to look for an indirection.
131
- if (!content_type.nil? and
131
+ if (!content_type.nil? and !content_type.to_s.empty? and
132
132
  content_type.split(';', 2)[0].downcase == YADIS_CONTENT_TYPE)
133
133
  return resp.final_url
134
134
  else
@@ -74,7 +74,7 @@ class HTMLTokenizer
74
74
  # Token is a comment
75
75
  tag_end = @page.index('-->', (@cur_pos + 1))
76
76
  if tag_end.nil?
77
- raise OpenIDError, "No end found to started comment:\n#{@page[@cur_pos,80]}"
77
+ raise HTMLTokenizerError, "No end found to started comment:\n#{@page[@cur_pos,80]}"
78
78
  end
79
79
  # p @page[@cur_pos .. (tag_end+2)]
80
80
  HTMLComment.new(@page[@cur_pos .. (tag_end + 2)])
@@ -82,7 +82,7 @@ class HTMLTokenizer
82
82
  # Token is a html tag
83
83
  tag_end = @page.index('>', (@cur_pos + 1))
84
84
  if tag_end.nil?
85
- raise OpenIDError, "No end found to started tag:\n#{@page[@cur_pos,80]}"
85
+ raise HTMLTokenizerError, "No end found to started tag:\n#{@page[@cur_pos,80]}"
86
86
  end
87
87
  # p @page[@cur_pos .. tag_end]
88
88
  HTMLTag.new(@page[@cur_pos .. tag_end])
@@ -166,6 +166,9 @@ class HTMLTokenizer
166
166
 
167
167
  end
168
168
 
169
+ class HTMLTokenizerError < Exception
170
+ end
171
+
169
172
  # The parent class for all three types of HTML tokens
170
173
  class HTMLToken
171
174
  attr_accessor :raw
@@ -209,7 +212,7 @@ class HTMLComment < HTMLToken
209
212
  super(text)
210
213
  temp_arr = text.scan(/^<!--\s*(.*?)\s*-->$/m)
211
214
  if temp_arr[0].nil?
212
- raise OpenIDError, "Text passed to HTMLComment.initialize is not a comment"
215
+ raise HTMLTokenizerError, "Text passed to HTMLComment.initialize is not a comment"
213
216
  end
214
217
 
215
218
  @contents = temp_arr[0][0]
@@ -222,7 +225,7 @@ class HTMLTag < HTMLToken
222
225
  def initialize(text)
223
226
  super(text)
224
227
  if ?< != text[0] or ?> != text[-1]
225
- raise OpenIDError, "Text passed to HTMLComment.initialize is not a comment"
228
+ raise HTMLTokenizerError, "Text passed to HTMLComment.initialize is not a comment"
226
229
  end
227
230
 
228
231
  @attr_hash = Hash.new
@@ -230,7 +233,7 @@ class HTMLTag < HTMLToken
230
233
 
231
234
  tag_name = text.scan(/[\w:-]+/)[0]
232
235
  if tag_name.nil?
233
- raise OpenIDError, "Error, tag is nil: #{tag_name}"
236
+ raise HTMLTokenizerError, "Error, tag is nil: #{tag_name}"
234
237
  end
235
238
 
236
239
  if ?/ == text[1]
@@ -9,28 +9,36 @@ module OpenID
9
9
  # to keep track of whether or not we are in the head element
10
10
  in_head = false
11
11
 
12
- while el = parser.getTag('head', '/head', 'meta', 'body', '/body', 'html')
12
+ begin
13
+ while el = parser.getTag('head', '/head', 'meta', 'body', '/body',
14
+ 'html', 'script')
13
15
 
14
- # we are leaving head or have reached body, so we bail
15
- return nil if ['/head', 'body', '/body'].member?(el.tag_name)
16
+ # we are leaving head or have reached body, so we bail
17
+ return nil if ['/head', 'body', '/body'].member?(el.tag_name)
16
18
 
17
- if el.tag_name == 'head'
18
- unless el.to_s[-2] == ?/ # tag ends with a /: a short tag
19
- in_head = true
19
+ if el.tag_name == 'head'
20
+ unless el.to_s[-2] == ?/ # tag ends with a /: a short tag
21
+ in_head = true
22
+ end
23
+ end
24
+ next unless in_head
25
+
26
+ if el.tag_name == 'script'
27
+ unless el.to_s[-2] == ?/ # tag ends with a /: a short tag
28
+ parser.getTag('/script')
29
+ end
20
30
  end
21
- end
22
- next unless in_head
23
31
 
24
- return nil if el.tag_name == 'html'
32
+ return nil if el.tag_name == 'html'
25
33
 
26
- if el.tag_name == 'meta' and (equiv = el.attr_hash['http-equiv'])
27
- if ['x-xrds-location','x-yadis-location'].member?(equiv.downcase)
28
- return CGI::unescapeHTML(el.attr_hash['content'])
34
+ if el.tag_name == 'meta' and (equiv = el.attr_hash['http-equiv'])
35
+ if ['x-xrds-location','x-yadis-location'].member?(equiv.downcase)
36
+ return CGI::unescapeHTML(el.attr_hash['content'])
37
+ end
29
38
  end
30
39
  end
31
-
40
+ rescue HTMLTokenizerError # just stop parsing if there's an error
32
41
  end
33
42
  end
34
43
  end
35
44
  end
36
-
@@ -53,7 +53,7 @@ module OpenID
53
53
  }
54
54
  end
55
55
 
56
- cid_element = cid_elements[-1]
56
+ cid_element = cid_elements[0]
57
57
 
58
58
  if !cid_element
59
59
  return nil
@@ -61,19 +61,16 @@ module OpenID
61
61
 
62
62
  canonicalID = XRI.make_xri(cid_element.text)
63
63
 
64
- childID = canonicalID
64
+ childID = canonicalID.downcase
65
65
 
66
66
  xrd_list[1..-1].each { |xrd|
67
67
  parent_sought = childID[0...childID.rindex('!')]
68
68
 
69
- parent_list = []
70
- xrd.elements.each("CanonicalID") { |c|
71
- parent_list.push(XRI.make_xri(c.text))
72
- }
69
+ parent = XRI.make_xri(xrd.elements["CanonicalID"].text)
73
70
 
74
- if !parent_list.member?(parent_sought)
75
- raise XRDSFraud.new(sprintf("%s can not come from any of %s", parent_sought,
76
- parent_list))
71
+ if parent_sought != parent.downcase
72
+ raise XRDSFraud.new(sprintf("%s can not come from %s", parent_sought,
73
+ parent))
77
74
  end
78
75
 
79
76
  childID = parent_sought
@@ -1,7 +1,7 @@
1
1
  Num Tests: 72
2
2
 
3
3
  OpenID link parsing test cases
4
- Copyright (C) 2005-2006, JanRain, Inc.
4
+ Copyright (C) 2005-2008, JanRain, Inc.
5
5
  See COPYING for license information.
6
6
 
7
7
  File format
@@ -3,6 +3,14 @@ found
3
3
  <html><head><meta http-equiv="X-XRDS-Location" content="found"></head></html>
4
4
 
5
5
  found
6
+ <!-- minimal well-formed success case, xhtml closing, whitespace -->
7
+ <html><head><meta http-equiv="X-XRDS-Location" content="found" /></head></html>
8
+
9
+ found
10
+ <!-- minimal well-formed success case, xhtml closing, no whitespace -->
11
+ <html><head><meta http-equiv="X-XRDS-Location" content="found"/></head></html>
12
+
13
+ found
6
14
  <!-- minimal success case -->
7
15
  <html><head><meta http-equiv="X-XRDS-Location" content="found">
8
16
 
@@ -19,6 +27,14 @@ found
19
27
  <head><meta http-equiv="X-XRDS-Location" content="found">
20
28
 
21
29
  found
30
+ <!-- javascript in head -->
31
+ <html><head><script type="text/javascript">document.write("<body>");</script><META http-equiv="X-XRDS-Location" content="found">
32
+
33
+ None
34
+ <!-- no close script tag in head -->
35
+ <html><head><script type="text/javascript">document.write("<body>");<META http-equiv="X-XRDS-Location" content="found">
36
+
37
+ found
22
38
  <!-- case folding for tag names -->
23
39
  <html><head><META http-equiv="X-XRDS-Location" content="found">
24
40
 
@@ -96,6 +112,14 @@ None
96
112
  <html><head><body><meta http-equiv="X-XRDS-Location" content="found">
97
113
 
98
114
  None
115
+ <!-- <meta> is inside comment -->
116
+ <html>
117
+ <head>
118
+ <!--<meta http-equiv="X-XRDS-Location" content="found">-->
119
+ </head>
120
+ </html>
121
+
122
+ None
99
123
  <!-- <meta> is inside of <body> -->
100
124
  <html>
101
125
  <head>
@@ -3,7 +3,7 @@ Trust root parsing checking
3
3
  ========================================
4
4
 
5
5
  ----------------------------------------
6
- 19: Does not parse
6
+ 23: Does not parse
7
7
  ----------------------------------------
8
8
  baz.org
9
9
  *.foo.com
@@ -20,6 +20,10 @@ http://..it/
20
20
  http://.it/
21
21
  http://*:8081/
22
22
  http://*:80
23
+ http://localhost:1900foo/
24
+ http://foo.com\/
25
+ http://π.pi.com/
26
+ http://lambda.com/Λ
23
27
 
24
28
 
25
29
 
@@ -70,7 +74,7 @@ return_to matching
70
74
  ========================================
71
75
 
72
76
  ----------------------------------------
73
- 44: matches
77
+ 46: matches
74
78
  ----------------------------------------
75
79
  http://*/ http://cnn.com/
76
80
  http://*/ http://livejournal.com/
@@ -91,6 +95,7 @@ http://*.bar.co.uk http://www.bar.co.uk
91
95
  http://*.uoregon.edu http://x.cs.uoregon.edu
92
96
  http://x.com/abc http://x.com/abc
93
97
  http://x.com/abc http://x.com/abc/def
98
+ http://10.0.0.1/abc http://10.0.0.1/abc
94
99
  http://*.x.com http://x.com/gallery
95
100
  http://*.x.com http://foo.x.com/gallery
96
101
  http://foo.x.com http://foo.x.com/gallery/xxx
@@ -116,6 +121,7 @@ http://foo.com:80/ http://foo.com/stuff
116
121
  http://foo.com/path http://foo.com/path/extra
117
122
  http://foo.com/path2 http://foo.com/path2?extra=query
118
123
  http://foo.com/path2 http://foo.com/path2/?extra=query
124
+ http://foo.com/ HTTP://foo.com/
119
125
 
120
126
  ----------------------------------------
121
127
  25: does not match
@@ -24,14 +24,14 @@ module OpenID
24
24
  def test_deserialize_failure
25
25
  field_list = Util.kv_to_seq(@assoc.serialize)
26
26
  kv = Util.seq_to_kv(field_list + [['monkeys', 'funny']])
27
- assert_raises(StandardError) {
27
+ assert_raises(ProtocolError) {
28
28
  Association.deserialize(kv)
29
29
  }
30
30
 
31
31
  bad_version_list = field_list.dup
32
32
  bad_version_list[0] = ['version', 'moon']
33
33
  bad_version_kv = Util.seq_to_kv(bad_version_list)
34
- assert_raises(StandardError) {
34
+ assert_raises(ProtocolError) {
35
35
  Association.deserialize(bad_version_kv)
36
36
  }
37
37
  end
@@ -127,7 +127,7 @@ module OpenID
127
127
 
128
128
  def test_sign_bad_assoc_type
129
129
  @assoc.instance_eval { @assoc_type = 'Cookies' }
130
- assert_raises(StandardError) {
130
+ assert_raises(ProtocolError) {
131
131
  @assoc.sign([])
132
132
  }
133
133
  end
@@ -156,7 +156,7 @@ module OpenID
156
156
  })
157
157
  assoc = Association.from_expires_in(3600, '{sha1}', 'very_secret',
158
158
  "HMAC-SHA1")
159
- assert_raises(StandardError) {
159
+ assert_raises(ProtocolError) {
160
160
  assoc.check_message_signature(m)
161
161
  }
162
162
  end
@@ -169,7 +169,7 @@ module OpenID
169
169
  })
170
170
  assoc = Association.from_expires_in(3600, '{sha1}', 'very_secret',
171
171
  "HMAC-SHA1")
172
- assert_raises(StandardError) {
172
+ assert_raises(ProtocolError) {
173
173
  assoc.check_message_signature(m)
174
174
  }
175
175
  end
@@ -240,13 +240,13 @@ module OpenID
240
240
  end
241
241
 
242
242
  def test_bad_assoc_type
243
- assert_raises(StandardError) {
243
+ assert_raises(ProtocolError) {
244
244
  AssociationNegotiator.new([['OMG', 'Ponies']])
245
245
  }
246
246
  end
247
247
 
248
248
  def test_bad_session_type
249
- assert_raises(StandardError) {
249
+ assert_raises(ProtocolError) {
250
250
  AssociationNegotiator.new([['HMAC-SHA1', 'OMG-Ponies']])
251
251
  }
252
252
  end
@@ -279,7 +279,7 @@ module OpenID
279
279
  def request_association(assoc_type, session_type)
280
280
  m = @responses.shift
281
281
  if m.is_a?(Message)
282
- raise ServerError.from_message(m, nil)
282
+ raise ServerError.from_message(m)
283
283
  else
284
284
  return m
285
285
  end
@@ -0,0 +1,46 @@
1
+ require 'openid/extension'
2
+ require 'openid/message'
3
+ require 'test/unit'
4
+
5
+ module OpenID
6
+ class DummyExtension < OpenID::Extension
7
+ TEST_URI = 'http://an.extension'
8
+ TEST_ALIAS = 'dummy'
9
+ def initialize
10
+ @ns_uri = TEST_URI
11
+ @ns_alias = TEST_ALIAS
12
+ end
13
+
14
+ def get_extension_args
15
+ return {}
16
+ end
17
+ end
18
+
19
+ class ToMessageTest < Test::Unit::TestCase
20
+ def test_OpenID1
21
+ oid1_msg = Message.new(OPENID1_NS)
22
+ ext = DummyExtension.new
23
+ ext.to_message(oid1_msg)
24
+ namespaces = oid1_msg.namespaces
25
+ assert(namespaces.implicit?(DummyExtension::TEST_URI))
26
+ assert_equal(
27
+ DummyExtension::TEST_URI,
28
+ namespaces.get_namespace_uri(DummyExtension::TEST_ALIAS))
29
+ assert_equal(DummyExtension::TEST_ALIAS,
30
+ namespaces.get_alias(DummyExtension::TEST_URI))
31
+ end
32
+
33
+ def test_OpenID2
34
+ oid2_msg = Message.new(OPENID2_NS)
35
+ ext = DummyExtension.new
36
+ ext.to_message(oid2_msg)
37
+ namespaces = oid2_msg.namespaces
38
+ assert(!namespaces.implicit?(DummyExtension::TEST_URI))
39
+ assert_equal(
40
+ DummyExtension::TEST_URI,
41
+ namespaces.get_namespace_uri(DummyExtension::TEST_ALIAS))
42
+ assert_equal(DummyExtension::TEST_ALIAS,
43
+ namespaces.get_alias(DummyExtension::TEST_URI))
44
+ end
45
+ end
46
+ end
data/test/test_idres.rb CHANGED
@@ -99,6 +99,35 @@ module OpenID
99
99
  end
100
100
  end
101
101
 
102
+ def test_112
103
+ args = {'openid.assoc_handle' => 'fa1f5ff0-cde4-11dc-a183-3714bfd55ca8',
104
+ 'openid.claimed_id' => 'http://binkley.lan/user/test01',
105
+ 'openid.identity' => 'http://test01.binkley.lan/',
106
+ 'openid.mode' => 'id_res',
107
+ 'openid.ns' => 'http://specs.openid.net/auth/2.0',
108
+ 'openid.ns.pape' => 'http://specs.openid.net/extensions/pape/1.0',
109
+ 'openid.op_endpoint' => 'http://binkley.lan/server',
110
+ 'openid.pape.auth_policies' => 'none',
111
+ 'openid.pape.auth_time' => '2008-01-28T20:42:36Z',
112
+ 'openid.pape.nist_auth_level' => '0',
113
+ 'openid.response_nonce' => '2008-01-28T21:07:04Z99Q=',
114
+ 'openid.return_to' => 'http://binkley.lan:8001/process?janrain_nonce=2008-01-28T21%3A07%3A02Z0tMIKx',
115
+ 'openid.sig' => 'YJlWH4U6SroB1HoPkmEKx9AyGGg=',
116
+ 'openid.signed' => 'assoc_handle,identity,response_nonce,return_to,claimed_id,op_endpoint,pape.auth_time,ns.pape,pape.nist_auth_level,pape.auth_policies'
117
+ }
118
+ assert_equal(args['openid.ns'], OPENID2_NS)
119
+ incoming = Message.from_post_args(args)
120
+ assert(incoming.is_openid2)
121
+ idres = IdResHandler.new(incoming, nil)
122
+ car = idres.send(:create_check_auth_request)
123
+ expected_args = args.dup
124
+ expected_args['openid.mode'] = 'check_authentication'
125
+ expected = Message.from_post_args(expected_args)
126
+ assert(expected.is_openid2)
127
+ assert_equal(expected, car)
128
+ assert_equal(expected_args, car.to_post_args)
129
+ end
130
+
102
131
  def test_no_signed_list
103
132
  msg = Message.new(OPENID2_NS)
104
133
  idres = IdResHandler.new(msg, nil)
@@ -201,6 +230,11 @@ module OpenID
201
230
  [ [base, {}],
202
231
  [base + "?another=arg", {'another' => 'arg'}],
203
232
  [base + "?another=arg#frag", {'another' => 'arg'}],
233
+ ['HTTP'+base[4..-1], {}],
234
+ [base.sub('com', 'COM'), {}],
235
+ ['http://example.janrain.com:80/path', {}],
236
+ ['http://example.janrain.com/p%61th', {}],
237
+ ['http://example.janrain.com/./path',{}],
204
238
  ].each do |return_to, args|
205
239
  args['openid.return_to'] = return_to
206
240
  msg = Message.from_post_args(args)
@@ -370,20 +404,12 @@ module OpenID
370
404
  end
371
405
 
372
406
  def test_create_check_auth_request_success
373
- msg = call_idres_method(:create_check_auth_request) {}
374
- openid_args = @message.get_args(OPENID_NS)
375
- openid_args['mode'] = 'check_authentication'
376
- assert_equal(openid_args, msg.to_args)
407
+ ca_msg = call_idres_method(:create_check_auth_request) {}
408
+ expected = @message.copy
409
+ expected.set_arg(OPENID_NS, 'mode', 'check_authentication')
410
+ assert_equal(expected, ca_msg)
377
411
  end
378
412
 
379
- def test_create_check_auth_request_success_extra
380
- @message.set_arg(OPENID_NS, 'cookies', 'chocolate_chip')
381
- msg = call_idres_method(:create_check_auth_request) {}
382
- openid_args = @message.get_args(OPENID_NS)
383
- openid_args['mode'] = 'check_authentication'
384
- openid_args.delete('cookies')
385
- assert_equal(openid_args, msg.to_args)
386
- end
387
413
  end
388
414
 
389
415
  class CheckAuthResponseTest < Test::Unit::TestCase
@@ -554,11 +580,43 @@ module OpenID
554
580
 
555
581
  def test_openid1_no_endpoint
556
582
  @endpoint = nil
557
- assert_raises(StandardError) {
583
+ assert_raises(ProtocolError) {
558
584
  call_verify({'identity' => 'snakes on a plane'})
559
585
  }
560
586
  end
561
587
 
588
+ def test_openid1_fallback_1_0
589
+ claimed_id = 'http://claimed.id/'
590
+ @endpoint = nil
591
+ resp_mesg = Message.from_openid_args({
592
+ 'ns' => OPENID1_NS,
593
+ 'identity' => claimed_id,
594
+ })
595
+
596
+ # Pass the OpenID 1 claimed_id this way since we're passing
597
+ # None for the endpoint.
598
+ resp_mesg.set_arg(BARE_NS, 'openid1_claimed_id', claimed_id)
599
+
600
+ # We expect the OpenID 1 discovery verification to try
601
+ # matching the discovered endpoint against the 1.1 type and
602
+ # fall back to 1.0.
603
+ expected_endpoint = OpenIDServiceEndpoint.new
604
+ expected_endpoint.type_uris = [OPENID_1_0_TYPE]
605
+ expected_endpoint.local_id = nil
606
+ expected_endpoint.claimed_id = claimed_id
607
+
608
+ hacked_discover = Proc.new { ['unused', [expected_endpoint]] }
609
+ idres = IdResHandler.new(resp_mesg, nil, nil, @endpoint)
610
+ assert_log_matches('Performing discovery') {
611
+ OpenID.with_method_overridden(:discover, hacked_discover) {
612
+ idres.send(:verify_discovery_results)
613
+ }
614
+ }
615
+ actual_endpoint = idres.instance_variable_get(:@endpoint)
616
+ assert_equal(actual_endpoint, expected_endpoint)
617
+
618
+ end
619
+
562
620
  def test_openid2_no_op_endpoint
563
621
  assert_protocol_error("Missing required field: "\
564
622
  "<#{OPENID2_NS}>op_endpoint") {
@@ -603,12 +661,12 @@ module OpenID
603
661
  'identity' => 'sour grapes',
604
662
  'claimed_id' => 'monkeysoft',
605
663
  'op_endpoint' => 'Phone Home'}) do |idres|
606
- idres.instance_def(:discover_and_verify) do |to_match|
664
+ idres.instance_def(:discover_and_verify) do
607
665
  @endpoint = endpoint
608
666
  end
609
667
  end
610
668
  }
611
- assert(endpoint.equal?(result))
669
+ assert_equal(endpoint, result)
612
670
  end
613
671
 
614
672
 
@@ -626,7 +684,7 @@ module OpenID
626
684
  'claimed_id' => 'monkeysoft',
627
685
  'op_endpoint' => 'Green Cheese'}) do |idres|
628
686
  idres.extend(InstanceDefExtension)
629
- idres.instance_def(:discover_and_verify) do |to_match|
687
+ idres.instance_def(:discover_and_verify) do
630
688
  @endpoint = endpoint
631
689
  end
632
690
  end
@@ -669,8 +727,9 @@ module OpenID
669
727
 
670
728
  idres = IdResHandler.new(msg, nil, nil, @endpoint)
671
729
  idres.extend(InstanceDefExtension)
672
- idres.instance_def(:discover_and_verify) { |to_match|
673
- me.assert_equal(endpoint.claimed_id, to_match.claimed_id)
730
+ idres.instance_def(:discover_and_verify) { |claimed_id, to_match|
731
+ me.assert_equal(endpoint.claimed_id, to_match[0].claimed_id)
732
+ me.assert_equal(claimed_id, endpoint.claimed_id)
674
733
  raise ProtocolError, text
675
734
  }
676
735
  assert_log_matches('Error attempting to use stored',
@@ -709,7 +768,7 @@ module OpenID
709
768
  assert_raises(verified_error) {
710
769
  call_verify_modify({'ns' => OPENID1_NS,
711
770
  'identity' => @endpoint.local_id}) { |idres|
712
- idres.instance_def(:discover_and_verify) do |to_match|
771
+ idres.instance_def(:discover_and_verify) do
713
772
  raise verified_error
714
773
  end
715
774
  }
@@ -817,7 +876,7 @@ module OpenID
817
876
  assert_log_matches('Performing discovery on') do
818
877
  assert_protocol_error('No OpenID information found') do
819
878
  OpenID.with_method_overridden(:discover, disco) do
820
- idres.send(:discover_and_verify, endpoint)
879
+ idres.send(:discover_and_verify, :sentinel, [endpoint])
821
880
  end
822
881
  end
823
882
  end
@@ -834,7 +893,8 @@ module OpenID
834
893
  idres = IdResHandler.new(nil, nil)
835
894
  assert_log_matches('Discovery verification failure') do
836
895
  assert_protocol_error('No matching endpoint') do
837
- idres.send(:verify_discovered_services, [], endpoint)
896
+ idres.send(:verify_discovered_services,
897
+ 'http://bogus.id/', [], [endpoint])
838
898
  end
839
899
  end
840
900
  end