def setUp(self): self.endpoint = OpenIDServiceEndpoint() self.endpoint.identity_url = self.identity_url = 'http://identity.url/' self.store = None self.session = {} self.consumer = Consumer(self.session, self.store) self.consumer.consumer = StubConsumer() self.discovery = Discovery(self.session, self.identity_url, self.consumer.session_key_prefix)
def begin(self, user_url): """Start the OpenID authentication process. See steps 1-2 in the overview at the top of this file. @param user_url: Identity URL given by the user. This method performs a textual transformation of the URL to try and make sure it is normalized. For example, a user_url of example.com will be normalized to http://example.com/ normalizing and resolving any redirects the server might issue. @type user_url: str @returns: An object containing the discovered information will be returned, with a method for building a redirect URL to the server, as described in step 3 of the overview. This object may also be used to add extension arguments to the request, using its L{addExtensionArg<openid.consumer.consumer.AuthRequest.addExtensionArg>} method. @returntype: L{AuthRequest<openid.consumer.consumer.AuthRequest>} @raises openid.consumer.discover.DiscoveryFailure: when I fail to find an OpenID server for this URL. If the C{yadis} package is available, L{openid.consumer.discover.DiscoveryFailure} is an alias for C{yadis.discover.DiscoveryFailure}. """ if yadis_available and xri.identifierScheme(user_url) == "XRI": discoverMethod = discoverXRI openid_url = user_url else: discoverMethod = openIDDiscover openid_url = oidutil.normalizeUrl(user_url) if yadis_available: try: disco = Discovery(self.session, openid_url, self.session_key_prefix) service = disco.getNextService(discoverMethod) except fetchers.HTTPFetchingError, e: raise DiscoveryFailure('Error fetching XRDS document', e)
def complete(self, query): """Called to interpret the server's response to an OpenID request. It is called in step 4 of the flow described in the consumer overview. @param query: A dictionary of the query parameters for this HTTP request. @returns: a subclass of Response. The type of response is indicated by the status attribute, which will be one of SUCCESS, CANCEL, FAILURE, or SETUP_NEEDED. @see: L{SuccessResponse<openid.consumer.consumer.SuccessResponse>} @see: L{CancelResponse<openid.consumer.consumer.CancelResponse>} @see: L{SetupNeededResponse<openid.consumer.consumer.SetupNeededResponse>} @see: L{FailureResponse<openid.consumer.consumer.FailureResponse>} """ endpoint = self.session.get(self._token_key) if endpoint is None: response = FailureResponse(None, 'No session state found') else: response = self.consumer.complete(query, endpoint) del self.session[self._token_key] if (response.status in ['success', 'cancel'] and yadis_available and response.identity_url is not None): disco = Discovery(self.session, response.identity_url, self.session_key_prefix) # This is OK to do even if we did not do discovery in # the first place. disco.cleanup() return response
class ConsumerTest(unittest.TestCase): def setUp(self): self.endpoint = OpenIDServiceEndpoint() self.endpoint.identity_url = self.identity_url = 'http://identity.url/' self.store = None self.session = {} self.consumer = Consumer(self.session, self.store) self.consumer.consumer = StubConsumer() self.discovery = Discovery(self.session, self.identity_url, self.consumer.session_key_prefix) def test_beginWithoutDiscovery(self): # Does this really test anything non-trivial? result = self.consumer.beginWithoutDiscovery(self.endpoint) # The result is an auth request self.failUnless(isinstance(result, AuthRequest)) # Side-effect of calling beginWithoutDiscovery is setting the # session value to the endpoint attribute of the result self.failUnless(self.session[self.consumer._token_key] is result.endpoint) # The endpoint that we passed in is the endpoint on the auth_request self.failUnless(result.endpoint is self.endpoint) def test_completeEmptySession(self): response = self.consumer.complete({}) self.failUnlessEqual(response.status, FAILURE) self.failUnless(response.identity_url is None) def _doResp(self, auth_req, exp_resp): """complete a transaction, using the expected response from the generic consumer.""" self.consumer.consumer.response = exp_resp # endpoint is stored in the session self.failUnless(self.session) resp = self.consumer.complete({}) # All responses should have the same identity URL, and the # session should be cleaned out self.failUnless(resp.identity_url is self.identity_url) self.failIf(self.consumer._token_key in self.session) # Expected status response self.failUnlessEqual(resp.status, exp_resp.status) return resp def _doRespNoDisco(self, exp_resp): """Set up a transaction without discovery""" auth_req = self.consumer.beginWithoutDiscovery(self.endpoint) resp = self._doResp(auth_req, exp_resp) # There should be nothing left in the session once we have completed. self.failIf(self.session) return resp def test_noDiscoCompleteSuccessWithToken(self): self._doRespNoDisco(SuccessResponse(self.endpoint, {})) def test_noDiscoCompleteCancelWithToken(self): self._doRespNoDisco(CancelResponse(self.endpoint)) def test_noDiscoCompleteFailure(self): msg = 'failed!' resp = self._doRespNoDisco(FailureResponse(self.endpoint, msg)) self.failUnless(resp.message is msg) def test_noDiscoCompleteSetupNeeded(self): setup_url = 'http://setup.url/' resp = self._doRespNoDisco( SetupNeededResponse(self.endpoint, setup_url)) self.failUnless(resp.setup_url is setup_url) # To test that discovery is cleaned up, we need to initialize a # Yadis manager, and have it put its values in the session. def _doRespDisco(self, is_clean, exp_resp): """Set up and execute a transaction, with discovery""" self.discovery.createManager([self.endpoint], self.identity_url) auth_req = self.consumer.begin(self.identity_url) resp = self._doResp(auth_req, exp_resp) manager = self.discovery.getManager() if is_clean: self.failUnless(self.discovery.getManager() is None, manager) else: self.failIf(self.discovery.getManager() is None, manager) return resp # Cancel and success DO clean up the discovery process def test_completeSuccess(self): self._doRespDisco(True, SuccessResponse(self.endpoint, {})) def test_completeCancel(self): self._doRespDisco(True, CancelResponse(self.endpoint)) # Failure and setup_needed don't clean up the discovery process def test_completeFailure(self): msg = 'failed!' resp = self._doRespDisco(False, FailureResponse(self.endpoint, msg)) self.failUnless(resp.message is msg) def test_completeSetupNeeded(self): setup_url = 'http://setup.url/' resp = self._doRespDisco( False, SetupNeededResponse(self.endpoint, setup_url)) self.failUnless(resp.setup_url is setup_url) def test_begin(self): self.discovery.createManager([self.endpoint], self.identity_url) # Should not raise an exception auth_req = self.consumer.begin(self.identity_url) self.failUnless(isinstance(auth_req, AuthRequest)) self.failUnless(auth_req.endpoint is self.endpoint) self.failUnless(auth_req.endpoint is self.consumer.consumer.endpoint) self.failUnless(auth_req.assoc is self.consumer.consumer.assoc)