import typing from functools import wraps from flask import current_app from .utils import current_user def login_required(func): """ Checks if the user is authenticated and executes AuthManager.unauthorized logic if not. Example: @app.route('/page') @login_required def page(): return 'page content' """ @wraps(func) def decorated_view(*args, **kwargs): if not current_user.is_authenticated: return current_app.auth_manager.unauthorized() return func(*args, **kwargs) return decorated_view def claims_required(claims: typing.Iterable, login_redirect=True): """ Checks if the user has any of required claims and executes AuthManager.unauthorized logic if not. This check use `or` logic against the iterable. If You need `and` logic, just use the decorator multiple times to achieve this. Example: @app.route('/page') @claims_required([SomeClaim(SomeClaim.Values.some_value)]) def page(): return 'page content' """ def wrapped(func): @wraps(func) def decorated_view(*args, **kwargs): if not current_user.is_authenticated or not set(claims) & set( current_user.claims ): return current_app.auth_manager.unauthorized(login_redirect) return func(*args, **kwargs) return decorated_view return wrapped