Authentication Required / Anonymous Allowed Decorators & Hooks


#1

Going from @Bogdanp 's idea of using the route component to access the function handler attached to it, we can attach attributes to the function and check them to allow anonymous or force authentication required.


# hooks.py
class AuthRequiredHook():
    def __init__(self, whitelist=None) -> None:
        self.whitelist = set(whitelist or [])

    def on_request(self, route: Route, user: JWTUser=None) -> None:
        if getattr(route.handler, 'authenticated', True) or route.handler in self.whitelist:
            return
        if not user:
            raise exception.Forbidden({'message': 'Invalid token'})

# decorators.py
def anonymous_allowed(fn):
    fn.authenticated = False
    return fn


def authentication_required(fn):
    fn.authenticated = True
    return fn

# views

@authentication_required
def some_view():
    return None

# assert some_view.authenticated == True

routes = [
    Route('/', method='GET', handler=some_view)  # <-- notice handler attr
]

And voila!