diff options
author | Kali Kaneko (leap communications) <kali@leap.se> | 2016-11-09 20:34:51 +0100 |
---|---|---|
committer | Kali Kaneko (leap communications) <kali@leap.se> | 2016-12-29 03:09:50 +0100 |
commit | 86976a27e7aa9222afc0695c240b0ea7cc8e362b (patch) | |
tree | 8f19391d07b0f2e67b94f3f1e9bc168bd3e4cea8 /tests | |
parent | c3acb3ca45480d3a4d72731ca68b69bec6db4e2c (diff) |
[feature] authentication classes and tests
Diffstat (limited to 'tests')
-rw-r--r-- | tests/unit/core/test_web_api.py | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/tests/unit/core/test_web_api.py b/tests/unit/core/test_web_api.py new file mode 100644 index 0000000..f440417 --- /dev/null +++ b/tests/unit/core/test_web_api.py @@ -0,0 +1,105 @@ +import base64 + +from twisted.cred import portal +from twisted.trial import unittest +from twisted.web.test.test_web import DummyRequest +from twisted.web import resource + +from leap.bitmask.core import _web + + +def b64encode(s): + return base64.b64encode(s).strip() + + +class APIMixin: + """ + L{TestCase} mixin class which defines a number of tests for + L{basic.BasicCredentialFactory}. Because this mixin defines C{setUp}, it + must be inherited before L{TestCase}. + """ + def setUp(self): + self.request = self.makeRequest() + + api = AuthTestResource() + self.realm = _web.HttpPasswordRealm(api) + tokens = {'testuser': 'token'} + checker = _web.TokenDictChecker(tokens) + self.portal = portal.Portal(self.realm, [checker]) + + def makeRequest(self, method=b'GET', clientAddress=None): + """ + Create a request object to be passed to + TokenCredentialFactory.decode along with a response value. + Override this in a subclass. + """ + raise NotImplementedError("%r did not implement makeRequest" % ( + self.__class__,)) + + +class WhitelistedResourceTests(APIMixin, unittest.TestCase): + + def makeRequest(self, method=b'GET', clientAddress=None, path='/'): + """ + Create a L{DummyRequest} (change me to create a + L{twisted.web.http.Request} instead). + """ + request = DummyRequest(b'/') + request.method = method + request.client = clientAddress + request.path = path + return request + + def test_render_returns_unauthorized_by_default(self): + """ + By default, a Whitelisted resource renders with a 401 response code and + a I{WWW-Authenticate} header and puts a simple unauthorized message + into the response body. + """ + protected = _web.WhitelistHTTPAuthSessionWrapper( + self.portal, + [_web.TokenCredentialFactory('localhost')]) + request = self.makeRequest(method='POST', path='/') + request.render(protected) + assert request.responseCode == 401 + + auth_header = request.responseHeaders.getRawHeaders( + b'www-authenticate') + assert auth_header == [b'token realm="localhost"'] + assert b'Unauthorized' == b''.join(request.written) + + def test_whitelisted_resource_does_render(self): + protected = _web.WhitelistHTTPAuthSessionWrapper( + self.portal, + [_web.TokenCredentialFactory('localhost')], + whitelist=['/whitelisted']) + request = self.makeRequest(method='GET', path='/whitelisted') + request.render(protected) + assert b'dummyGET' == b''.join(request.written) + + def test_good_token_authenticates(self): + protected = _web.WhitelistHTTPAuthSessionWrapper( + self.portal, + [_web.TokenCredentialFactory('localhost')], + whitelist=[]) + request = self.makeRequest(method='GET', path='/') + authorization = b64encode(b'testuser:token') + request.requestHeaders.addRawHeader(b'authorization', + b'Token ' + authorization) + request.render(protected) + assert b'dummyGET' == b''.join(request.written) + + def test_session_does_not_use_cookies(self): + # TODO + pass + + +class AuthTestResource(resource.Resource): + + isLeaf = True + + def render_GET(self, request): + return "dummyGET" + + def render_POST(self, request): + return "dummyPOST" |