From fa2dcb657cf2c8fa331636d5646557a9a3af7c70 Mon Sep 17 00:00:00 2001
From: Benjamin Bertrand <benjamin.bertrand@esss.se>
Date: Tue, 5 Sep 2017 16:45:27 +0200
Subject: [PATCH] Add decorator to protect routes (using cookie)

To make it easier, different decorators are created
depending if the user logged in using a JWT (API)
or cookie (web UI).
---
 app/decorators.py | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/app/decorators.py b/app/decorators.py
index 18c3158..2782378 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
-- 
GitLab