summaryrefslogtreecommitdiff
path: root/tests/unit
diff options
context:
space:
mode:
Diffstat (limited to 'tests/unit')
-rw-r--r--tests/unit/core/test_web_api.py105
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"