Tres Seaver
2012-03-18 a9030688e0953ef0598d0209cd94dddd3a66c824
Portable base64 {en,de}coding of basic auth header.
3 files modified
32 ■■■■■ changed files
repoze/who/_compat.py 7 ●●●●● patch | view | raw | blame | history
repoze/who/plugins/basicauth.py 17 ●●●●● patch | view | raw | blame | history
repoze/who/plugins/tests/test_basicauth.py 8 ●●●●● patch | view | raw | blame | history
repoze/who/_compat.py
@@ -17,6 +17,13 @@
except NameError: #pragma NO COVER Python >= 3.0
    u = str
try:
    from base64 import decodebytes
    from base64 import encodebytes
except: # Python < 3.0
    from base64 import decodestring as decodebytes
    from base64 import encodestring as encodebytes
def REQUEST_METHOD(environ):
    return environ['REQUEST_METHOD']
repoze/who/plugins/basicauth.py
@@ -1,37 +1,40 @@
import binascii
from repoze.who._compat import AUTHORIZATION
from webob.exc import HTTPUnauthorized
from zope.interface import implementer
from repoze.who.interfaces import IIdentifier
from repoze.who.interfaces import IChallenger
from repoze.who._compat import AUTHORIZATION
from repoze.who._compat import decodebytes
@implementer(IIdentifier, IChallenger)
class BasicAuthPlugin(object):
    def __init__(self, realm):
        self.realm = realm
    # IIdentifier
    def identify(self, environ):
        authorization = AUTHORIZATION(environ)
        if type(authorization) != type(b''):
            # this header *must* be base64-encoded ASCII
            authorization = authorization.encode('ascii')
        try:
            authmeth, auth = authorization.split(' ', 1)
            authmeth, auth = authorization.split(b' ', 1)
        except ValueError: # not enough values to unpack
            return None
        if authmeth.lower() == 'basic':
            try:
                auth = auth.strip().decode('base64')
                auth = auth.strip()
                auth = decodebytes(auth)
            except binascii.Error: # can't decode
                return None
            try:
                login, password = auth.split(':', 1)
                login, password = auth.split(b':', 1)
            except ValueError: # not enough values to unpack
                return None
            auth = {'login':login, 'password':password}
            auth = {'login': login, 'password': password}
            return auth
        return None
repoze/who/plugins/tests/test_basicauth.py
@@ -35,7 +35,7 @@
        items = []
        for item in app_iter:
            items.append(item)
        response = ''.join(items)
        response = b''.join(items).decode('utf-8')
        self.failUnless(response.startswith('401 Unauthorized'))
        
    def test_identify_noauthinfo(self):
@@ -57,15 +57,17 @@
        self.assertEqual(creds, None)
    def test_identify_basic_badrepr(self):
        from repoze.who._compat import encodebytes
        plugin = self._makeOne('realm')
        value = 'foo'.encode('base64')
        value = encodebytes(b'foo').decode('ascii')
        environ = self._makeEnviron({'HTTP_AUTHORIZATION':'Basic %s' % value})
        creds = plugin.identify(environ)
        self.assertEqual(creds, None)
    def test_identify_basic_ok(self):
        from repoze.who._compat import encodebytes
        plugin = self._makeOne('realm')
        value = 'foo:bar'.encode('base64')
        value = encodebytes(b'foo:bar').decode('ascii')
        environ = self._makeEnviron({'HTTP_AUTHORIZATION':'Basic %s' % value})
        creds = plugin.identify(environ)
        self.assertEqual(creds, {'login':'foo', 'password':'bar'})