From a81d14b4f83f6307c366dd75b4cbc1de5ae866b8 Mon Sep 17 00:00:00 2001 From: Luka Date: Thu, 28 Oct 2021 14:09:10 +0000 Subject: [PATCH] feat(Users): Implemented Kratos CRUD --- api/users.py | 38 ------------------------- app.py | 13 ++++----- {api => areas}/__init__.py | 0 areas/apps/__init__.py | 1 + {api => areas/apps}/apps.py | 2 +- areas/auth/__init__.py | 1 + {api => areas/auth}/auth.py | 2 +- areas/users/__init__.py | 1 + areas/users/users.py | 57 +++++++++++++++++++++++++++++++++++++ helpers/kratos_api.py | 32 +++++++++++++++++++++ 10 files changed, 99 insertions(+), 48 deletions(-) delete mode 100644 api/users.py rename {api => areas}/__init__.py (100%) create mode 100644 areas/apps/__init__.py rename {api => areas/apps}/apps.py (98%) create mode 100644 areas/auth/__init__.py rename {api => areas/auth}/auth.py (95%) create mode 100644 areas/users/__init__.py create mode 100644 areas/users/users.py create mode 100644 helpers/kratos_api.py diff --git a/api/users.py b/api/users.py deleted file mode 100644 index b96a03f..0000000 --- a/api/users.py +++ /dev/null @@ -1,38 +0,0 @@ -from flask import jsonify -from flask_jwt_extended import jwt_required -from flask_cors import cross_origin - -from . import api_v1 - - -USER_DATA = [ - {"id": 1, "email": "john@doe.com", "name": "John Doe", "status": "active", "last_login": "2021-08-03T07:40:51+00:00"} -] - - -@api_v1.route('/users', methods=['GET']) -@jwt_required() -@cross_origin() -def get_users(): - return jsonify(USER_DATA) - - -@api_v1.route('/users', methods=['POST']) -@jwt_required() -@cross_origin() -def post_user(): - return jsonify(USER_DATA), 201 - - -@api_v1.route('/users/', methods=['PUT']) -@jwt_required() -@cross_origin() -def put_user(id): - return jsonify(USER_DATA) - - -@api_v1.route('/users/', methods=['DELETE']) -@jwt_required() -@cross_origin() -def delete_user(id): - return jsonify(USER_DATA) diff --git a/app.py b/app.py index bbf66e1..2c7d1cf 100644 --- a/app.py +++ b/app.py @@ -1,12 +1,14 @@ from flask import Flask, jsonify from flask_jwt_extended import JWTManager from flask_cors import CORS -import requests +from areas import api_v1 +# There imports are required +from areas import users +from areas import apps +from areas import auth from config import * -from api import api_v1, auth, users, apps - app = Flask(__name__) cors = CORS(app) app.config['SECRET_KEY'] = SECRET_KEY @@ -26,8 +28,3 @@ def expired_token_callback(*args): @app.route('/') def index(): return 'Open App Stack API v1.0' - -@app.route('/hello') -def hello(): - requests.get('{}/health/ready'.format(KRATOS_URL)) - return 'Open App Stack API v1.0' diff --git a/api/__init__.py b/areas/__init__.py similarity index 100% rename from api/__init__.py rename to areas/__init__.py diff --git a/areas/apps/__init__.py b/areas/apps/__init__.py new file mode 100644 index 0000000..2dbf1c6 --- /dev/null +++ b/areas/apps/__init__.py @@ -0,0 +1 @@ +from .apps import * \ No newline at end of file diff --git a/api/apps.py b/areas/apps/apps.py similarity index 98% rename from api/apps.py rename to areas/apps/apps.py index af9bcd6..edfc852 100644 --- a/api/apps.py +++ b/areas/apps/apps.py @@ -2,7 +2,7 @@ from flask import jsonify from flask_jwt_extended import jwt_required from flask_cors import cross_origin -from . import api_v1 +from areas import api_v1 CONFIG_DATA = [ { diff --git a/areas/auth/__init__.py b/areas/auth/__init__.py new file mode 100644 index 0000000..d7c8ad3 --- /dev/null +++ b/areas/auth/__init__.py @@ -0,0 +1 @@ +from .auth import * \ No newline at end of file diff --git a/api/auth.py b/areas/auth/auth.py similarity index 95% rename from api/auth.py rename to areas/auth/auth.py index fb4cdd9..af89132 100644 --- a/api/auth.py +++ b/areas/auth/auth.py @@ -2,7 +2,7 @@ from flask import request, jsonify from flask_jwt_extended import create_access_token from flask_cors import cross_origin -from . import api_v1 +from areas import api_v1 USERNAME = 'admin' PASSWORD = 'admin' diff --git a/areas/users/__init__.py b/areas/users/__init__.py new file mode 100644 index 0000000..642b070 --- /dev/null +++ b/areas/users/__init__.py @@ -0,0 +1 @@ +from .users import * \ No newline at end of file diff --git a/areas/users/users.py b/areas/users/users.py new file mode 100644 index 0000000..7ad285c --- /dev/null +++ b/areas/users/users.py @@ -0,0 +1,57 @@ +from flask import jsonify, request +from flask_jwt_extended import jwt_required +from flask_cors import cross_origin + +from areas import api_v1 +from helpers.kratos_api import KratosApi + + +@api_v1.route('/users', methods=['GET']) +@jwt_required() +@cross_origin() +def get_users(): + res = KratosApi.get('/identities') + return jsonify(res.json()) + +@api_v1.route('/users/', methods=['GET']) +@jwt_required() +@cross_origin() +def get_user(id): + res = KratosApi.get('/identities/{}'.format(id)) + return jsonify(res.json()) + + +@api_v1.route('/users', methods=['POST']) +@jwt_required() +@cross_origin() +def post_user(): + data = request.get_json() + kratos_data = { + "schema_id": "default", + "traits": data + } + res = KratosApi.post('/identities', kratos_data) + return jsonify(res.json()), res.status_code + + +@api_v1.route('/users/', methods=['PUT']) +@jwt_required() +@cross_origin() +def put_user(id): + data = request.get_json() + kratos_data = { + "schema_id": "default", + "traits": data + } + res = KratosApi.put('/identities/{}'.format(id), kratos_data) + return jsonify(res.json()), res.status_code + + +@api_v1.route('/users/', methods=['DELETE']) +@jwt_required() +@cross_origin() +def delete_user(id): + res = KratosApi.delete('/identities/{}'.format(id)) + if (res.status_code == 204): + return jsonify(), res.status_code + return jsonify(res.json()), res.status_code diff --git a/helpers/kratos_api.py b/helpers/kratos_api.py new file mode 100644 index 0000000..5a25b31 --- /dev/null +++ b/helpers/kratos_api.py @@ -0,0 +1,32 @@ +import requests + +from config import * + +class KratosApi(): + @staticmethod + def get(url): + try: + return requests.get('{}{}'.format(KRATOS_URL, url)) + except: + return "Failed to contact Kratos" + + @staticmethod + def post(url, data): + try: + return requests.post('{}{}'.format(KRATOS_URL, url), json=data) + except: + return "Failed to contact Kratos" + + @staticmethod + def put(url, data): + try: + return requests.put('{}{}'.format(KRATOS_URL, url), json=data) + except: + return "Failed to contact Kratos" + + @staticmethod + def delete(url): + try: + return requests.delete('{}{}'.format(KRATOS_URL, url)) + except: + return "Failed to contact Kratos" \ No newline at end of file