Authentication Required / Anonymous Allowed Decorators & Hooks

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.

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:
        if not user:
            raise exception.Forbidden({'message': 'Invalid token'})

def anonymous_allowed(fn):
    fn.authenticated = False
    return fn

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

# views

def some_view():
    return None

# assert some_view.authenticated == True

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

And voila!