Skip to content
This repository was archived by the owner on Jul 24, 2023. It is now read-only.

Commit fa1fde9

Browse files
author
http://j3h.us/
committed
[project @ Ported Python id_res tests]
1 parent 2ec6574 commit fa1fde9

File tree

3 files changed

+397
-79
lines changed

3 files changed

+397
-79
lines changed

lib/openid/consumer/idres.rb

Lines changed: 107 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,24 @@
11
require "openid/message"
22
require "openid/protocolerror"
33
require "openid/kvpost"
4+
require "openid/consumer/discovery"
45

56
module OpenID
7+
class TypeURIMismatch < ProtocolError
8+
attr_reader :type_uri, :endpoint
9+
10+
def initialize(type_uri, endpoint)
11+
@type_uri = type_uri
12+
@endpoint = endpoint
13+
end
14+
end
15+
616
class Consumer
717
class IdResHandler
8-
attr_accessor(:openid1_nonce_query_arg_name,
9-
:openid1_return_to_identifier_name)
18+
attr_accessor :openid1_nonce_query_arg_name,
19+
:openid1_return_to_identifier_name
20+
21+
attr_reader :endpoint, :message
1022

1123
def initialize(message, return_to, store=nil, endpoint=nil)
1224
@store = store # Fer the nonce and invalidate_handle
@@ -16,21 +28,29 @@ def initialize(message, return_to, store=nil, endpoint=nil)
1628
@signed_list = nil
1729
@openid1_nonce_query_arg_name = 'rp_nonce'
1830
@openid1_return_to_identifier_name = 'openid1_claimed_id'
31+
32+
# Start the verification process
33+
id_res
1934
end
2035

36+
def signed_fields
37+
signed_list.map {|x| 'openid.' + x}
38+
end
39+
40+
protected
41+
42+
# This method will raise ProtocolError unless the request is a
43+
# valid id_res response. Once it has been verified, the methods
44+
# 'endpoint', 'message', and 'signed_fields' contain the
45+
# verified information.
2146
def id_res
2247
check_for_fields
2348
verify_return_to
2449
verify_discovery_results
2550
check_signature
2651
check_nonce
27-
28-
signed_fields = signed_list.map {|x| 'openid.' + x}
29-
SuccessResponse(@endpoint, @message, signed_fields)
3052
end
3153

32-
protected
33-
3454
def server_url
3555
@endpoint.nil? ? nil : @endpoint.server_url
3656
end
@@ -251,44 +271,49 @@ def check_nonce
251271
end
252272

253273
def verify_discovery_results
254-
case openid_namespace
255-
when OPENID1_NS
256-
verify_discovery_results_openid1
257-
when OPENID2_NS
258-
verify_discovery_results_openid2
259-
else
260-
raise StandardError, "Not reached: #{openid_namespace}"
274+
begin
275+
case openid_namespace
276+
when OPENID1_NS
277+
verify_discovery_results_openid1
278+
when OPENID2_NS
279+
verify_discovery_results_openid2
280+
else
281+
raise StandardError, "Not reached: #{openid_namespace}"
282+
end
283+
rescue Message::KeyNotFound => why
284+
raise ProtocolError, "Missing required field: #{why.message}"
261285
end
262286
end
263287

264288
def verify_discovery_results_openid2
265-
to_match = XXXOpenIDServiceEndpoint.new
289+
to_match = OpenIDServiceEndpoint.new
266290
to_match.type_uris = [OPENID_2_0_TYPE]
267291
to_match.claimed_id = fetch('claimed_id', nil)
268292
to_match.local_id = fetch('identity', nil)
269293
to_match.server_url = fetch('op_endpoint')
270294

271295
if to_match.claimed_id.nil? && !to_match.local_id.nil?
272-
raise ProtocoError, ('openid.identity is present without '\
273-
'openid.claimed_id')
296+
raise ProtocolError, ('openid.identity is present without '\
297+
'openid.claimed_id')
274298
elsif !to_match.claimed_id.nil? && to_match.local_id.nil?
275-
raise ProtocoError, ('openid.claimed_id is present without '\
276-
'openid.identity')
299+
raise ProtocolError, ('openid.claimed_id is present without '\
300+
'openid.identity')
277301

278302
# This is a response without identifiers, so there's really no
279303
# checking that we can do, so return an endpoint that's for
280304
# the specified `openid.op_endpoint'
281305
elsif to_match.claimed_id.nil?
282306
@endpoint =
283307
OpenIDServiceEndpoint.from_op_endpoint_url(to_match.server_url)
308+
return
284309
end
285310

286311
if @endpoint.nil?
287312
Util.log('No pre-discovered information supplied')
288313
discover_and_verify(to_match)
289314
else
290315
begin
291-
verify_discovery_single(@endpoint)
316+
verify_discovery_single(@endpoint, to_match)
292317
rescue ProtocolError => why
293318
Util.log("Error attempting to use stored discovery "\
294319
"information: #{why.message}")
@@ -325,19 +350,15 @@ def verify_discovery_results_openid1
325350
# Restore delegate information from the initiation phase
326351
to_match.claimed_id = claimed_id
327352

328-
if to_match.local_id.nil?
329-
raise ProtocolError, 'Missing required field "openid.identity"'
330-
end
331-
332353
to_match_1_0 = to_match.dup
333354
to_match_1_0.type_uris = [OPENID_1_0_TYPE]
334355

335356
if !@endpoint.nil?
336357
begin
337358
begin
338-
verify_discovery_single(to_match)
359+
verify_discovery_single(@endpoint, to_match)
339360
rescue TypeURIMismatch
340-
verify_discovery_single(to_match_1_0)
361+
verify_discovery_single(@endpoint, to_match_1_0)
341362
end
342363
rescue ProtocolError => why
343364
Util.log('Error attempting to use stored discovery information: ' +
@@ -358,64 +379,17 @@ def verify_discovery_results_openid1
358379
end
359380
end
360381

361-
def verify_discovery_single(to_match)
362-
# Every type URI that's in the to_match endpoint has to be
363-
# present in the discovered endpoint.
364-
for type_uri in to_match.type_uris
365-
if !@endpoint.uses_extension(type_uri)
366-
raise TypeURIMismatch(type_uri, @endpoint)
367-
end
368-
end
369-
370-
# Fragments do not influence discovery, so we can't compare a
371-
# claimed identifier with a fragment to discovered information.
372-
defragged_claimed_id = claimed_id.dup
373-
defragged_claimed_id.fragment = nil
374-
375-
if defragged_claimed_id != endpoint.claimed_id
376-
raise ProtocolError, ("Claimed ID does not match (different "\
377-
"subjects!), Expected "\
378-
"#{defragged_claimed_id}, got "\
379-
"#{@endpoint.claimed_id}")
380-
end
381-
382-
if to_match.get_local_id != endpoint.get_local_id
383-
raise ProtocolError, ("local_id mismatch. Expected "\
384-
"#{to_match.get_local_id}, got "\
385-
"#{@endpoint.get_local_id}")
386-
end
387-
388-
# If the server URL is nil, this must be an OpenID 1
389-
# response, because op_endpoint is a required parameter in
390-
# OpenID 2. In that case, we don't actually care what the
391-
# discovered server_url is, because signature checking or
392-
# check_auth should take care of that check for us.
393-
if to_match.server_url.nil?
394-
if to_match.preferred_namespace == OPENID1_NS
395-
raise StandardError,
396-
"The code calling this must ensure that OpenID 2"\
397-
"responses have a non-none `openid.op_endpoint' and"\
398-
"that it is set as the `server_url' attribute of the"\
399-
"`to_match' endpoint."
400-
end
401-
elsif to_match.server_url != @endpoint.server_url
402-
raise ProtocolError, ("OP Endpoint mismatch. Expected"\
403-
"#{to_match.server_url}, got "\
404-
"#{@endpoint.server_url}")
405-
end
406-
end
407-
408382
# Given an endpoint object created from the information in an
409383
# OpenID response, perform discovery and verify the discovery
410384
# results, returning the matching endpoint that is the result of
411385
# doing that discovery.
412386
def discover_and_verify(to_match)
413387
Util.log("Performing discovery on #{to_match.claimed_id}")
414-
_, services = discover(to_match.claimed_id)
388+
_, services = OpenID.discover(to_match.claimed_id)
415389
if services.length == 0
416390
# XXX: this might want to be something other than
417-
# ProtcolError. In Python, it's DiscoveryFailure
418-
raise ProtcolError("No OpenID information found at "\
391+
# ProtocolError. In Python, it's DiscoveryFailure
392+
raise ProtocolError("No OpenID information found at "\
419393
"#{to_match.claimed_id}")
420394
end
421395
verify_discovered_services(services, to_match)
@@ -448,6 +422,63 @@ def verify_discovered_services(services, to_match)
448422
raise ProtocolError("No matching endpoint found after "\
449423
"discovering #{to_match.claimed_id}")
450424
end
425+
426+
def verify_discovery_single(endpoint, to_match)
427+
# Every type URI that's in the to_match endpoint has to be
428+
# present in the discovered endpoint.
429+
for type_uri in to_match.type_uris
430+
if !endpoint.uses_extension(type_uri)
431+
raise TypeURIMismatch.new(type_uri, endpoint)
432+
end
433+
end
434+
435+
# Fragments do not influence discovery, so we can't compare a
436+
# claimed identifier with a fragment to discovered information.
437+
defragged_claimed_id =
438+
case Yadis::XRI.identifier_scheme(endpoint.claimed_id)
439+
when :xri
440+
endpoint.claimed_id
441+
when :uri
442+
parsed = URI.parse(endpoint.claimed_id)
443+
parsed.fragment = nil
444+
parsed.to_s
445+
else
446+
raise StandardError, 'Not reached'
447+
end
448+
449+
if defragged_claimed_id != endpoint.claimed_id
450+
raise ProtocolError, ("Claimed ID does not match (different "\
451+
"subjects!), Expected "\
452+
"#{defragged_claimed_id}, got "\
453+
"#{endpoint.claimed_id}")
454+
end
455+
456+
if to_match.get_local_id != endpoint.get_local_id
457+
raise ProtocolError, ("local_id mismatch. Expected "\
458+
"#{to_match.get_local_id}, got "\
459+
"#{endpoint.get_local_id}")
460+
end
461+
462+
# If the server URL is nil, this must be an OpenID 1
463+
# response, because op_endpoint is a required parameter in
464+
# OpenID 2. In that case, we don't actually care what the
465+
# discovered server_url is, because signature checking or
466+
# check_auth should take care of that check for us.
467+
if to_match.server_url.nil?
468+
if to_match.preferred_namespace != OPENID1_NS
469+
raise StandardError,
470+
"The code calling this must ensure that OpenID 2 "\
471+
"responses have a non-none `openid.op_endpoint' and "\
472+
"that it is set as the `server_url' attribute of the "\
473+
"`to_match' endpoint."
474+
end
475+
elsif to_match.server_url != endpoint.server_url
476+
raise ProtocolError, ("OP Endpoint mismatch. Expected"\
477+
"#{to_match.server_url}, got "\
478+
"#{endpoint.server_url}")
479+
end
480+
end
481+
451482
end
452483
end
453484
end

0 commit comments

Comments
 (0)