From 604297a083419278d85be47e40d1905043c38460 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 19 Oct 2013 03:10:54 -0500 Subject: attempt to decode basic header as utf-8 and fallback to latin-1 fixes #898 fixes #904 --- pyramid/authentication.py | 9 ++++++++- 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 -- cgit v1.2.3