From 907e0ecaaba8511cf3d7333de20c00167a0e13e4 Mon Sep 17 00:00:00 2001 From: Davor Date: Wed, 8 Jun 2022 21:41:59 +0200 Subject: [PATCH] add permission layer for admins for backend API --- areas/auth/auth.py | 2 +- areas/roles/role_service.py | 5 +++++ areas/users/users.py | 3 +++ helpers/auth_guard.py | 24 ++++++++++++++++++++++++ 4 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 helpers/auth_guard.py diff --git a/areas/auth/auth.py b/areas/auth/auth.py index 8a137d0..a119ffa 100644 --- a/areas/auth/auth.py +++ b/areas/auth/auth.py @@ -37,7 +37,7 @@ def hydra_callback(): identity = i access_token = create_access_token( - identity=token, expires_delta=timedelta(days=365) + identity=token, expires_delta=timedelta(days=365), additional_claims={"user_id": identity["id"]} ) apps = App.query.all() diff --git a/areas/roles/role_service.py b/areas/roles/role_service.py index 7d70f99..a117985 100644 --- a/areas/roles/role_service.py +++ b/areas/roles/role_service.py @@ -1,3 +1,4 @@ +from areas.apps.models import AppRole from .models import Role @@ -10,3 +11,7 @@ class RoleService: @staticmethod def get_role_by_id(role_id): return Role.query.filter_by(id=role_id).first() + + def is_user_admin(userId): + dashboard_role_id = AppRole.query.filter_by(user_id=userId, app_id=1).first().role_id + return dashboard_role_id == 1 \ No newline at end of file diff --git a/areas/users/users.py b/areas/users/users.py index d472ed6..a413455 100644 --- a/areas/users/users.py +++ b/areas/users/users.py @@ -5,6 +5,7 @@ from flask_expects_json import expects_json from areas import api_v1 from helpers import KratosApi +from helpers.auth_guard import admin_required from .validation import schema from .user_service import UserService @@ -13,6 +14,7 @@ from .user_service import UserService @api_v1.route("/users", methods=["GET"]) @jwt_required() @cross_origin() +@admin_required() def get_users(): res = UserService.get_users() return jsonify(res) @@ -49,6 +51,7 @@ def put_user(id): @api_v1.route("/users/", methods=["DELETE"]) @jwt_required() @cross_origin() +@admin_required() def delete_user(id): res = KratosApi.delete("/identities/{}".format(id)) if res.status_code == 204: diff --git a/helpers/auth_guard.py b/helpers/auth_guard.py new file mode 100644 index 0000000..d40cd3d --- /dev/null +++ b/helpers/auth_guard.py @@ -0,0 +1,24 @@ +from functools import wraps + +from flask import jsonify +from areas.roles.role_service import RoleService + +from flask_jwt_extended import verify_jwt_in_request +from flask_jwt_extended import get_jwt + +def admin_required(): + def wrapper(fn): + @wraps(fn) + def decorator(*args, **kwargs): + verify_jwt_in_request() + claims = get_jwt() + userId = claims["user_id"] + isAdmin = RoleService.is_user_admin(userId) + if isAdmin: + return fn(*args, **kwargs) + else: + return jsonify(msg="Admins only!"), 403 + + return decorator + + return wrapper \ No newline at end of file