From 53529cd73727dd2812cf769c8807f91d4de48803 Mon Sep 17 00:00:00 2001 From: Davor Date: Tue, 21 Jun 2022 14:41:54 +0200 Subject: [PATCH 1/4] add me endpoint --- areas/users/user_service.py | 30 ++++++++++++++++++++++++++++++ areas/users/users.py | 29 ++++++++++++++++++++++++++++- helpers/auth_guard.py | 6 +++--- 3 files changed, 61 insertions(+), 4 deletions(-) diff --git a/areas/users/user_service.py b/areas/users/user_service.py index d394460..a0b50c3 100644 --- a/areas/users/user_service.py +++ b/areas/users/user_service.py @@ -68,6 +68,36 @@ class UserService: return UserService.get_user(id) + @staticmethod + def put_personal_info(id, data): + kratos_data = { + "schema_id": "default", + "traits": {"email": data["email"], "name": data["name"]}, + } + KratosApi.put("/admin/identities/{}".format(id), kratos_data) + + # TODO: if the user is no admin - he can't change app roles - implement + + if data["app_roles"]: + app_roles = data["app_roles"] + for ar in app_roles: + app = App.query.filter_by(slug=ar["name"]).first() + app_role = AppRole.query.filter_by(user_id=id, app_id=app.id).first() + + if app_role: + app_role.role_id = ar["role_id"] if "role_id" in ar else None + db.session.commit() + else: + appRole = AppRole( + user_id=id, + role_id=ar["role_id"] if "role_id" in ar else None, + app_id=app.id, + ) + db.session.add(appRole) + db.session.commit() + + return UserService.get_user(id) + @staticmethod def delete_user(id): app_role = AppRole.query.filter_by(user_id=id).all() diff --git a/areas/users/users.py b/areas/users/users.py index 4536586..03d059d 100644 --- a/areas/users/users.py +++ b/areas/users/users.py @@ -1,5 +1,5 @@ from flask import jsonify, request -from flask_jwt_extended import jwt_required +from flask_jwt_extended import get_jwt, jwt_required from flask_cors import cross_origin from flask_expects_json import expects_json @@ -23,6 +23,7 @@ def get_users(): @api_v1.route("/users/", methods=["GET"]) @jwt_required() @cross_origin() +@admin_required() def get_user(id): res = UserService.get_user(id) return jsonify(res) @@ -43,6 +44,7 @@ def post_user(): @jwt_required() @cross_origin() @expects_json(schema) +@admin_required() def put_user(id): data = request.get_json() res = UserService.put_user(id, data) @@ -59,3 +61,28 @@ def delete_user(id): UserService.delete_user(id) return jsonify(), res.status_code return jsonify(res.json()), res.status_code + + +@api_v1.route("/me", methods=["GET"]) +@jwt_required() +@cross_origin() +def get_personal_info(): + user_id = __get_user_id_from_jwt() + res = UserService.get_user(user_id) + return jsonify(res) + + +@api_v1.route("/me", methods=["PUT"]) +@jwt_required() +@cross_origin() +@expects_json(schema) +def update_personal_info(): + data = request.get_json() + user_id = __get_user_id_from_jwt() + res = UserService.put_user(user_id, data) + return jsonify(res) + + +def __get_user_id_from_jwt(): + claims = get_jwt() + return claims["user_id"] diff --git a/helpers/auth_guard.py b/helpers/auth_guard.py index 900e35e..36bbeeb 100644 --- a/helpers/auth_guard.py +++ b/helpers/auth_guard.py @@ -2,10 +2,10 @@ from functools import wraps from areas.roles.role_service import RoleService -from flask_jwt_extended import verify_jwt_in_request -from flask_jwt_extended import get_jwt +from flask_jwt_extended import get_jwt, verify_jwt_in_request from helpers import Unauthorized + def admin_required(): def wrapper(fn): @wraps(fn) @@ -21,4 +21,4 @@ def admin_required(): return decorator - return wrapper \ No newline at end of file + return wrapper From 5b55c4498bf74317df7f388563be253898906cd1 Mon Sep 17 00:00:00 2001 From: Davor Date: Sat, 9 Jul 2022 12:18:03 +0200 Subject: [PATCH 2/4] non admin can't change app roles --- areas/users/user_service.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/areas/users/user_service.py b/areas/users/user_service.py index a0b50c3..d434b96 100644 --- a/areas/users/user_service.py +++ b/areas/users/user_service.py @@ -1,5 +1,6 @@ from database import db from areas.apps.models import App, AppRole +from areas.roles.role_service import RoleService from helpers import KratosApi class UserService: @@ -76,9 +77,9 @@ class UserService: } KratosApi.put("/admin/identities/{}".format(id), kratos_data) - # TODO: if the user is no admin - he can't change app roles - implement - - if data["app_roles"]: + is_admin = RoleService.is_user_admin(id) + + if is_admin and data["app_roles"]: app_roles = data["app_roles"] for ar in app_roles: app = App.query.filter_by(slug=ar["name"]).first() From 8bcccf417db555fd6693ca90787d62b0b7e28f78 Mon Sep 17 00:00:00 2001 From: Davor Date: Mon, 11 Jul 2022 21:55:31 +0200 Subject: [PATCH 3/4] remove unused function - add check if editing user is admin for role editing --- areas/users/user_service.py | 32 ++------------------------------ areas/users/users.py | 5 +++-- 2 files changed, 5 insertions(+), 32 deletions(-) diff --git a/areas/users/user_service.py b/areas/users/user_service.py index d434b96..cfec282 100644 --- a/areas/users/user_service.py +++ b/areas/users/user_service.py @@ -42,43 +42,15 @@ class UserService: return UserService.get_user(res["id"]) @staticmethod - def put_user(id, data): + def put_user(id, user_editing_id, data): kratos_data = { "schema_id": "default", "traits": {"email": data["email"], "name": data["name"]}, } KratosApi.put("/admin/identities/{}".format(id), kratos_data) - if data["app_roles"]: - app_roles = data["app_roles"] - for ar in app_roles: - app = App.query.filter_by(slug=ar["name"]).first() - app_role = AppRole.query.filter_by(user_id=id, app_id=app.id).first() + is_admin = RoleService.is_user_admin(user_editing_id) - if app_role: - app_role.role_id = ar["role_id"] if "role_id" in ar else None - db.session.commit() - else: - appRole = AppRole( - user_id=id, - role_id=ar["role_id"] if "role_id" in ar else None, - app_id=app.id, - ) - db.session.add(appRole) - db.session.commit() - - return UserService.get_user(id) - - @staticmethod - def put_personal_info(id, data): - kratos_data = { - "schema_id": "default", - "traits": {"email": data["email"], "name": data["name"]}, - } - KratosApi.put("/admin/identities/{}".format(id), kratos_data) - - is_admin = RoleService.is_user_admin(id) - if is_admin and data["app_roles"]: app_roles = data["app_roles"] for ar in app_roles: diff --git a/areas/users/users.py b/areas/users/users.py index 03d059d..ca6117e 100644 --- a/areas/users/users.py +++ b/areas/users/users.py @@ -47,7 +47,8 @@ def post_user(): @admin_required() def put_user(id): data = request.get_json() - res = UserService.put_user(id, data) + user_id = __get_user_id_from_jwt() + res = UserService.put_user(id, user_id, data) return jsonify(res) @@ -79,7 +80,7 @@ def get_personal_info(): def update_personal_info(): data = request.get_json() user_id = __get_user_id_from_jwt() - res = UserService.put_user(user_id, data) + res = UserService.put_user(user_id, user_id, data) return jsonify(res) From 3a12949372d8a782a30c50c9ca97a2203855c640 Mon Sep 17 00:00:00 2001 From: Stackspin renovate bot Date: Thu, 14 Jul 2022 02:05:29 +0000 Subject: [PATCH 4/4] Update dependency bitnami/kubectl to v1.24.3 --- docker-compose.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 8e0bae6..43e2e2f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -40,7 +40,7 @@ services: - kube_port_mysql entrypoint: ["bash", "-c", "flask run --host $$(hostname -i)"] kube_port_kratos_admin: - image: bitnami/kubectl:1.24.2 + image: bitnami/kubectl:1.24.3 user: "${KUBECTL_UID}:${KUBECTL_GID}" expose: - 8000 @@ -48,7 +48,7 @@ services: - "$KUBECONFIG:/.kube/config" entrypoint: ["bash", "-c", "kubectl -n stackspin port-forward --address $$(hostname -i) service/kratos-admin 8000:80"] kube_port_hydra_admin: - image: bitnami/kubectl:1.24.2 + image: bitnami/kubectl:1.24.3 user: "${KUBECTL_UID}:${KUBECTL_GID}" expose: - 4445 @@ -56,7 +56,7 @@ services: - "$KUBECONFIG:/.kube/config" entrypoint: ["bash", "-c", "kubectl -n stackspin port-forward --address $$(hostname -i) service/hydra-admin 4445:4445"] kube_port_kratos_public: - image: bitnami/kubectl:1.24.2 + image: bitnami/kubectl:1.24.3 user: "${KUBECTL_UID}:${KUBECTL_GID}" ports: - "8080:8080" @@ -66,7 +66,7 @@ services: - "$KUBECONFIG:/.kube/config" entrypoint: ["bash", "-c", "kubectl -n stackspin port-forward --address $$(hostname -i) service/kratos-public 8080:80"] kube_port_mysql: - image: bitnami/kubectl:1.24.2 + image: bitnami/kubectl:1.24.3 user: "${KUBECTL_UID}:${KUBECTL_GID}" expose: - 3306