From 67e55b85a8882b4cc8b97abec3e8d641a0d4c0ad Mon Sep 17 00:00:00 2001 From: "Michael P. Daugherty" Date: Sun, 6 May 2012 15:56:05 +0800 Subject: [PATCH] Update to accept openid requests from Google Apps domains, which are unusual because the claimed id is a url for the hosted domain, but the identification is actually hosted on Google. --- openid/consumer/consumer.py | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/openid/consumer/consumer.py b/openid/consumer/consumer.py index a81be06f..fb79a7d4 100644 --- a/openid/consumer/consumer.py +++ b/openid/consumer/consumer.py @@ -189,6 +189,7 @@ import cgi import copy +import urllib from urlparse import urlparse, urldefrag from openid import fetchers @@ -917,13 +918,20 @@ def _verifyDiscoveryResultsOpenID2(self, resp_msg, endpoint): elif to_match.claimed_id is None: return OpenIDServiceEndpoint.fromOPEndpointURL(to_match.server_url) + # If the open id service endpoint is for a google apps hosted domain, we need to change the claimed id to + # the Google user-xrds URL + if to_match.server_url.startswith(u'https://www.google.com/a/'): + claimed_id = u'https://www.google.com/accounts/o8/user-xrds?uri=%s' % urllib.quote_plus(to_match.claimed_id) + else: + claimed_id = to_match.claimed_id + # The claimed ID doesn't match, so we have to do discovery # again. This covers not using sessions, OP identifier # endpoints and responses that didn't match the original # request. if not endpoint: oidutil.log('No pre-discovered information supplied.') - endpoint = self._discoverAndVerify(to_match.claimed_id, [to_match]) + endpoint = self._discoverAndVerify(claimed_id, [to_match]) else: # The claimed ID matches, so we use the endpoint that we # discovered in initiation. This should be the most common @@ -936,7 +944,7 @@ def _verifyDiscoveryResultsOpenID2(self, resp_msg, endpoint): str(e)) oidutil.log("Attempting discovery to verify endpoint") endpoint = self._discoverAndVerify( - to_match.claimed_id, [to_match]) + claimed_id, [to_match]) # The endpoint we return should have the claimed ID from the # message we just verified, fragment and all. @@ -1004,18 +1012,32 @@ def _verifyDiscoverySingle(self, endpoint, to_match): if not endpoint.usesExtension(type_uri): raise TypeURIMismatch(type_uri, endpoint) + # If the open id service endpoint is for a google apps hosted domain, we need to change the claimed id to + # the Google user-xrds URL + if to_match.server_url.startswith(u'https://www.google.com/a/'): + claimed_id = u'https://www.google.com/accounts/o8/user-xrds?uri=%s' % urllib.quote_plus(to_match.claimed_id) + else: + claimed_id = to_match.claimed_id + # Fragments do not influence discovery, so we can't compare a # claimed identifier with a fragment to discovered information. - defragged_claimed_id, _ = urldefrag(to_match.claimed_id) + defragged_claimed_id, _ = urldefrag(claimed_id) if defragged_claimed_id != endpoint.claimed_id: raise ProtocolError( 'Claimed ID does not match (different subjects!), ' 'Expected %s, got %s' % (defragged_claimed_id, endpoint.claimed_id)) - if to_match.getLocalID() != endpoint.getLocalID(): + # If the open id service endpoint is for a google apps hosted domain, we need to change the local id to + # the Google user-xrds URL + if to_match.server_url.startswith(u'https://www.google.com/a/'): + local_id = u'https://www.google.com/accounts/o8/user-xrds?uri=%s' % urllib.quote_plus(to_match.local_id) + else: + local_id = to_match.getLocalID() + + if local_id != endpoint.getLocalID(): raise ProtocolError('local_id mismatch. Expected %s, got %s' % - (to_match.getLocalID(), endpoint.getLocalID())) + (local_id, endpoint.getLocalID())) # If the server URL is None, this must be an OpenID 1 # response, because op_endpoint is a required parameter in @@ -1668,9 +1690,9 @@ def htmlMarkup(self, realm, return_to=None, immediate=False, @returns: str """ - return oidutil.autoSubmitHTML(self.formMarkup(realm, + return oidutil.autoSubmitHTML(self.formMarkup(realm, return_to, - immediate, + immediate, form_tag_attrs)) def shouldSendRedirect(self):