test_checkid_request.rb
294 lines
| 9.4 KiB
| text/x-ruby
|
RubyLexer
|
r2376 | require "openid/consumer/checkid_request" | ||
require "openid/message" | ||||
require "test/unit" | ||||
require "testutil" | ||||
require "util" | ||||
module OpenID | ||||
class Consumer | ||||
class CheckIDRequest | ||||
class DummyEndpoint | ||||
attr_accessor :preferred_namespace, :local_id, :server_url, | ||||
:is_op_identifier, :claimed_id | ||||
def initialize | ||||
@preferred_namespace = nil | ||||
@local_id = nil | ||||
@server_url = nil | ||||
@is_op_identifier = false | ||||
end | ||||
def get_local_id | ||||
@local_id | ||||
end | ||||
def compatibility_mode | ||||
@preferred_namespace == OPENID1_NS | ||||
end | ||||
end | ||||
module CheckIDTestMixin | ||||
include TestUtil | ||||
def setup | ||||
@endpoint = DummyEndpoint.new | ||||
@endpoint.local_id = 'http://server.unittest/joe' | ||||
@endpoint.claimed_id = 'http://joe.vanity.example/' | ||||
@endpoint.server_url = 'http://server.unittest/' | ||||
@endpoint.preferred_namespace = preferred_namespace | ||||
@realm = 'http://example/' | ||||
@return_to = 'http://example/return/' | ||||
@assoc = GoodAssoc.new | ||||
@checkid_req = CheckIDRequest.new(@assoc, @endpoint) | ||||
end | ||||
def assert_has_identifiers(msg, local_id, claimed_id) | ||||
assert_openid_value_equal(msg, 'identity', local_id) | ||||
assert_openid_value_equal(msg, 'claimed_id', claimed_id) | ||||
end | ||||
def assert_openid_key_exists(msg, key) | ||||
assert(msg.get_arg(OPENID_NS, key), | ||||
"#{key} not present in #{msg.get_args(OPENID_NS).inspect}") | ||||
end | ||||
def assert_openid_key_absent(msg, key) | ||||
assert(msg.get_arg(OPENID_NS, key).nil?) | ||||
end | ||||
def assert_openid_value_equal(msg, key, expected) | ||||
actual = msg.get_arg(OPENID_NS, key, NO_DEFAULT) | ||||
error_text = ("Expected #{expected.inspect} for openid.#{key} "\ | ||||
"but got #{actual.inspect}: #{msg.inspect}") | ||||
assert_equal(expected, actual, error_text) | ||||
end | ||||
def assert_anonymous(msg) | ||||
['claimed_id', 'identity'].each do |key| | ||||
assert_openid_key_absent(msg, key) | ||||
end | ||||
end | ||||
def assert_has_required_fields(msg) | ||||
internal_message = @checkid_req.instance_variable_get(:@message) | ||||
assert_equal(preferred_namespace, | ||||
internal_message.get_openid_namespace) | ||||
assert_equal(preferred_namespace, msg.get_openid_namespace) | ||||
assert_openid_value_equal(msg, 'mode', expected_mode) | ||||
# Implement these in subclasses because they depend on | ||||
# protocol differences! | ||||
assert_has_realm(msg) | ||||
assert_identifiers_present(msg) | ||||
end | ||||
# TESTS | ||||
def test_check_no_assoc_handle | ||||
@checkid_req.instance_variable_set('@assoc', nil) | ||||
msg = assert_log_matches("Generated checkid") { | ||||
@checkid_req.get_message(@realm, @return_to, immediate) | ||||
} | ||||
assert_openid_key_absent(msg, 'assoc_handle') | ||||
end | ||||
def test_check_with_assoc_handle | ||||
msg = assert_log_matches("Generated checkid") { | ||||
@checkid_req.get_message(@realm, @return_to, immediate) | ||||
} | ||||
assert_openid_value_equal(msg, 'assoc_handle', @assoc.handle) | ||||
end | ||||
def test_add_extension_arg | ||||
@checkid_req.add_extension_arg('bag:', 'color', 'brown') | ||||
@checkid_req.add_extension_arg('bag:', 'material', 'paper') | ||||
assert(@checkid_req.message.namespaces.member?('bag:')) | ||||
assert_equal(@checkid_req.message.get_args('bag:'), | ||||
{'color' => 'brown', 'material' => 'paper'}) | ||||
msg = assert_log_matches("Generated checkid") { | ||||
@checkid_req.get_message(@realm, @return_to, immediate) | ||||
} | ||||
# XXX: this depends on the way that Message assigns | ||||
# namespaces. Really it doesn't care that it has alias "0", | ||||
# but that is tested anyway | ||||
post_args = msg.to_post_args() | ||||
assert_equal('brown', post_args['openid.ext0.color']) | ||||
assert_equal('paper', post_args['openid.ext0.material']) | ||||
end | ||||
def test_standard | ||||
msg = assert_log_matches('Generated checkid') { | ||||
@checkid_req.get_message(@realm, @return_to, immediate) | ||||
} | ||||
assert_has_identifiers(msg, @endpoint.local_id, @endpoint.claimed_id) | ||||
end | ||||
def test_send_redirect? | ||||
silence_logging { | ||||
url = @checkid_req.redirect_url(@realm, @return_to, immediate) | ||||
assert(url.length < OPENID1_URL_LIMIT) | ||||
assert(@checkid_req.send_redirect?(@realm, @return_to, immediate)) | ||||
@return_to << '/foo' * 1000 | ||||
url = @checkid_req.redirect_url(@realm, @return_to, immediate) | ||||
assert(url.length > OPENID1_URL_LIMIT) | ||||
actual = @checkid_req.send_redirect?(@realm, @return_to, immediate) | ||||
expected = preferred_namespace != OPENID2_NS | ||||
assert_equal(expected, actual) | ||||
} | ||||
end | ||||
end | ||||
class TestCheckIDRequestOpenID2 < Test::Unit::TestCase | ||||
include CheckIDTestMixin | ||||
def immediate | ||||
false | ||||
end | ||||
def expected_mode | ||||
'checkid_setup' | ||||
end | ||||
def preferred_namespace | ||||
OPENID2_NS | ||||
end | ||||
# check presence of proper realm key and absence of the wrong | ||||
# one. | ||||
def assert_has_realm(msg) | ||||
assert_openid_value_equal(msg, 'realm', @realm) | ||||
assert_openid_key_absent(msg, 'trust_root') | ||||
end | ||||
def assert_identifiers_present(msg) | ||||
identity_present = msg.has_key?(OPENID_NS, 'identity') | ||||
claimed_present = msg.has_key?(OPENID_NS, 'claimed_id') | ||||
assert_equal(claimed_present, identity_present) | ||||
end | ||||
# OpenID Checkid_Requests should be able to set 'anonymous' to true. | ||||
def test_set_anonymous_works_for_openid2 | ||||
assert(@checkid_req.message.is_openid2) | ||||
assert_nothing_raised {@checkid_req.anonymous = true} | ||||
assert_nothing_raised {@checkid_req.anonymous = false} | ||||
end | ||||
def test_user_anonymous_ignores_identfier | ||||
@checkid_req.anonymous = true | ||||
msg = assert_log_matches('Generated checkid') { | ||||
@checkid_req.get_message(@realm, @return_to, immediate) | ||||
} | ||||
assert_has_required_fields(msg) | ||||
assert_anonymous(msg) | ||||
end | ||||
def test_op_anonymous_ignores_identifier | ||||
@endpoint.is_op_identifier = true | ||||
@checkid_req.anonymous = true | ||||
msg = assert_log_matches('Generated checkid') { | ||||
@checkid_req.get_message(@realm, @return_to, immediate) | ||||
} | ||||
assert_has_required_fields(msg) | ||||
assert_anonymous(msg) | ||||
end | ||||
def test_op_identifier_sends_identifier_select | ||||
@endpoint.is_op_identifier = true | ||||
msg = assert_log_matches('Generated checkid') { | ||||
@checkid_req.get_message(@realm, @return_to, immediate) | ||||
} | ||||
assert_has_required_fields(msg) | ||||
assert_has_identifiers(msg, IDENTIFIER_SELECT, IDENTIFIER_SELECT) | ||||
end | ||||
end | ||||
class TestCheckIDRequestOpenID1 < Test::Unit::TestCase | ||||
include CheckIDTestMixin | ||||
def immediate | ||||
false | ||||
end | ||||
def preferred_namespace | ||||
OPENID1_NS | ||||
end | ||||
def expected_mode | ||||
'checkid_setup' | ||||
end | ||||
# Make sure claimed_is is *absent* in request. | ||||
def assert_has_identifiers(msg, op_specific_id, claimed_id) | ||||
assert_openid_value_equal(msg, 'identity', op_specific_id) | ||||
assert_openid_key_absent(msg, 'claimed_id') | ||||
end | ||||
def assert_identifiers_present(msg) | ||||
assert_openid_key_absent(msg, 'claimed_id') | ||||
assert(msg.has_key?(OPENID_NS, 'identity')) | ||||
end | ||||
# check presence of proper realm key and absence of the wrong | ||||
# one. | ||||
def assert_has_realm(msg) | ||||
assert_openid_value_equal(msg, 'trust_root', @realm) | ||||
assert_openid_key_absent(msg, 'realm') | ||||
end | ||||
# TESTS | ||||
# OpenID 1 requests MUST NOT be able to set anonymous to true | ||||
def test_set_anonymous_fails_for_openid1 | ||||
assert(@checkid_req.message.is_openid1) | ||||
assert_raises(ArgumentError) { | ||||
@checkid_req.anonymous = true | ||||
} | ||||
assert_nothing_raised{ | ||||
@checkid_req.anonymous = false | ||||
} | ||||
end | ||||
# Identfier select SHOULD NOT be sent, but this pathway is in | ||||
# here in case some special discovery stuff is done to trigger | ||||
# it with OpenID 1. If it is triggered, it will send | ||||
# identifier_select just like OpenID 2. | ||||
def test_identifier_select | ||||
@endpoint.is_op_identifier = true | ||||
msg = assert_log_matches('Generated checkid') { | ||||
@checkid_req.get_message(@realm, @return_to, immediate) | ||||
} | ||||
assert_has_required_fields(msg) | ||||
assert_equal(IDENTIFIER_SELECT, | ||||
msg.get_arg(OPENID1_NS, 'identity')) | ||||
end | ||||
end | ||||
class TestCheckIDRequestOpenID1Immediate < TestCheckIDRequestOpenID1 | ||||
def immediate | ||||
true | ||||
end | ||||
def expected_mode | ||||
'checkid_immediate' | ||||
end | ||||
end | ||||
class TestCheckid_RequestOpenID2Immediate < TestCheckIDRequestOpenID2 | ||||
def immediate | ||||
true | ||||
end | ||||
def expected_mode | ||||
'checkid_immediate' | ||||
end | ||||
end | ||||
end | ||||
end | ||||
end | ||||