diff options
author | Gael Pasgrimaud <gael@gawel.org> | 2014-04-16 20:32:11 +0200 |
---|---|---|
committer | Gael Pasgrimaud <gael@gawel.org> | 2014-04-16 20:34:04 +0200 |
commit | b31cdebb5655b6e2fe0620d807c2d85f5b0f6c18 (patch) | |
tree | e84f68d9c8caaeb9db3f374b30bf49fc5c190480 | |
parent | bc5b86cc8c2feef77cd852efe65527148b241a14 (diff) | |
download | webtest-b31cdebb5655b6e2fe0620d807c2d85f5b0f6c18.tar.gz |
add authorization property
-rw-r--r-- | CHANGELOG.rst | 2 | ||||
-rw-r--r-- | docs/testapp.rst | 11 | ||||
-rw-r--r-- | tests/test_authorisation.py | 41 | ||||
-rw-r--r-- | webtest/app.py | 37 | ||||
-rw-r--r-- | webtest/debugapp.py | 2 |
5 files changed, 92 insertions, 1 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst index e8d8f04..54b85dd 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,8 @@ News - Fixed #107 Explicit error message when WSGIProxy2 is not installer +- Fixed #103 Broken "Edit me on GitHub" links in documentation + 2.0.14 (2014-01-23) ------------------- diff --git a/docs/testapp.rst b/docs/testapp.rst index 06bba54..fb7066e 100644 --- a/docs/testapp.rst +++ b/docs/testapp.rst @@ -96,6 +96,17 @@ If you want *all* your requests to have this key, do: app = TestApp(my_app, extra_environ=dict(REMOTE_USER='bob')) +If you have to use HTTP authorization you can use the ``.authorization`` +property to set the ``HTTP_AUTHORIZATION`` key of the extra_environ +dictionnary: + +.. code-block:: python + + app = TestApp(my_app) + app.authorization = ('Basic', ('user', 'password')) + +Only Basic auth is supported for now. + Testing a non wsgi application ------------------------------ diff --git a/tests/test_authorisation.py b/tests/test_authorisation.py new file mode 100644 index 0000000..f1f03d9 --- /dev/null +++ b/tests/test_authorisation.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +from webtest.debugapp import DebugApp +from tests.compat import unittest +from base64 import b64decode +from webtest.compat import to_bytes + +import webtest + + +class TestAuthorization(unittest.TestCase): + + def callFUT(self): + return webtest.TestApp(DebugApp()) + + def test_basic_authorization(self): + app = self.callFUT() + authorization = ('Basic', ['gawel', 'passwd']) + app.authorization = authorization + + self.assertIn('HTTP_AUTHORIZATION', app.extra_environ) + self.assertEquals(app.authorization, authorization) + + resp = app.get('/') + resp.mustcontain('HTTP_AUTHORIZATION: Basic Z2F3ZWw6cGFzc3dk') + header = resp.request.environ['HTTP_AUTHORIZATION'] + self.assertTrue(header.startswith('Basic ')) + authtype, value = header.split(' ') + auth = (authtype, + b64decode(to_bytes(value)).decode('latin1').split(':')) + self.assertEquals(authorization, auth) + + app.authorization = None + self.assertNotIn('HTTP_AUTHORIZATION', app.extra_environ) + + def test_invalid(self): + app = self.callFUT() + self.assertRaises(ValueError, app.set_authorization, ()) + self.assertRaises(ValueError, app.set_authorization, '') + self.assertRaises(ValueError, app.set_authorization, ('Basic', '')) + self.assertRaises(ValueError, app.set_authorization, ('Basic', ())) diff --git a/webtest/app.py b/webtest/app.py index 6acdde1..3a21643 100644 --- a/webtest/app.py +++ b/webtest/app.py @@ -17,6 +17,8 @@ import random import re import warnings +from base64 import b64encode + from six import StringIO from six import BytesIO from six import string_types @@ -146,6 +148,41 @@ class TestApp(object): if parser_features: self.RequestClass.ResponseClass.parser_features = parser_features + def get_authorization(self): + """Allow to set the HTTP_AUTHORIZATION environ key. Value should looks + like ``('Basic', ('user', 'password'))`` + + If value is None the the HTTP_AUTHORIZATION is removed + """ + return self.authorization_value + + def set_authorization(self, value): + self.authorization_value = value + if value is not None: + invalid_value = ( + "You should use a value like ('Basic', ('user', 'password'))" + ) + if isinstance(value, (list, tuple)) and len(value) == 2: + authtype, val = value + if authtype == 'Basic' and val and \ + isinstance(val, (list, tuple)): + val = ':'.join(list(val)) + val = b64encode(to_bytes(val)).strip() + val = val.decode('latin1') + else: + raise ValueError(invalid_value) + value = str('%s %s' % (authtype, val)) + else: + raise ValueError(invalid_value) + self.extra_environ.update({ + 'HTTP_AUTHORIZATION': value, + }) + else: + if 'HTTP_AUTHORIZATION' in self.extra_environ: + del self.extra_environ['HTTP_AUTHORIZATION'] + + authorization = property(get_authorization, set_authorization) + @property def cookies(self): return dict([(cookie.name, cookie.value) for cookie in self.cookiejar]) diff --git a/webtest/debugapp.py b/webtest/debugapp.py index 970f31c..60b4435 100644 --- a/webtest/debugapp.py +++ b/webtest/debugapp.py @@ -11,7 +11,7 @@ class DebugApp(object): """The WSGI application used for testing""" def __init__(self, form=None, show_form=False): - if os.path.isfile(form): + if form and os.path.isfile(form): fd = open(form, 'rb') self.form = fd.read() fd.close() |