import base64

class Unauthorized(Exception):
    pass

def getuserpass(environ):
    authinfo = environ.get('HTTP_AUTHORIZATION')
    if not authinfo:
        return ('anonymous', None)
    authtype, userinfo = authinfo.split(' ')
    assert authtype == 'Basic', 'unsupported auth type %s' % (authtype,)
    username, password = base64.decodestring(userinfo).split(':')
    return username, password

def authenticate(acl, username, password, users):
    if username not in users or users[username]['passwd'] != password:
        return False
    return True

def authorize(acl, user, permission):
    return acl.user_has_permission(user, permission)

def require(acl, environ, perm, realm, users):
    user, password = getuserpass(environ)
    if ((user != 'anonymous' and
            not authenticate(acl, user, password, users)) or
            not authorize(acl, user, perm)):
        raise Unauthorized()

