PageRenderTime 44ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/gems/ruby-openid-2.1.2/test/test_idres.rb

http://github.com/fudgestudios/bort
Ruby | 904 lines | 776 code | 110 blank | 18 comment | 3 complexity | e088cb951d23f6029e57af923a0dbeec MD5 | raw file
Possible License(s): MIT, Apache-2.0
  1. require "testutil"
  2. require "util"
  3. require "test/unit"
  4. require "openid/consumer/idres"
  5. require "openid/protocolerror"
  6. require "openid/store/memory"
  7. require "openid/store/nonce"
  8. module OpenID
  9. class Consumer
  10. class IdResHandler
  11. # Subclass of IdResHandler that doesn't do verification upon
  12. # construction. All of the tests call this, except for the ones
  13. # explicitly for id_res.
  14. class IdResHandler < OpenID::Consumer::IdResHandler
  15. def id_res
  16. end
  17. end
  18. class CheckForFieldsTest < Test::Unit::TestCase
  19. include ProtocolErrorMixin
  20. BASE_FIELDS = ['return_to', 'assoc_handle', 'sig', 'signed']
  21. OPENID2_FIELDS = BASE_FIELDS + ['op_endpoint']
  22. OPENID1_FIELDS = BASE_FIELDS + ['identity']
  23. OPENID1_SIGNED = ['return_to', 'identity']
  24. OPENID2_SIGNED =
  25. OPENID1_SIGNED + ['response_nonce', 'claimed_id', 'assoc_handle']
  26. def mkMsg(ns, fields, signed_fields)
  27. msg = Message.new(ns)
  28. fields.each do |field|
  29. msg.set_arg(OPENID_NS, field, "don't care")
  30. end
  31. if fields.member?('signed')
  32. msg.set_arg(OPENID_NS, 'signed', signed_fields.join(','))
  33. end
  34. msg
  35. end
  36. 1.times do # so as not to bleed into the outer namespace
  37. n = 0
  38. [[],
  39. ['foo'],
  40. ['bar', 'baz'],
  41. ].each do |signed_fields|
  42. test = lambda do
  43. msg = mkMsg(OPENID2_NS, OPENID2_FIELDS, signed_fields)
  44. idres = IdResHandler.new(msg, nil)
  45. assert_equal(signed_fields, idres.send(:signed_list))
  46. # Do it again to make sure logic for caching is correct
  47. assert_equal(signed_fields, idres.send(:signed_list))
  48. end
  49. define_method("test_signed_list_#{n += 1}", test)
  50. end
  51. end
  52. # test all missing fields for OpenID 1 and 2
  53. 1.times do
  54. [["openid1", OPENID1_NS, OPENID1_FIELDS],
  55. ["openid2", OPENID2_NS, OPENID2_FIELDS],
  56. ].each do |ver, ns, all_fields|
  57. all_fields.each do |field|
  58. test = lambda do
  59. fields = all_fields.dup
  60. fields.delete(field)
  61. msg = mkMsg(ns, fields, [])
  62. idres = IdResHandler.new(msg, nil)
  63. assert_protocol_error("Missing required field #{field}") {
  64. idres.send(:check_for_fields)
  65. }
  66. end
  67. define_method("test_#{ver}_check_missing_#{field}", test)
  68. end
  69. end
  70. end
  71. # Test all missing signed for OpenID 1 and 2
  72. 1.times do
  73. [["openid1", OPENID1_NS, OPENID1_FIELDS, OPENID1_SIGNED],
  74. ["openid2", OPENID2_NS, OPENID2_FIELDS, OPENID2_SIGNED],
  75. ].each do |ver, ns, all_fields, signed_fields|
  76. signed_fields.each do |signed_field|
  77. test = lambda do
  78. fields = signed_fields.dup
  79. fields.delete(signed_field)
  80. msg = mkMsg(ns, all_fields, fields)
  81. # Make sure the signed field is actually in the request
  82. msg.set_arg(OPENID_NS, signed_field, "don't care")
  83. idres = IdResHandler.new(msg, nil)
  84. assert_protocol_error("#{signed_field.inspect} not signed") {
  85. idres.send(:check_for_fields)
  86. }
  87. end
  88. define_method("test_#{ver}_check_missing_signed_#{signed_field}", test)
  89. end
  90. end
  91. end
  92. def test_112
  93. args = {'openid.assoc_handle' => 'fa1f5ff0-cde4-11dc-a183-3714bfd55ca8',
  94. 'openid.claimed_id' => 'http://binkley.lan/user/test01',
  95. 'openid.identity' => 'http://test01.binkley.lan/',
  96. 'openid.mode' => 'id_res',
  97. 'openid.ns' => 'http://specs.openid.net/auth/2.0',
  98. 'openid.ns.pape' => 'http://specs.openid.net/extensions/pape/1.0',
  99. 'openid.op_endpoint' => 'http://binkley.lan/server',
  100. 'openid.pape.auth_policies' => 'none',
  101. 'openid.pape.auth_time' => '2008-01-28T20:42:36Z',
  102. 'openid.pape.nist_auth_level' => '0',
  103. 'openid.response_nonce' => '2008-01-28T21:07:04Z99Q=',
  104. 'openid.return_to' => 'http://binkley.lan:8001/process?janrain_nonce=2008-01-28T21%3A07%3A02Z0tMIKx',
  105. 'openid.sig' => 'YJlWH4U6SroB1HoPkmEKx9AyGGg=',
  106. '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'
  107. }
  108. assert_equal(args['openid.ns'], OPENID2_NS)
  109. incoming = Message.from_post_args(args)
  110. assert(incoming.is_openid2)
  111. idres = IdResHandler.new(incoming, nil)
  112. car = idres.send(:create_check_auth_request)
  113. expected_args = args.dup
  114. expected_args['openid.mode'] = 'check_authentication'
  115. expected = Message.from_post_args(expected_args)
  116. assert(expected.is_openid2)
  117. assert_equal(expected, car)
  118. assert_equal(expected_args, car.to_post_args)
  119. end
  120. def test_no_signed_list
  121. msg = Message.new(OPENID2_NS)
  122. idres = IdResHandler.new(msg, nil)
  123. assert_protocol_error("Response missing signed") {
  124. idres.send(:signed_list)
  125. }
  126. end
  127. def test_success_openid1
  128. msg = mkMsg(OPENID1_NS, OPENID1_FIELDS, OPENID1_SIGNED)
  129. idres = IdResHandler.new(msg, nil)
  130. assert_nothing_raised {
  131. idres.send(:check_for_fields)
  132. }
  133. end
  134. end
  135. class ReturnToArgsTest < Test::Unit::TestCase
  136. include OpenID::ProtocolErrorMixin
  137. def check_return_to_args(query)
  138. idres = IdResHandler.new(Message.from_post_args(query), nil)
  139. class << idres
  140. def verify_return_to_base(unused)
  141. end
  142. end
  143. idres.send(:verify_return_to)
  144. end
  145. def assert_bad_args(msg, query)
  146. assert_protocol_error(msg) {
  147. check_return_to_args(query)
  148. }
  149. end
  150. def test_return_to_args_okay
  151. assert_nothing_raised {
  152. check_return_to_args({
  153. 'openid.mode' => 'id_res',
  154. 'openid.return_to' => 'http://example.com/?foo=bar',
  155. 'foo' => 'bar',
  156. })
  157. }
  158. end
  159. def test_unexpected_arg_okay
  160. assert_bad_args("Unexpected parameter", {
  161. 'openid.mode' => 'id_res',
  162. 'openid.return_to' => 'http://example.com/',
  163. 'foo' => 'bar',
  164. })
  165. end
  166. def test_return_to_mismatch
  167. assert_bad_args('Message missing ret', {
  168. 'openid.mode' => 'id_res',
  169. 'openid.return_to' => 'http://example.com/?foo=bar',
  170. })
  171. assert_bad_args("Parameter 'foo' val", {
  172. 'openid.mode' => 'id_res',
  173. 'openid.return_to' => 'http://example.com/?foo=bar',
  174. 'foo' => 'foos',
  175. })
  176. end
  177. end
  178. class ReturnToVerifyTest < Test::Unit::TestCase
  179. def test_bad_return_to
  180. return_to = "http://some.url/path?foo=bar"
  181. m = Message.new(OPENID1_NS)
  182. m.set_arg(OPENID_NS, 'mode', 'cancel')
  183. m.set_arg(BARE_NS, 'foo', 'bar')
  184. # Scheme, authority, and path differences are checked by
  185. # IdResHandler.verify_return_to_base. Query args checked by
  186. # IdResHandler.verify_return_to_args.
  187. [
  188. # Scheme only
  189. "https://some.url/path?foo=bar",
  190. # Authority only
  191. "http://some.url.invalid/path?foo=bar",
  192. # Path only
  193. "http://some.url/path_extra?foo=bar",
  194. # Query args differ
  195. "http://some.url/path?foo=bar2",
  196. "http://some.url/path?foo2=bar",
  197. ].each do |bad|
  198. m.set_arg(OPENID_NS, 'return_to', bad)
  199. idres = IdResHandler.new(m, return_to)
  200. assert_raises(ProtocolError) {
  201. idres.send(:verify_return_to)
  202. }
  203. end
  204. end
  205. def test_good_return_to
  206. base = 'http://example.janrain.com/path'
  207. [ [base, {}],
  208. [base + "?another=arg", {'another' => 'arg'}],
  209. [base + "?another=arg#frag", {'another' => 'arg'}],
  210. ['HTTP'+base[4..-1], {}],
  211. [base.sub('com', 'COM'), {}],
  212. ['http://example.janrain.com:80/path', {}],
  213. ['http://example.janrain.com/p%61th', {}],
  214. ['http://example.janrain.com/./path',{}],
  215. ].each do |return_to, args|
  216. args['openid.return_to'] = return_to
  217. msg = Message.from_post_args(args)
  218. idres = IdResHandler.new(msg, base)
  219. assert_nothing_raised {
  220. idres.send(:verify_return_to)
  221. }
  222. end
  223. end
  224. end
  225. class DummyEndpoint
  226. attr_accessor :server_url
  227. def initialize(server_url)
  228. @server_url = server_url
  229. end
  230. end
  231. class CheckSigTest < Test::Unit::TestCase
  232. include ProtocolErrorMixin
  233. include TestUtil
  234. def setup
  235. @assoc = GoodAssoc.new('{not_dumb}')
  236. @store = Store::Memory.new
  237. @server_url = 'http://server.url/'
  238. @endpoint = DummyEndpoint.new(@server_url)
  239. @store.store_association(@server_url, @assoc)
  240. @message = Message.from_post_args({
  241. 'openid.mode' => 'id_res',
  242. 'openid.identity' => '=example',
  243. 'openid.sig' => GOODSIG,
  244. 'openid.assoc_handle' => @assoc.handle,
  245. 'openid.signed' => 'mode,identity,assoc_handle,signed',
  246. 'frobboz' => 'banzit',
  247. })
  248. end
  249. def call_idres_method(method_name)
  250. idres = IdResHandler.new(@message, nil, @store, @endpoint)
  251. idres.extend(InstanceDefExtension)
  252. yield idres
  253. idres.send(method_name)
  254. end
  255. def call_check_sig(&proc)
  256. call_idres_method(:check_signature, &proc)
  257. end
  258. def no_check_auth(idres)
  259. idres.instance_def(:check_auth) { fail "Called check_auth" }
  260. end
  261. def test_sign_good
  262. assert_nothing_raised {
  263. call_check_sig(&method(:no_check_auth))
  264. }
  265. end
  266. def test_bad_sig
  267. @message.set_arg(OPENID_NS, 'sig', 'bad sig!')
  268. assert_protocol_error('Bad signature') {
  269. call_check_sig(&method(:no_check_auth))
  270. }
  271. end
  272. def test_check_auth_ok
  273. @message.set_arg(OPENID_NS, 'assoc_handle', 'dumb-handle')
  274. check_auth_called = false
  275. call_check_sig do |idres|
  276. idres.instance_def(:check_auth) do
  277. check_auth_called = true
  278. end
  279. end
  280. assert(check_auth_called)
  281. end
  282. def test_check_auth_ok_no_store
  283. @store = nil
  284. check_auth_called = false
  285. call_check_sig do |idres|
  286. idres.instance_def(:check_auth) do
  287. check_auth_called = true
  288. end
  289. end
  290. assert(check_auth_called)
  291. end
  292. def test_expired_assoc
  293. @assoc.expires_in = -1
  294. @store.store_association(@server_url, @assoc)
  295. assert_protocol_error('Association with') {
  296. call_check_sig(&method(:no_check_auth))
  297. }
  298. end
  299. def call_check_auth(&proc)
  300. assert_log_matches("Using 'check_authentication'") {
  301. call_idres_method(:check_auth, &proc)
  302. }
  303. end
  304. def test_check_auth_create_fail
  305. assert_protocol_error("Could not generate") {
  306. call_check_auth do |idres|
  307. idres.instance_def(:create_check_auth_request) do
  308. raise Message::KeyNotFound, "Testing"
  309. end
  310. end
  311. }
  312. end
  313. def test_check_auth_okay
  314. OpenID.extend(OverrideMethodMixin)
  315. me = self
  316. send_resp = Proc.new do |req, server_url|
  317. me.assert_equal(:req, req)
  318. :expected_response
  319. end
  320. OpenID.with_method_overridden(:make_kv_post, send_resp) do
  321. final_resp = call_check_auth do |idres|
  322. idres.instance_def(:create_check_auth_request) {
  323. :req
  324. }
  325. idres.instance_def(:process_check_auth_response) do |resp|
  326. me.assert_equal(:expected_response, resp)
  327. end
  328. end
  329. end
  330. end
  331. def test_check_auth_process_fail
  332. OpenID.extend(OverrideMethodMixin)
  333. me = self
  334. send_resp = Proc.new do |req, server_url|
  335. me.assert_equal(:req, req)
  336. :expected_response
  337. end
  338. OpenID.with_method_overridden(:make_kv_post, send_resp) do
  339. assert_protocol_error("Testing") do
  340. final_resp = call_check_auth do |idres|
  341. idres.instance_def(:create_check_auth_request) { :req }
  342. idres.instance_def(:process_check_auth_response) do |resp|
  343. me.assert_equal(:expected_response, resp)
  344. raise ProtocolError, "Testing"
  345. end
  346. end
  347. end
  348. end
  349. end
  350. 1.times do
  351. # Fields from the signed list
  352. ['mode', 'identity', 'assoc_handle'
  353. ].each do |field|
  354. test = lambda do
  355. @message.del_arg(OPENID_NS, field)
  356. assert_raises(Message::KeyNotFound) {
  357. call_idres_method(:create_check_auth_request) {}
  358. }
  359. end
  360. define_method("test_create_check_auth_missing_#{field}", test)
  361. end
  362. end
  363. def test_create_check_auth_request_success
  364. ca_msg = call_idres_method(:create_check_auth_request) {}
  365. expected = @message.copy
  366. expected.set_arg(OPENID_NS, 'mode', 'check_authentication')
  367. assert_equal(expected, ca_msg)
  368. end
  369. end
  370. class CheckAuthResponseTest < Test::Unit::TestCase
  371. include TestUtil
  372. include ProtocolErrorMixin
  373. def setup
  374. @message = Message.from_openid_args({
  375. 'is_valid' => 'true',
  376. })
  377. @assoc = GoodAssoc.new
  378. @store = Store::Memory.new
  379. @server_url = 'http://invalid/'
  380. @endpoint = DummyEndpoint.new(@server_url)
  381. @idres = IdResHandler.new(nil, nil, @store, @endpoint)
  382. end
  383. def call_process
  384. @idres.send(:process_check_auth_response, @message)
  385. end
  386. def test_valid
  387. assert_log_matches() { call_process }
  388. end
  389. def test_invalid
  390. for is_valid in ['false', 'monkeys']
  391. @message.set_arg(OPENID_NS, 'is_valid', 'false')
  392. assert_protocol_error("Server #{@server_url} responds") {
  393. assert_log_matches() { call_process }
  394. }
  395. end
  396. end
  397. def test_valid_invalidate
  398. @message.set_arg(OPENID_NS, 'invalidate_handle', 'cheese')
  399. assert_log_matches("Received 'invalidate_handle'") { call_process }
  400. end
  401. def test_invalid_invalidate
  402. @message.set_arg(OPENID_NS, 'invalidate_handle', 'cheese')
  403. for is_valid in ['false', 'monkeys']
  404. @message.set_arg(OPENID_NS, 'is_valid', 'false')
  405. assert_protocol_error("Server #{@server_url} responds") {
  406. assert_log_matches("Received 'invalidate_handle'") {
  407. call_process
  408. }
  409. }
  410. end
  411. end
  412. def test_invalidate_no_store
  413. @idres.instance_variable_set(:@store, nil)
  414. @message.set_arg(OPENID_NS, 'invalidate_handle', 'cheese')
  415. assert_log_matches("Received 'invalidate_handle'",
  416. 'Unexpectedly got "invalidate_handle"') {
  417. call_process
  418. }
  419. end
  420. end
  421. class NonceTest < Test::Unit::TestCase
  422. include TestUtil
  423. include ProtocolErrorMixin
  424. def setup
  425. @store = Object.new
  426. class << @store
  427. attr_accessor :nonces, :succeed
  428. def use_nonce(server_url, time, extra)
  429. @nonces << [server_url, time, extra]
  430. @succeed
  431. end
  432. end
  433. @store.nonces = []
  434. @nonce = Nonce.mk_nonce
  435. end
  436. def call_check_nonce(post_args, succeed=false)
  437. response = Message.from_post_args(post_args)
  438. if !@store.nil?
  439. @store.succeed = succeed
  440. end
  441. idres = IdResHandler.new(response, nil, @store, nil)
  442. idres.send(:check_nonce)
  443. end
  444. def test_openid1_success
  445. assert_nothing_raised {
  446. call_check_nonce({'rp_nonce' => @nonce}, true)
  447. }
  448. end
  449. def test_openid1_missing
  450. assert_protocol_error('Nonce missing') { call_check_nonce({}) }
  451. end
  452. def test_openid2_ignore_rp_nonce
  453. assert_protocol_error('Nonce missing') {
  454. call_check_nonce({'rp_nonce' => @nonce,
  455. 'openid.ns' => OPENID2_NS})
  456. }
  457. end
  458. def test_openid2_success
  459. assert_nothing_raised {
  460. call_check_nonce({'openid.response_nonce' => @nonce,
  461. 'openid.ns' => OPENID2_NS}, true)
  462. }
  463. end
  464. def test_openid1_ignore_response_nonce
  465. assert_protocol_error('Nonce missing') {
  466. call_check_nonce({'openid.response_nonce' => @nonce})
  467. }
  468. end
  469. def test_no_store
  470. @store = nil
  471. assert_nothing_raised {
  472. call_check_nonce({'rp_nonce' => @nonce})
  473. }
  474. end
  475. def test_already_used
  476. assert_protocol_error('Nonce already used') {
  477. call_check_nonce({'rp_nonce' => @nonce}, false)
  478. }
  479. end
  480. def test_malformed_nonce
  481. assert_protocol_error('Malformed nonce') {
  482. call_check_nonce({'rp_nonce' => 'whee!'})
  483. }
  484. end
  485. end
  486. class DiscoveryVerificationTest < Test::Unit::TestCase
  487. include ProtocolErrorMixin
  488. include TestUtil
  489. def setup
  490. @endpoint = OpenIDServiceEndpoint.new
  491. end
  492. def call_verify(msg_args)
  493. call_verify_modify(msg_args){}
  494. end
  495. def call_verify_modify(msg_args)
  496. msg = Message.from_openid_args(msg_args)
  497. idres = IdResHandler.new(msg, nil, nil, @endpoint)
  498. idres.extend(InstanceDefExtension)
  499. yield idres
  500. idres.send(:verify_discovery_results)
  501. idres.instance_variable_get(:@endpoint)
  502. end
  503. def assert_verify_protocol_error(error_prefix, openid_args)
  504. assert_protocol_error(error_prefix) {call_verify(openid_args)}
  505. end
  506. def test_openid1_no_local_id
  507. @endpoint.claimed_id = 'http://invalid/'
  508. assert_verify_protocol_error("Missing required field: "\
  509. "<#{OPENID1_NS}>identity", {})
  510. end
  511. def test_openid1_no_endpoint
  512. @endpoint = nil
  513. assert_raises(ProtocolError) {
  514. call_verify({'identity' => 'snakes on a plane'})
  515. }
  516. end
  517. def test_openid1_fallback_1_0
  518. claimed_id = 'http://claimed.id/'
  519. @endpoint = nil
  520. resp_mesg = Message.from_openid_args({
  521. 'ns' => OPENID1_NS,
  522. 'identity' => claimed_id,
  523. })
  524. # Pass the OpenID 1 claimed_id this way since we're passing
  525. # None for the endpoint.
  526. resp_mesg.set_arg(BARE_NS, 'openid1_claimed_id', claimed_id)
  527. # We expect the OpenID 1 discovery verification to try
  528. # matching the discovered endpoint against the 1.1 type and
  529. # fall back to 1.0.
  530. expected_endpoint = OpenIDServiceEndpoint.new
  531. expected_endpoint.type_uris = [OPENID_1_0_TYPE]
  532. expected_endpoint.local_id = nil
  533. expected_endpoint.claimed_id = claimed_id
  534. hacked_discover = Proc.new { ['unused', [expected_endpoint]] }
  535. idres = IdResHandler.new(resp_mesg, nil, nil, @endpoint)
  536. assert_log_matches('Performing discovery') {
  537. OpenID.with_method_overridden(:discover, hacked_discover) {
  538. idres.send(:verify_discovery_results)
  539. }
  540. }
  541. actual_endpoint = idres.instance_variable_get(:@endpoint)
  542. assert_equal(actual_endpoint, expected_endpoint)
  543. end
  544. def test_openid2_no_op_endpoint
  545. assert_protocol_error("Missing required field: "\
  546. "<#{OPENID2_NS}>op_endpoint") {
  547. call_verify({'ns'=>OPENID2_NS})
  548. }
  549. end
  550. def test_openid2_local_id_no_claimed
  551. assert_verify_protocol_error('openid.identity is present without',
  552. {'ns' => OPENID2_NS,
  553. 'op_endpoint' => 'Phone Home',
  554. 'identity' => 'Jorge Lius Borges'})
  555. end
  556. def test_openid2_no_local_id_claimed
  557. assert_log_matches() {
  558. assert_protocol_error('openid.claimed_id is present without') {
  559. call_verify({'ns' => OPENID2_NS,
  560. 'op_endpoint' => 'Phone Home',
  561. 'claimed_id' => 'Manuel Noriega'})
  562. }
  563. }
  564. end
  565. def test_openid2_no_identifiers
  566. op_endpoint = 'Phone Home'
  567. result_endpoint = assert_log_matches() {
  568. call_verify({'ns' => OPENID2_NS,
  569. 'op_endpoint' => op_endpoint})
  570. }
  571. assert(result_endpoint.is_op_identifier)
  572. assert_equal(op_endpoint, result_endpoint.server_url)
  573. assert(result_endpoint.claimed_id.nil?)
  574. end
  575. def test_openid2_no_endpoint_does_disco
  576. endpoint = OpenIDServiceEndpoint.new
  577. endpoint.claimed_id = 'monkeysoft'
  578. @endpoint = nil
  579. result = assert_log_matches('No pre-discovered') {
  580. call_verify_modify({'ns' => OPENID2_NS,
  581. 'identity' => 'sour grapes',
  582. 'claimed_id' => 'monkeysoft',
  583. 'op_endpoint' => 'Phone Home'}) do |idres|
  584. idres.instance_def(:discover_and_verify) do
  585. @endpoint = endpoint
  586. end
  587. end
  588. }
  589. assert_equal(endpoint, result)
  590. end
  591. def test_openid2_mismatched_does_disco
  592. @endpoint.claimed_id = 'nothing special, but different'
  593. @endpoint.local_id = 'green cheese'
  594. endpoint = OpenIDServiceEndpoint.new
  595. endpoint.claimed_id = 'monkeysoft'
  596. result = assert_log_matches('Error attempting to use stored',
  597. 'Attempting discovery') {
  598. call_verify_modify({'ns' => OPENID2_NS,
  599. 'identity' => 'sour grapes',
  600. 'claimed_id' => 'monkeysoft',
  601. 'op_endpoint' => 'Green Cheese'}) do |idres|
  602. idres.extend(InstanceDefExtension)
  603. idres.instance_def(:discover_and_verify) do
  604. @endpoint = endpoint
  605. end
  606. end
  607. }
  608. assert(endpoint.equal?(result))
  609. end
  610. def test_openid2_use_pre_discovered
  611. @endpoint.local_id = 'my identity'
  612. @endpoint.claimed_id = 'http://i-am-sam/'
  613. @endpoint.server_url = 'Phone Home'
  614. @endpoint.type_uris = [OPENID_2_0_TYPE]
  615. result = assert_log_matches() {
  616. call_verify({'ns' => OPENID2_NS,
  617. 'identity' => @endpoint.local_id,
  618. 'claimed_id' => @endpoint.claimed_id,
  619. 'op_endpoint' => @endpoint.server_url
  620. })
  621. }
  622. assert(result.equal?(@endpoint))
  623. end
  624. def test_openid2_use_pre_discovered_wrong_type
  625. text = "verify failed"
  626. me = self
  627. @endpoint.local_id = 'my identity'
  628. @endpoint.claimed_id = 'i am sam'
  629. @endpoint.server_url = 'Phone Home'
  630. @endpoint.type_uris = [OPENID_1_1_TYPE]
  631. endpoint = @endpoint
  632. msg = Message.from_openid_args({'ns' => OPENID2_NS,
  633. 'identity' => @endpoint.local_id,
  634. 'claimed_id' =>
  635. @endpoint.claimed_id,
  636. 'op_endpoint' =>
  637. @endpoint.server_url})
  638. idres = IdResHandler.new(msg, nil, nil, @endpoint)
  639. idres.extend(InstanceDefExtension)
  640. idres.instance_def(:discover_and_verify) { |claimed_id, to_match|
  641. me.assert_equal(endpoint.claimed_id, to_match[0].claimed_id)
  642. me.assert_equal(claimed_id, endpoint.claimed_id)
  643. raise ProtocolError, text
  644. }
  645. assert_log_matches('Error attempting to use stored',
  646. 'Attempting discovery') {
  647. assert_protocol_error(text) {
  648. idres.send(:verify_discovery_results)
  649. }
  650. }
  651. end
  652. def test_openid1_use_pre_discovered
  653. @endpoint.local_id = 'my identity'
  654. @endpoint.claimed_id = 'http://i-am-sam/'
  655. @endpoint.server_url = 'Phone Home'
  656. @endpoint.type_uris = [OPENID_1_1_TYPE]
  657. result = assert_log_matches() {
  658. call_verify({'ns' => OPENID1_NS,
  659. 'identity' => @endpoint.local_id})
  660. }
  661. assert(result.equal?(@endpoint))
  662. end
  663. def test_openid1_use_pre_discovered_wrong_type
  664. verified_error = Class.new(Exception)
  665. @endpoint.local_id = 'my identity'
  666. @endpoint.claimed_id = 'i am sam'
  667. @endpoint.server_url = 'Phone Home'
  668. @endpoint.type_uris = [OPENID_2_0_TYPE]
  669. assert_log_matches('Error attempting to use stored',
  670. 'Attempting discovery') {
  671. assert_raises(verified_error) {
  672. call_verify_modify({'ns' => OPENID1_NS,
  673. 'identity' => @endpoint.local_id}) { |idres|
  674. idres.instance_def(:discover_and_verify) do
  675. raise verified_error
  676. end
  677. }
  678. }
  679. }
  680. end
  681. def test_openid2_fragment
  682. claimed_id = "http://unittest.invalid/"
  683. claimed_id_frag = claimed_id + "#fragment"
  684. @endpoint.local_id = 'my identity'
  685. @endpoint.claimed_id = claimed_id
  686. @endpoint.server_url = 'Phone Home'
  687. @endpoint.type_uris = [OPENID_2_0_TYPE]
  688. result = assert_log_matches() {
  689. call_verify({'ns' => OPENID2_NS,
  690. 'identity' => @endpoint.local_id,
  691. 'claimed_id' => claimed_id_frag,
  692. 'op_endpoint' => @endpoint.server_url})
  693. }
  694. [:local_id, :server_url, :type_uris].each do |sym|
  695. assert_equal(@endpoint.send(sym), result.send(sym))
  696. end
  697. assert_equal(claimed_id_frag, result.claimed_id)
  698. end
  699. def test_endpoint_without_local_id
  700. # An endpoint like this with no local_id is generated as a result of
  701. # e.g. Yadis discovery with no LocalID tag.
  702. @endpoint.server_url = "http://localhost:8000/openidserver"
  703. @endpoint.claimed_id = "http://localhost:8000/id/id-jo"
  704. to_match = OpenIDServiceEndpoint.new
  705. to_match.server_url = "http://localhost:8000/openidserver"
  706. to_match.claimed_id = "http://localhost:8000/id/id-jo"
  707. to_match.local_id = "http://localhost:8000/id/id-jo"
  708. idres = IdResHandler.new(nil, nil)
  709. assert_log_matches() {
  710. result = idres.send(:verify_discovery_single, @endpoint, to_match)
  711. }
  712. end
  713. end
  714. class IdResTopLevelTest < Test::Unit::TestCase
  715. def test_id_res
  716. endpoint = OpenIDServiceEndpoint.new
  717. endpoint.server_url = 'http://invalid/server'
  718. endpoint.claimed_id = 'http://my.url/'
  719. endpoint.local_id = 'http://invalid/username'
  720. endpoint.type_uris = [OPENID_2_0_TYPE]
  721. assoc = GoodAssoc.new
  722. store = Store::Memory.new
  723. store.store_association(endpoint.server_url, assoc)
  724. signed_fields =
  725. [
  726. 'response_nonce',
  727. 'op_endpoint',
  728. 'assoc_handle',
  729. 'identity',
  730. 'claimed_id',
  731. 'ns',
  732. 'return_to',
  733. ]
  734. return_to = 'http://return.to/'
  735. args = {
  736. 'ns' => OPENID2_NS,
  737. 'return_to' => return_to,
  738. 'claimed_id' => endpoint.claimed_id,
  739. 'identity' => endpoint.local_id,
  740. 'assoc_handle' => assoc.handle,
  741. 'op_endpoint' => endpoint.server_url,
  742. 'response_nonce' => Nonce.mk_nonce,
  743. 'signed' => signed_fields.join(','),
  744. 'sig' => GOODSIG,
  745. }
  746. msg = Message.from_openid_args(args)
  747. idres = OpenID::Consumer::IdResHandler.new(msg, return_to,
  748. store, endpoint)
  749. assert_equal(idres.signed_fields,
  750. signed_fields.map {|f|'openid.' + f})
  751. end
  752. end
  753. class DiscoverAndVerifyTest < Test::Unit::TestCase
  754. include ProtocolErrorMixin
  755. include TestUtil
  756. def test_no_services
  757. me = self
  758. disco = Proc.new do |e|
  759. me.assert_equal(e, :sentinel)
  760. [:undefined, []]
  761. end
  762. endpoint = OpenIDServiceEndpoint.new
  763. endpoint.claimed_id = :sentinel
  764. idres = IdResHandler.new(nil, nil)
  765. assert_log_matches('Performing discovery on') do
  766. assert_protocol_error('No OpenID information found') do
  767. OpenID.with_method_overridden(:discover, disco) do
  768. idres.send(:discover_and_verify, :sentinel, [endpoint])
  769. end
  770. end
  771. end
  772. end
  773. end
  774. class VerifyDiscoveredServicesTest < Test::Unit::TestCase
  775. include ProtocolErrorMixin
  776. include TestUtil
  777. def test_no_services
  778. endpoint = OpenIDServiceEndpoint.new
  779. endpoint.claimed_id = :sentinel
  780. idres = IdResHandler.new(nil, nil)
  781. assert_log_matches('Discovery verification failure') do
  782. assert_protocol_error('No matching endpoint') do
  783. idres.send(:verify_discovered_services,
  784. 'http://bogus.id/', [], [endpoint])
  785. end
  786. end
  787. end
  788. end
  789. end
  790. end
  791. end