def run(): trust_root = consumer_url consumer = GenericConsumer(store) setConsumerSession(consumer) request = consumer.begin(endpoint) return_to = consumer_url m = request.getMessage(trust_root, return_to, immediate) redirect_url = request.redirectURL(trust_root, return_to, immediate) parsed = urlparse.urlparse(redirect_url) qs = parsed[4] q = parseQuery(qs) new_return_to = q['openid.return_to'] del q['openid.return_to'] assert q == { 'openid.mode':mode, 'openid.identity':delegate_url, 'openid.trust_root':trust_root, 'openid.assoc_handle':fetcher.assoc_handle, }, (q, user_url, delegate_url, mode) assert new_return_to.startswith(return_to) assert redirect_url.startswith(server_url) parsed = urlparse.urlparse(new_return_to) query = parseQuery(parsed[4]) query.update({ 'openid.mode':'id_res', 'openid.return_to':new_return_to, 'openid.identity':delegate_url, 'openid.assoc_handle':fetcher.assoc_handle, }) assoc = store.getAssociation(server_url, fetcher.assoc_handle) message = Message.fromPostArgs(query) message = assoc.signMessage(message) info = consumer.complete(message, request.endpoint, new_return_to) assert info.status == SUCCESS, info.message assert info.identity_url == user_url
def run(): trust_root = consumer_url consumer = GenericConsumer(store) request = consumer.begin(endpoint) return_to = consumer_url redirect_url = request.redirectURL(trust_root, return_to, immediate) parsed = urlparse.urlparse(redirect_url) qs = parsed[4] q = parseQuery(qs) new_return_to = q['openid.return_to'] del q['openid.return_to'] assert q == { 'openid.mode':mode, 'openid.identity':delegate_url, 'openid.trust_root':trust_root, 'openid.assoc_handle':fetcher.assoc_handle, }, (q, user_url, delegate_url, mode) assert new_return_to.startswith(return_to) assert redirect_url.startswith(server_url) query = { 'nonce':request.return_to_args['nonce'], 'openid.mode':'id_res', 'openid.return_to':new_return_to, 'openid.identity':delegate_url, 'openid.assoc_handle':fetcher.assoc_handle, } assoc = store.getAssociation(server_url, fetcher.assoc_handle) assoc.addSignature(['mode', 'return_to', 'identity'], query) info = consumer.complete(query, request.endpoint) assert info.status == SUCCESS, info.message assert info.identity_url == user_url
class TestCompleteMissingSig(unittest.TestCase, CatchLogs): def setUp(self): self.store = GoodAssocStore() self.consumer = GenericConsumer(self.store) self.server_url = "http://idp.unittest/" CatchLogs.setUp(self) claimed_id = 'bogus.claimed' self.message = Message.fromOpenIDArgs( {'mode': 'id_res', 'return_to': 'return_to (just anything)', 'identity': claimed_id, 'assoc_handle': 'does not matter', 'sig': GOODSIG, 'response_nonce': mkNonce(), 'signed': 'identity,return_to,response_nonce,assoc_handle,claimed_id,op_endpoint', 'claimed_id': claimed_id, 'op_endpoint': self.server_url, 'ns':OPENID2_NS, }) self.endpoint = OpenIDServiceEndpoint() self.endpoint.server_url = self.server_url self.endpoint.claimed_id = claimed_id self.consumer._checkReturnTo = lambda unused1, unused2 : True def tearDown(self): CatchLogs.tearDown(self) def test_idResMissingNoSigs(self): def _vrfy(resp_msg, endpoint=None): return endpoint self.consumer._verifyDiscoveryResults = _vrfy r = self.consumer.complete(self.message, self.endpoint, None) self.failUnlessSuccess(r) def test_idResNoIdentity(self): self.message.delArg(OPENID_NS, 'identity') self.message.delArg(OPENID_NS, 'claimed_id') self.endpoint.claimed_id = None self.message.setArg(OPENID_NS, 'signed', 'return_to,response_nonce,assoc_handle,op_endpoint') r = self.consumer.complete(self.message, self.endpoint, None) self.failUnlessSuccess(r) def test_idResMissingIdentitySig(self): self.message.setArg(OPENID_NS, 'signed', 'return_to,response_nonce,assoc_handle,claimed_id') r = self.consumer.complete(self.message, self.endpoint, None) self.failUnlessEqual(r.status, FAILURE) def test_idResMissingReturnToSig(self): self.message.setArg(OPENID_NS, 'signed', 'identity,response_nonce,assoc_handle,claimed_id') r = self.consumer.complete(self.message, self.endpoint, None) self.failUnlessEqual(r.status, FAILURE) def test_idResMissingAssocHandleSig(self): self.message.setArg(OPENID_NS, 'signed', 'identity,response_nonce,return_to,claimed_id') r = self.consumer.complete(self.message, self.endpoint, None) self.failUnlessEqual(r.status, FAILURE) def test_idResMissingClaimedIDSig(self): self.message.setArg(OPENID_NS, 'signed', 'identity,response_nonce,return_to,assoc_handle') r = self.consumer.complete(self.message, self.endpoint, None) self.failUnlessEqual(r.status, FAILURE) def failUnlessSuccess(self, response): if response.status != SUCCESS: self.fail("Non-successful response: %s" % (response,))
class TestReturnToArgs(unittest.TestCase): """Verifying the Return URL paramaters. From the specification "Verifying the Return URL":: To verify that the "openid.return_to" URL matches the URL that is processing this assertion: - The URL scheme, authority, and path MUST be the same between the two URLs. - Any query parameters that are present in the "openid.return_to" URL MUST also be present with the same values in the accepting URL. XXX: So far we have only tested the second item on the list above. XXX: _verifyReturnToArgs is not invoked anywhere. """ def setUp(self): store = object() self.consumer = GenericConsumer(store) def test_returnToArgsOkay(self): query = { 'openid.mode': 'id_res', 'openid.return_to': 'http://example.com/?foo=bar', 'foo': 'bar', } # no return value, success is assumed if there are no exceptions. self.consumer._verifyReturnToArgs(query) def test_returnToArgsUnexpectedArg(self): query = { 'openid.mode': 'id_res', 'openid.return_to': 'http://example.com/', 'foo': 'bar', } # no return value, success is assumed if there are no exceptions. self.failUnlessRaises(ProtocolError, self.consumer._verifyReturnToArgs, query) def test_returnToMismatch(self): query = { 'openid.mode': 'id_res', 'openid.return_to': 'http://example.com/?foo=bar', } # fail, query has no key 'foo'. self.failUnlessRaises(ValueError, self.consumer._verifyReturnToArgs, query) query['foo'] = 'baz' # fail, values for 'foo' do not match. self.failUnlessRaises(ValueError, self.consumer._verifyReturnToArgs, query) def test_noReturnTo(self): query = {'openid.mode': 'id_res'} self.failUnlessRaises(ValueError, self.consumer._verifyReturnToArgs, query) def test_completeBadReturnTo(self): """Test GenericConsumer.complete()'s handling of bad return_to values. """ return_to = "http://some.url/path?foo=bar" # Scheme, authority, and path differences are checked by # GenericConsumer._checkReturnTo. Query args checked by # GenericConsumer._verifyReturnToArgs. bad_return_tos = [ # Scheme only "https://some.url/path?foo=bar", # Authority only "http://some.url.invalid/path?foo=bar", # Path only "http://some.url/path_extra?foo=bar", # Query args differ "http://some.url/path?foo=bar2", "http://some.url/path?foo2=bar", ] m = Message(OPENID1_NS) m.setArg(OPENID_NS, 'mode', 'cancel') m.setArg(BARE_NS, 'foo', 'bar') endpoint = None for bad in bad_return_tos: m.setArg(OPENID_NS, 'return_to', bad) self.failIf(self.consumer._checkReturnTo(m, return_to)) def test_completeGoodReturnTo(self): """Test GenericConsumer.complete()'s handling of good return_to values. """ return_to = "http://some.url/path" good_return_tos = [ (return_to, {}), (return_to + "?another=arg", {(BARE_NS, 'another'): 'arg'}), (return_to + "?another=arg#fragment", {(BARE_NS, 'another'): 'arg'}), ("HTTP"+return_to[4:], {}), (return_to.replace('url','URL'), {}), ("http://some.url:80/path", {}), ("http://some.url/p%61th", {}), ("http://some.url/./path", {}), ] endpoint = None for good, extra in good_return_tos: m = Message(OPENID1_NS) m.setArg(OPENID_NS, 'mode', 'cancel') for ns, key in extra: m.setArg(ns, key, extra[(ns, key)]) m.setArg(OPENID_NS, 'return_to', good) result = self.consumer.complete(m, endpoint, return_to) self.failUnless(isinstance(result, CancelResponse), \ "Expected CancelResponse, got %r for %s" % (result, good,))