diff --git a/app/decorators.py b/app/decorators.py index 18c31589676b966c579b2ef9eb0e944ab8393be0..2782378f7ffad7a1c061d29c341850af65efc418 100644 --- a/app/decorators.py +++ b/app/decorators.py @@ -10,6 +10,8 @@ This module defines some useful decorators. """ from functools import wraps +from flask import current_app, abort +from flask_login import current_user from flask_jwt_extended import get_current_user from .utils import InventoryError @@ -45,6 +47,8 @@ def jwt_groups_required(*groups): def jwt_groups_accepted(*groups): """Decorator which specifies that a user must have at least one of the specified groups. + This shall be used for users logged in using a JWT (API). + Example:: @bp.route('/models', methods=['POST']) @jwt_required @@ -68,3 +72,33 @@ def jwt_groups_accepted(*groups): return fn(*args, **kwargs) return decorated_view return wrapper + + +def login_groups_accepted(*groups): + """Decorator which specifies that a user must have at least one of the specified groups. + + This shall be used for users logged in using a cookie (web UI). + + Example:: + @bp.route('/models', methods=['POST']) + @login_groups_accepted('admin', 'create') + def create_model(): + return create() + + The current user must be in either 'admin' or 'create' group + to access this route. + This checks that the user is logged in. There is no need to + use the @login_required decorator. + + :param groups: accepted groups + """ + def wrapper(fn): + @wraps(fn) + def decorated_view(*args, **kwargs): + if not current_user.is_authenticated: + return current_app.login_manager.unauthorized() + if not current_user.is_member_of_one_group(groups): + abort(403) + return fn(*args, **kwargs) + return decorated_view + return wrapper