From 8417cac86458bd5037df295eba7bf71595582398 Mon Sep 17 00:00:00 2001 From: Miguel Mateo Mendoza Rojas <115849391+MiguelMRojas@users.noreply.github.com> Date: Tue, 10 Oct 2023 09:05:38 -0500 Subject: [PATCH] Release: v0.0.9 (#42) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: Enable CORS (#40) * feat: Register endpoint (#39) * feat: enpoint registration coverage 57% Implementation of the registration endpoint, 57% coverage is achieved * style: Fix formatter and linter warnings * test: Use random data in register tests * refactor: Update register endpoint according to the `.net` spec * test: Fix broken test --------- Co-authored-by: Antonio Donis Co-authored-by: Pedro Andrés Chaparro Quintero <62714297+PedroChaparro@users.noreply.github.com> Co-authored-by: Pedro Andrés Chaparro Quintero Co-authored-by: Andrea Velasquez <55466005+andre154@users.noreply.github.com> Co-authored-by: Andvelavi <54145562+Andvelavi@users.noreply.github.com> --- CHANGELOG.md | 7 ++++ CLI.md | 10 ++++++ Dockerfile | 1 + docs/spec.openapi.yaml | 4 +-- main.py | 6 ++++ package-lock.json | 4 +-- package.json | 2 +- requirements.txt | 1 + src/config/environment.py | 1 + src/controllers/_account_controllers.py | 31 ++++++++++++++++ src/views/__init__.py | 2 ++ src/views/_account_views.py | 9 +++++ src/views/_account_views_test.py | 48 +++++++++++++++++++++++++ 13 files changed, 121 insertions(+), 5 deletions(-) create mode 100644 CLI.md create mode 100644 src/controllers/_account_controllers.py create mode 100644 src/views/_account_views.py create mode 100644 src/views/_account_views_test.py diff --git a/CHANGELOG.md b/CHANGELOG.md index f91fbbf..a50b069 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### 0.0.9 (2023-10-09) + + +### Features + +* Register endpoint ([#39](https://github.com/hawks-atlanta/proxy-python/issues/39)) ([38392d4](https://github.com/hawks-atlanta/proxy-python/commit/38392d476c718eacc7e70e0bed98de08f2f1d186)) + ### 0.0.8 (2023-10-09) ### 0.0.7 (2023-10-09) diff --git a/CLI.md b/CLI.md new file mode 100644 index 0000000..04b6c61 --- /dev/null +++ b/CLI.md @@ -0,0 +1,10 @@ +# CLI + +This document describes how to use the service as a CLI tool. + +## Environment variables + +| Variable | Description | Example | +| ----------------- | ------------------------------------------------------ | ------------------------------------------ | +| `GATEWAY_BASEURL` | Base URL of the gateway | `https://gateway:8080` | +| `ALLOWED_ORIGINS` | An string with the allowed origins separated by commas | `https://example.com,https://example2.com` | diff --git a/Dockerfile b/Dockerfile index f78f500..bacbdbd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,4 +6,5 @@ COPY . . USER application RUN pip install -r requirements.txt ENV GATEWAY_BASEURL "http://gateway:8080" +ENV ALLOWED_ORIGINS "http://localhost:5173" ENTRYPOINT ["python", "-m", "flask", "-A", "./main.py", "run", "--host", "0.0.0.0", "--port", "8080"] \ No newline at end of file diff --git a/docs/spec.openapi.yaml b/docs/spec.openapi.yaml index 7f150bf..b777cbe 100644 --- a/docs/spec.openapi.yaml +++ b/docs/spec.openapi.yaml @@ -43,7 +43,7 @@ paths: application/json: schema: $ref: "#/components/schemas/statusResponse" - /register: + /account/register: post: tags: - Authentication @@ -577,7 +577,7 @@ components: authorization: type: object properties: - jwt: + token: type: string fileDetails: type: object diff --git a/main.py b/main.py index c8edc98..b7e2b7e 100644 --- a/main.py +++ b/main.py @@ -1,8 +1,14 @@ import flask +from flask_cors import CORS from src.views import views +from src.config.environment import variables app = flask.Flask(__name__) app.register_blueprint(views) +allowed_origins_list = variables["ALLOWED_ORIGINS"].split(",") + +CORS(app, resources={r"/*": {"origins": allowed_origins_list}}) + if __name__ == "__main__": app.run(debug=True) diff --git a/package-lock.json b/package-lock.json index bce946d..4f7d9e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { "name": "frontend-python", - "version": "0.0.8", + "version": "0.0.9", "lockfileVersion": 3, "requires": true, "packages": { "": { - "version": "0.0.8", + "version": "0.0.9", "devDependencies": { "git-semver-tags": "^4.1.1", "standard-version": "^9.5.0" diff --git a/package.json b/package.json index b5444f4..65fd999 100644 --- a/package.json +++ b/package.json @@ -3,5 +3,5 @@ "git-semver-tags": "^4.1.1", "standard-version": "^9.5.0" }, - "version": "0.0.8" + "version": "0.0.9" } diff --git a/requirements.txt b/requirements.txt index 4661a8c..d1daf10 100644 --- a/requirements.txt +++ b/requirements.txt @@ -39,3 +39,4 @@ urllib3==2.0.4 Werkzeug==2.3.7 wrapt==1.15.0 zeep==4.2.1 +flask-cors==4.0.0 \ No newline at end of file diff --git a/src/config/environment.py b/src/config/environment.py index 5f7962d..f2724f4 100644 --- a/src/config/environment.py +++ b/src/config/environment.py @@ -2,4 +2,5 @@ variables = { "GATEWAY_BASEURL": os.getenv("GATEWAY_BASEURL", "http://localhost:8080"), + "ALLOWED_ORIGINS": os.getenv("ALLOWED_ORIGINS", "http://localhost:5173"), } diff --git a/src/controllers/_account_controllers.py b/src/controllers/_account_controllers.py new file mode 100644 index 0000000..fc82a38 --- /dev/null +++ b/src/controllers/_account_controllers.py @@ -0,0 +1,31 @@ +from flask import request +from src.config.soap_client import soap_client + + +def register_handler(): + try: + # Get JSON data from the request + data = request.json + + if not data: + return {"msg": "No JSON data provided in the request"}, 400 + + username = data.get("username") + password = data.get("password") + + if not username or not password: + return {"msg": "Required fields are missing in JSON data"}, 400 + + result = soap_client.service.account_register( + {"username": username, "password": password} + ) + + if result.auth is not None: + jwt = result.auth.token + return {"msg": "Register succeeded", "token": jwt}, 200 + + return {"msg": "Username already registered"}, 409 + + except Exception as e: + print("[Exception] register_handler ->", str(e)) + return {"msg": "Internal error", "error": str(e)}, 500 diff --git a/src/views/__init__.py b/src/views/__init__.py index 127bccd..4b1c006 100644 --- a/src/views/__init__.py +++ b/src/views/__init__.py @@ -1,5 +1,6 @@ import flask from ._authentication_views import views as authentication_views +from ._account_views import views as account_views # NOTE: Register all views / routes using the following blueprint @@ -7,3 +8,4 @@ views.register_blueprint(authentication_views) +views.register_blueprint(account_views) diff --git a/src/views/_account_views.py b/src/views/_account_views.py new file mode 100644 index 0000000..60f98e6 --- /dev/null +++ b/src/views/_account_views.py @@ -0,0 +1,9 @@ +import flask +from src.controllers import _account_controllers + +views = flask.Blueprint("account", __name__) + + +@views.route("/account/register", methods=["POST"]) +def account_register(): + return _account_controllers.register_handler() diff --git a/src/views/_account_views_test.py b/src/views/_account_views_test.py new file mode 100644 index 0000000..2d37c36 --- /dev/null +++ b/src/views/_account_views_test.py @@ -0,0 +1,48 @@ +import json +from main import app +from src.lib.faker import fake_username, fake_password + +register_test_data = {"username": fake_username(), "password": fake_password()} + + +def test_account_register_successful() -> None: + register_data = { + "username": register_test_data["username"], + "password": register_test_data["password"], + } + response = app.test_client().post("/account/register", json=register_data) + json_response = json.loads(response.data) + + assert response.status_code == 200 + assert json.loads(response.data)["msg"] == "Register succeeded" + assert json_response["token"] != "" + + +def test_account_register_missing_fields() -> None: + # Empty json + data = {} + response = app.test_client().post("/account/register", json=data) + + assert response.status_code == 400 + assert json.loads(response.data)["msg"] == "No JSON data provided in the request" + + # Missing password + data = {"username": register_test_data["username"]} + response = app.test_client().post("/account/register", json=data) + + assert response.status_code == 400 + assert ( + json.loads(response.data)["msg"] == "Required fields are missing in JSON data" + ) + + +def test_account_register_Username_already_registered() -> None: + data = { + "username": register_test_data["username"], + "password": register_test_data["password"], + } + response = app.test_client().post("/account/register", json=data) + json_response = json.loads(response.data) + + assert response.status_code == 409 + assert json_response["msg"] == "Username already registered"