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