diff options
| author | Michael Merickel <michael@digitalartefacts.com> | 2013-10-19 03:10:54 -0500 |
|---|---|---|
| committer | Michael Merickel <michael@digitalartefacts.com> | 2013-10-19 03:10:54 -0500 |
| commit | 604297a083419278d85be47e40d1905043c38460 (patch) | |
| tree | 2558f54951c05f60e8a0bbab463be163d935a066 | |
| parent | f0e57015af826c4c28f2d9df825b9b0355069285 (diff) | |
| download | pyramid-604297a083419278d85be47e40d1905043c38460.tar.gz pyramid-604297a083419278d85be47e40d1905043c38460.tar.bz2 pyramid-604297a083419278d85be47e40d1905043c38460.zip | |
attempt to decode basic header as utf-8 and fallback to latin-1
fixes #898
fixes #904
| -rw-r--r-- | pyramid/authentication.py | 9 | ||||
| -rw-r--r-- | pyramid/tests/test_authentication.py | 18 |
2 files changed, 24 insertions, 3 deletions
diff --git a/pyramid/authentication.py b/pyramid/authentication.py index 454ebd4b2..6b6fbd041 100644 --- a/pyramid/authentication.py +++ b/pyramid/authentication.py @@ -1176,10 +1176,17 @@ class BasicAuthAuthenticationPolicy(CallbackAuthenticationPolicy): return None if authmeth.lower() != 'basic': return None + try: - auth = b64decode(auth.strip()).decode('ascii') + authbytes = b64decode(auth.strip()) except (TypeError, binascii.Error): # can't decode return None + + try: + auth = authbytes.decode('utf-8') + except UnicodeDecodeError: + auth = authbytes.decode('latin-1') + try: username, password = auth.split(':', 1) except ValueError: # not enough values to unpack diff --git a/pyramid/tests/test_authentication.py b/pyramid/tests/test_authentication.py index 19e95cf9a..ed6cc5903 100644 --- a/pyramid/tests/test_authentication.py +++ b/pyramid/tests/test_authentication.py @@ -1378,11 +1378,25 @@ class TestBasicAuthAuthenticationPolicy(unittest.TestCase): import base64 request = testing.DummyRequest() inputs = b'm\xc3\xb6rk\xc3\xb6:m\xc3\xb6rk\xc3\xb6password'.decode('utf-8') - request.headers['Authorization'] = 'Basic %s' % base64.b64encode(inputs.encode('utf-8')) + request.headers['Authorization'] = 'Basic %s' % ( + base64.b64encode(inputs.encode('utf-8'))) def check(username, password, request): return [] policy = self._makeOne(check) - self.assertEqual(policy.authenticated_userid(request), b'm\xc3\xb6rk\xc3\xb6'.decode('utf-8')) + self.assertEqual(policy.authenticated_userid(request), + b'm\xc3\xb6rk\xc3\xb6'.decode('utf-8')) + + def test_authenticated_userid_latin1(self): + import base64 + request = testing.DummyRequest() + inputs = b'm\xc3\xb6rk\xc3\xb6:m\xc3\xb6rk\xc3\xb6password'.decode('utf-8') + request.headers['Authorization'] = 'Basic %s' % ( + base64.b64encode(inputs.encode('latin-1'))) + def check(username, password, request): + return [] + policy = self._makeOne(check) + self.assertEqual(policy.authenticated_userid(request), + b'm\xc3\xb6rk\xc3\xb6'.decode('utf-8')) def test_unauthenticated_userid_invalid_payload(self): import base64 |
