diff --git a/docs/spec.openapi.yaml b/docs/spec.openapi.yaml index 81f6342..830f42a 100644 --- a/docs/spec.openapi.yaml +++ b/docs/spec.openapi.yaml @@ -23,26 +23,26 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/credentials' + $ref: "#/components/schemas/credentials" responses: - '200': + "200": description: Login succeed content: application/json: schema: - $ref: '#/components/schemas/authorization' - '401': + $ref: "#/components/schemas/authorization" + "401": description: Invalid credentials content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '500': + $ref: "#/components/schemas/statusResponse" + "500": description: Internal error content: application/json: schema: - $ref: '#/components/schemas/statusResponse' + $ref: "#/components/schemas/statusResponse" /register: post: tags: @@ -52,26 +52,26 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/credentials' + $ref: "#/components/schemas/credentials" responses: - '201': + "201": description: Registration succeed content: application/json: schema: - $ref: '#/components/schemas/authorization' - '409': + $ref: "#/components/schemas/authorization" + "409": description: Username already registered content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '500': + $ref: "#/components/schemas/statusResponse" + "500": description: Internal error content: application/json: schema: - $ref: '#/components/schemas/statusResponse' + $ref: "#/components/schemas/statusResponse" /challenge: post: tags: @@ -81,26 +81,26 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/authorization' + $ref: "#/components/schemas/authorization" responses: - '200': + "200": description: Account token is still valid content: application/json: schema: - $ref: '#/components/schemas/account' - '401': + $ref: "#/components/schemas/account" + "401": description: Unauthorized content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '500': + $ref: "#/components/schemas/statusResponse" + "500": description: Internal error content: application/json: schema: - $ref: '#/components/schemas/statusResponse' + $ref: "#/components/schemas/statusResponse" /account/password: patch: tags: @@ -111,7 +111,7 @@ paths: application/json: schema: allOf: - - $ref: '#/components/schemas/authorization' + - $ref: "#/components/schemas/authorization" - type: object properties: currentPassword: @@ -119,24 +119,24 @@ paths: newPassword: type: string responses: - '200': + "200": description: Password updated successfully content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '401': + $ref: "#/components/schemas/statusResponse" + "401": description: Unauthorized content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '500': + $ref: "#/components/schemas/statusResponse" + "500": description: Internal error content: application/json: schema: - $ref: '#/components/schemas/statusResponse' + $ref: "#/components/schemas/statusResponse" /files: post: @@ -152,28 +152,28 @@ paths: fileName: type: string location: - type: string + type: string file: - type: string + type: string responses: - '201': + "201": description: File created successfully content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '401': + $ref: "#/components/schemas/statusResponse" + "401": description: Not authorized content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '500': + $ref: "#/components/schemas/statusResponse" + "500": description: Internal error content: application/json: schema: - $ref: '#/components/schemas/statusResponse' + $ref: "#/components/schemas/statusResponse" /folders: post: @@ -189,26 +189,26 @@ paths: folderName: type: string location: - type: string #UUID + type: string #UUID responses: - '201': + "201": description: Folder created successfully content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '401': + $ref: "#/components/schemas/statusResponse" + "401": description: Not authorized content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '500': + $ref: "#/components/schemas/statusResponse" + "500": description: Internal error content: application/json: schema: - $ref: '#/components/schemas/statusResponse' + $ref: "#/components/schemas/statusResponse" /files/shared: get: @@ -216,26 +216,26 @@ paths: - Files description: Gets the list of shared files responses: - '200': + "200": description: List of shared files obtained content: application/json: schema: type: array items: - $ref: '#/components/schemas/fileDetailsShared' - '401': + $ref: "#/components/schemas/fileDetailsShared" + "401": description: Not authorized content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '500': + $ref: "#/components/schemas/statusResponse" + "500": description: Internal error content: application/json: schema: - $ref: '#/components/schemas/statusResponse' + $ref: "#/components/schemas/statusResponse" /files/{fileId}/edit: put: tags: @@ -253,24 +253,24 @@ paths: schema: type: string responses: - '200': + "200": description: File successfully edited content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '401': + $ref: "#/components/schemas/statusResponse" + "401": description: Not authorized content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '500': + $ref: "#/components/schemas/statusResponse" + "500": description: Internal error content: application/json: schema: - $ref: '#/components/schemas/statusResponse' + $ref: "#/components/schemas/statusResponse" /files/{fileId}: delete: tags: @@ -283,24 +283,24 @@ paths: schema: type: string responses: - '200': + "200": description: File successfully deleted content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '401': + $ref: "#/components/schemas/statusResponse" + "401": description: Not authorized content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '500': - description: Internal error + $ref: "#/components/schemas/statusResponse" + "500": + description: Internal error content: application/json: schema: - $ref: '#/components/schemas/statusResponse' + $ref: "#/components/schemas/statusResponse" /files/{fileId}/move: patch: tags: @@ -318,26 +318,25 @@ paths: schema: type: string responses: - '200': + "200": description: File moved successfully content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '401': + $ref: "#/components/schemas/statusResponse" + "401": description: Not authorized content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '500': + $ref: "#/components/schemas/statusResponse" + "500": description: Internal error content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - - + $ref: "#/components/schemas/statusResponse" + /files/list: get: tags: @@ -348,30 +347,30 @@ paths: name: location required: false schema: - type: string + type: string description: The location (UUID) to list files from responses: - '200': + "200": description: List of files in the location content: application/json: schema: type: array items: - $ref: '#/components/schemas/fileDetails' - '401': + $ref: "#/components/schemas/fileDetails" + "401": description: Not authorized content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '500': + $ref: "#/components/schemas/statusResponse" + "500": description: Internal error content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - + $ref: "#/components/schemas/statusResponse" + /files/download/{fileUUID}: get: tags: @@ -385,31 +384,31 @@ paths: type: string description: The UUID of the file to download responses: - '200': + "200": description: File downloaded successfully content: - application/octet-stream: + application/octet-stream: schema: - type: string - format: binary - '401': + type: string + format: binary + "401": description: Not authorized content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '404': + $ref: "#/components/schemas/statusResponse" + "404": description: File not found content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '500': + $ref: "#/components/schemas/statusResponse" + "500": description: Internal error content: application/json: schema: - $ref: '#/components/schemas/statusResponse' + $ref: "#/components/schemas/statusResponse" /files/share: post: @@ -420,39 +419,39 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/shareWithReq' + $ref: "#/components/schemas/shareWithReq" responses: - '200': + "200": description: File shared successfully content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '400': + $ref: "#/components/schemas/statusResponse" + "400": description: Bad request content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '401': + $ref: "#/components/schemas/statusResponse" + "401": description: Not authorized content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '404': + $ref: "#/components/schemas/statusResponse" + "404": description: File not found content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '500': + $ref: "#/components/schemas/statusResponse" + "500": description: Internal error content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - + $ref: "#/components/schemas/statusResponse" + /files/unshare: post: tags: @@ -462,39 +461,39 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/shareWithReq' + $ref: "#/components/schemas/shareWithReq" responses: - '200': + "200": description: File unshared successfully content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '400': + $ref: "#/components/schemas/statusResponse" + "400": description: Bad request content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '401': + $ref: "#/components/schemas/statusResponse" + "401": description: Not authorized content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '404': + $ref: "#/components/schemas/statusResponse" + "404": description: File not found content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '500': + $ref: "#/components/schemas/statusResponse" + "500": description: Internal error content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - + $ref: "#/components/schemas/statusResponse" + /files/sharedwithwho: get: tags: @@ -505,9 +504,9 @@ paths: name: fileUUID required: true schema: - type: string + type: string responses: - '200': + "200": description: List of users the file is shared with content: application/json: @@ -520,26 +519,24 @@ paths: type: string example: sulcud - '401': + "401": description: Not authorized content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '404': + $ref: "#/components/schemas/statusResponse" + "404": description: File not found content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - '500': + $ref: "#/components/schemas/statusResponse" + "500": description: Internal error content: application/json: schema: - $ref: '#/components/schemas/statusResponse' - - + $ref: "#/components/schemas/statusResponse" components: schemas: @@ -553,8 +550,6 @@ components: properties: msg: type: string - succeed: - type: boolean credentials: type: object properties: @@ -592,11 +587,11 @@ components: fileUUID: type: string ownerusername: - type: string + type: string shareWithReq: type: object properties: fileUUID: type: string otherUsername: - type: string \ No newline at end of file + type: string diff --git a/main.py b/main.py index 33b5539..c8edc98 100644 --- a/main.py +++ b/main.py @@ -1,6 +1,8 @@ import flask -import pages.home +from src.views import views -app = flask.Flask(__name__, template_folder="templates") +app = flask.Flask(__name__) +app.register_blueprint(views) -app.register_blueprint(pages.home.home) +if __name__ == "__main__": + app.run(debug=True) diff --git a/pages/home/__init__.py b/pages/home/__init__.py deleted file mode 100644 index fe56a2b..0000000 --- a/pages/home/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -import flask -from ._view import view - - -home = flask.Blueprint("home", __name__) -home.register_blueprint(view) diff --git a/pages/home/_view.py b/pages/home/_view.py deleted file mode 100644 index 5dfe67e..0000000 --- a/pages/home/_view.py +++ /dev/null @@ -1,8 +0,0 @@ -import flask - -view = flask.Blueprint("home", __name__) - - -@view.route("/", methods=["GET"]) -def index(): - return flask.render_template("index.html") diff --git a/pages/home/_view_test.py b/pages/home/_view_test.py deleted file mode 100644 index 2335a78..0000000 --- a/pages/home/_view_test.py +++ /dev/null @@ -1,6 +0,0 @@ -from main import app - - -def test_view() -> None: - response = app.test_client().get("/") - assert response.status_code == 200 diff --git a/requirements.txt b/requirements.txt index 807163b..c457864 100644 Binary files a/requirements.txt and b/requirements.txt differ diff --git a/src/config/environment.py b/src/config/environment.py new file mode 100644 index 0000000..5f7962d --- /dev/null +++ b/src/config/environment.py @@ -0,0 +1,5 @@ +import os + +variables = { + "GATEWAY_BASEURL": os.getenv("GATEWAY_BASEURL", "http://localhost:8080"), +} diff --git a/src/config/soap_client.py b/src/config/soap_client.py new file mode 100644 index 0000000..5feb89c --- /dev/null +++ b/src/config/soap_client.py @@ -0,0 +1,5 @@ +from zeep import Client +from .environment import variables + +soap_wsdl = f"{variables['GATEWAY_BASEURL']}/service?wsdl" +soap_client = Client(soap_wsdl) diff --git a/src/controllers/_authentication_controllers.py b/src/controllers/_authentication_controllers.py new file mode 100644 index 0000000..d209391 --- /dev/null +++ b/src/controllers/_authentication_controllers.py @@ -0,0 +1,31 @@ +from flask import request +from src.config.soap_client import soap_client + + +def login_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.auth_login( + {"username": username, "password": password} + ) + + if result.auth is not None: + jwt = result.auth.token + return {"msg": "Login successful", "jwt": jwt}, 200 + + return {"msg": "Invalid credentials"}, 401 + + except Exception as e: + print("SOAP Error:", str(e)) + return {"msg": "Internal error", "error": str(e)}, 500 diff --git a/src/views/__init__.py b/src/views/__init__.py new file mode 100644 index 0000000..127bccd --- /dev/null +++ b/src/views/__init__.py @@ -0,0 +1,9 @@ +import flask +from ._authentication_views import views as authentication_views + + +# NOTE: Register all views / routes using the following blueprint +views = flask.Blueprint("views", __name__) + + +views.register_blueprint(authentication_views) diff --git a/src/views/_authentication_views.py b/src/views/_authentication_views.py new file mode 100644 index 0000000..cebb89c --- /dev/null +++ b/src/views/_authentication_views.py @@ -0,0 +1,9 @@ +import flask +from src.controllers import _authentication_controllers + +views = flask.Blueprint("authentication", __name__) + + +@views.route("/auth_login", methods=["POST"]) +def auth_login(): + return _authentication_controllers.login_handler() diff --git a/src/views/_authentication_views_test.py b/src/views/_authentication_views_test.py new file mode 100644 index 0000000..bfc3f8e --- /dev/null +++ b/src/views/_authentication_views_test.py @@ -0,0 +1,43 @@ +import json +from main import app +from config.soap_client import soap_client + + +def test_auth_login_successful() -> None: + registration_data = {"username": "miguel1", "password": "miguel1"} + + registration_result = soap_client.service.account_register(registration_data) + + assert registration_result.error is False + + login_data = {"username": "miguel1", "password": "miguel1"} + + response = app.test_client().post("/auth_login", json=login_data) + + assert response.status_code == 200 + + assert json.loads(response.data)["msg"] == "Login successful" + + assert "jwt" in json.loads(response.data) + + +def test_auth_login_invalid_credentials() -> None: + data = {"username": "miguel", "password": "miguel"} + + response = app.test_client().post("/auth_login", json=data) + + assert response.status_code == 401 + + assert json.loads(response.data)["msg"] == "Invalid credentials" + + +def test_auth_login_missing_fields() -> None: + data = {"username": "miguel"} + + response = app.test_client().post("/auth_login", json=data) + + assert response.status_code == 400 + + assert ( + json.loads(response.data)["msg"] == "Required fields are missing in JSON data" + ) # noqa: E501 diff --git a/templates/index.html b/templates/index.html deleted file mode 100644 index 6116828..0000000 --- a/templates/index.html +++ /dev/null @@ -1 +0,0 @@ -

Hello world

\ No newline at end of file