from functools import wraps from flask import request, abort from flask_login import current_user from flask_login.config import EXEMPT_METHODS from app import app def priv_required(*perms): """ Requires the user to be an authenticated member with privileges [perms]. Calls :attr:`LoginManager.unauthorized` if the user is not authenticated, and a 403 if some of the privileges are missing. Example: @app.route('/admin') @priv_required('access-admin-board') def admin_board(): pass It can be convenient to globally turn off authentication when unit testing. Setting the `LOGIN_DISABLED` configuration variable to `True` will silence this decorator. """ def decorated_view(func): @wraps(func) def wrapped(*args, **kwargs): if request.method in EXEMPT_METHODS: return func(*args, **kwargs) elif not current_user.is_authenticated: return app.login_manager.unauthorized() else: for p in perms: if not current_user.priv(p): # TODO: Add error message and privilege name abort(403) return func(*args, **kwargs) return wrapped return decorated_view def guest_only(func): """ Opposite decorator of @login_required """ @wraps(func) def wrapped(*args, **kwargs): if current_user.is_authenticated: abort(404) return func(*args, **kwargs) return wrapped