def test_unexpectedLoginError(self): """ Any unexpected failure from L{Portal.login} results in a 500 response code and causes the failure to be logged. """ logObserver = EventLoggingObserver.createWithCleanup( self, globalLogPublisher) class UnexpectedException(Exception): pass class BrokenChecker: credentialInterfaces = (IUsernamePassword, ) def requestAvatarId(self, credentials): raise UnexpectedException() self.portal.registerChecker(BrokenChecker()) self.credentialFactories.append(BasicCredentialFactory('example.com')) request = self.makeRequest([self.childName]) child = self._authorizedBasicLogin(request) request.render(child) self.assertEqual(request.responseCode, 500) self.assertEquals(1, len(logObserver)) self.assertIsInstance(logObserver[0]["log_failure"].value, UnexpectedException) self.assertEqual(len(self.flushLoggedErrors(UnexpectedException)), 1)
def testUnauthorizedOptionsCall(self): """ Validates that a regular non-CORS OPTIONS call returns an appropriate response """ request = http.Request(DummyChannel(), False) request.method = 'OPTIONS' request._fluidDB_reqid = 'xxx' request.args = dict() request.postpath = [] request.content = NoContent() request.requestHeaders.setRawHeaders('Origin', ['*']) resource = WSFEUnauthorizedResource( [BasicCredentialFactory('example.com')]) resource.render(request) self.assertEqual(http.OK, request.code) headers = request.responseHeaders self.assertEqual('DELETE, GET, HEAD, POST, PUT', headers.getRawHeaders('Allow')[0]) self.assertEqual( 'Accept, Authorization, Content-Type, X-FluidDB-Access-Token', headers.getRawHeaders('Access-Control-Allow-Headers')[0]) self.assertEqual( 'DELETE, GET, HEAD, POST, PUT', headers.getRawHeaders('Access-Control-Allow-Methods')[0])
def test_decodeRaises(self): """ L{HTTPAuthSessionWrapper.getChildWithDefault} returns an L{UnauthorizedResource} instance when called with a request which has a I{Basic Authorization} header which cannot be decoded using base64. """ self.credentialFactories.append(BasicCredentialFactory('example.com')) request = self.makeRequest([self.childName]) request.headers['authorization'] = 'Basic decode should fail' child = self.wrapper.getChildWithDefault(self.childName, request) self.assertIsInstance(child, UnauthorizedResource)
def test_decodeRaises(self): """ Resource traversal which enouncters an L{HTTPAuthSessionWrapper} results in an L{UnauthorizedResource} when the request has a I{Basic Authorization} header which cannot be decoded using base64. """ self.credentialFactories.append(BasicCredentialFactory('example.com')) request = self.makeRequest([self.childName]) request.headers['authorization'] = 'Basic decode should fail' child = getChildForRequest(self.wrapper, request) self.assertIsInstance(child, UnauthorizedResource)
def test_selectParseResponse(self): """ L{HTTPAuthSessionWrapper._selectParseHeader} returns a two-tuple giving the L{ICredentialFactory} to use to parse the header and a string containing the portion of the header which remains to be parsed. """ basicAuthorization = b'Basic abcdef123456' self.assertEqual(self.wrapper._selectParseHeader(basicAuthorization), (None, None)) factory = BasicCredentialFactory('example.com') self.credentialFactories.append(factory) self.assertEqual(self.wrapper._selectParseHeader(basicAuthorization), (factory, b'abcdef123456'))
def test_renderQuotesRealm(self): """ The realm value included in the I{WWW-Authenticate} header set in the response when L{UnauthorizedResounrce} is rendered has quotes and backslashes escaped. """ resource = UnauthorizedResource( [BasicCredentialFactory('example\\"foo')]) request = self.makeRequest() request.render(resource) self.assertEqual( request.responseHeaders.getRawHeaders(b'www-authenticate'), [b'basic realm="example\\\\\\"foo"'])
def _unauthorizedRenderTest(self, request): """ Render L{UnauthorizedResource} for the given request object and verify that the response code is I{Unauthorized} and that a I{WWW-Authenticate} header is set in the response containing a challenge. """ resource = UnauthorizedResource( [BasicCredentialFactory('example.com')]) request.render(resource) self.assertEqual(request.responseCode, 401) self.assertEqual( request.responseHeaders.getRawHeaders(b'www-authenticate'), [b'basic realm="example.com"'])
def _invalidAuthorizationTest(self, response): self.credentialFactories.append(BasicCredentialFactory('example.com')) request = self.makeRequest([self.childName]) request.headers['authorization'] = response child = self.wrapper.getChildWithDefault(self.childName, request) d = request.notifyFinish() def cbFinished(result): self.assertEqual(request.responseCode, 401) d.addCallback(cbFinished) render(child, request) return d
def test_render(self): """ L{UnauthorizedResource} renders with a 401 response code and a I{WWW-Authenticate} header and puts a simple unauthorized message into the response body. """ resource = UnauthorizedResource([ BasicCredentialFactory('example.com')]) request = DummyRequest(['']) render(resource, request) self.assertEqual(request.responseCode, 401) self.assertEqual( request.responseHeaders.getRawHeaders('www-authenticate'), ['basic realm="example.com"']) self.assertEqual(request.written, ['Unauthorized'])
def test_getChildWithDefaultAuthorized(self): """ Resource traversal which encounters an L{HTTPAuthSessionWrapper} results in an L{IResource} which renders the L{IResource} avatar retrieved from the portal when the request has a valid I{Authorization} header. """ self.credentialFactories.append(BasicCredentialFactory('example.com')) request = self.makeRequest([self.childName]) child = self._authorizedBasicLogin(request) d = request.notifyFinish() def cbFinished(ignored): self.assertEquals(request.written, [self.childContent]) d.addCallback(cbFinished) render(child, request) return d
def test_logout(self): """ The realm's logout callback is invoked after the resource is rendered. """ self.credentialFactories.append(BasicCredentialFactory('example.com')) class SlowerResource(Resource): def render(self, request): return NOT_DONE_YET self.avatar.putChild(self.childName, SlowerResource()) request = self.makeRequest([self.childName]) child = self._authorizedBasicLogin(request) render(child, request) self.assertEqual(self.realm.loggedOut, 0) request.finish() self.assertEqual(self.realm.loggedOut, 1)
def test_renderAuthorized(self): """ Resource traversal which terminates at an L{HTTPAuthSessionWrapper} and includes correct authentication headers results in the L{IResource} avatar (not one of its children) retrieved from the portal being rendered. """ self.credentialFactories.append(BasicCredentialFactory('example.com')) # Request it exactly, not any of its children. request = self.makeRequest([]) child = self._authorizedBasicLogin(request) d = request.notifyFinish() def cbFinished(ignored): self.assertEquals(request.written, [self.avatarContent]) d.addCallback(cbFinished) render(child, request) return d
def _invalidAuthorizationTest(self, response): """ Create a request with the given value as the value of an I{Authorization} header and perform resource traversal with it, starting at C{self.wrapper}. Assert that the result is a 401 response code. Return a L{Deferred} which fires when this is all done. """ self.credentialFactories.append(BasicCredentialFactory('example.com')) request = self.makeRequest([self.childName]) request.headers['authorization'] = response child = getChildForRequest(self.wrapper, request) d = request.notifyFinish() def cbFinished(result): self.assertEqual(request.responseCode, 401) d.addCallback(cbFinished) render(child, request) return d
def _logoutTest(self): """ Issue a request for an authentication-protected resource using valid credentials and then return the C{DummyRequest} instance which was used. This is a helper for tests about the behavior of the logout callback. """ self.credentialFactories.append(BasicCredentialFactory('example.com')) class SlowerResource(Resource): def render(self, request): return NOT_DONE_YET self.avatar.putChild(self.childName, SlowerResource()) request = self.makeRequest([self.childName]) child = self._authorizedBasicLogin(request) request.render(child) self.assertEqual(self.realm.loggedOut, 0) return request
def test_unexpectedLoginError(self): """ Any unexpected failure from L{Portal.login} results in a 500 response code and causes the failure to be logged. """ class UnexpectedException(Exception): pass class BrokenChecker(object): credentialInterfaces = (IUsernamePassword, ) def requestAvatarId(self, credentials): raise UnexpectedException() self.portal.registerChecker(BrokenChecker()) self.credentialFactories.append(BasicCredentialFactory('example.com')) request = self.makeRequest([self.childName]) child = self._authorizedBasicLogin(request) request.render(child) self.assertEqual(request.responseCode, 500) self.assertEqual(len(self.flushLoggedErrors(UnexpectedException)), 1)
def test_anonymousAccess(self): """ Anonymous requests are allowed if a L{Portal} has an anonymous checker registered. """ unprotectedContents = "contents of the unprotected child resource" self.avatars[ANONYMOUS] = Resource() self.avatars[ANONYMOUS].putChild( self.childName, Data(unprotectedContents, 'text/plain')) self.portal.registerChecker(AllowAnonymousAccess()) self.credentialFactories.append(BasicCredentialFactory('example.com')) request = self.makeRequest([self.childName]) child = getChildForRequest(self.wrapper, request) d = request.notifyFinish() def cbFinished(ignored): self.assertEquals(request.written, [unprotectedContents]) d.addCallback(cbFinished) render(child, request) return d