From 5ba6a9ed11a7148d7444928226de6f7e367a3429 Mon Sep 17 00:00:00 2001 From: violetaperezandrade Date: Thu, 11 Apr 2024 20:53:00 -0300 Subject: [PATCH 1/5] attempt to read header(it never arives :( ) --- .env.dist | 5 +++-- Dockerfile | 2 +- app.py | 6 ++++++ src/apps/users.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/resource.py | 1 + 5 files changed, 55 insertions(+), 3 deletions(-) diff --git a/.env.dist b/.env.dist index d853bef..b02b243 100644 --- a/.env.dist +++ b/.env.dist @@ -1,5 +1,6 @@ LOGGING_LEVEL= -PORT= USERS_HOST= MEASUREMENTS_HOST= -PLANTS_HOST= \ No newline at end of file +PLANTS_HOST= +JWT_SECRET= +HASH_ALGORITHM= \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 027cea3..74385c7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,4 +7,4 @@ RUN pip install -r requirements.txt EXPOSE 5000 -CMD ["gunicorn", "wsgi:app", "-b", "0.0.0.0:5000"] \ No newline at end of file +CMD ["gunicorn", "wsgi:app", "--reload", "-b", "0.0.0.0:5000"] \ No newline at end of file diff --git a/app.py b/app.py index 2f25e97..49916fd 100644 --- a/app.py +++ b/app.py @@ -1,6 +1,8 @@ import os +import sys import logging from flask import Flask +from flask import request from flask_restful import Api from werkzeug.routing import BaseConverter from src.resource import Gateway @@ -33,6 +35,10 @@ def __init__(self, url_map, *items): @app.after_request def _build_cors_post_response(response): + print(f"Headers(post response): {request.headers}") + sys.stdout.flush() + # if 'Origin' in request.headers: + # response.headers.add("Access-Control-Allow-Origin", request.headers['Origin']) response.headers.add("Access-Control-Allow-Origin", "*") response.headers.add("Access-Control-Allow-Headers", "*") response.headers.add("Access-Control-Allow-Methods", "*") diff --git a/src/apps/users.py b/src/apps/users.py index 71c5a9a..10be24a 100644 --- a/src/apps/users.py +++ b/src/apps/users.py @@ -1,16 +1,48 @@ +import http.client import os import logging +import jwt +import sys import requests from flask import make_response +TOKEN_FIELD_NAME = "x-access-token" + + def get_query_params(queryParam) -> str: if not queryParam: return "" return f"?{str(queryParam, 'utf-8')}" +def _get_token(headers: dict): + keyName = None + for key in headers.keys(): + if key.lower() == TOKEN_FIELD_NAME: + keyName = key + if not keyName: + return None + return headers.get(keyName) + + +def process_header(headers, body: dict) -> (dict, bool): + token = _get_token(headers) + if not token and not (body and "user_id" in body): # Check to not allow to bypass the token + return body, False + newBody = body.copy() if body else {} + try: + processToken = jwt.decode(token, key=os.getenv("HASH_SECRET"), algorithms=[os.getenv("HASH_ALGORITHM"), ]) + newBody["user_id"] = processToken.get("id", "") + newBody["email"] = processToken.get("email") + except jwt.ExpiredSignatureError: + return {"message": "expired token", "status": http.client.UNAUTHORIZED}, True + except jwt.InvalidTokenError: + return {"message": "invalid token", "status": http.client.FORBIDDEN}, True + return newBody, False + + class Users: def __init__(self): self.host = os.getenv("USERS_HOST") @@ -29,12 +61,24 @@ def get(self, url, body, headers, query_params): response.status_code) def post(self, url, body, headers, query_params): + print(f"URL: {url}") + sys.stdout.flush() + if not(url.startswith("login")): + print(f"NO ES UN CASO DE LOG IN !!!!!!! {url}") + sys.stdout.flush() + body, error = process_header(headers, body) + if error: + print(f"ES UN CASO DE ERROR(SEGUIMOS EN LOG IN'T ) !!!!!!! {url}") + sys.stdout.flush() + return make_response(body, body.get("status")) response = requests.post(f"{self.host}{url}" f"{get_query_params(query_params)}", json=body, headers=headers) logging.info(f"USERS | POST | {url}") logging.debug(f"BODY: {body}") + print(f"headers: {headers}") + sys.stdout.flush() return make_response(self.getResponseJson(response), response.status_code) diff --git a/src/resource.py b/src/resource.py index d0e4ed1..9156f1b 100644 --- a/src/resource.py +++ b/src/resource.py @@ -12,6 +12,7 @@ def getExtraData(): body = request.json else: body = {} + print(f"en get extract data headers: {request.headers}") headers = dict(request.headers) if 'Host' in headers: headers.pop('Host') # Invalid header From 57cac865c2f5917fefac234831f205cc426d3b68 Mon Sep 17 00:00:00 2001 From: violetaperezandrade Date: Sat, 13 Apr 2024 15:59:07 -0300 Subject: [PATCH 2/5] fix deseappearing header --- app.py | 6 ------ src/apps/users.py | 38 +++++++++++++++++++------------------- 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/app.py b/app.py index 49916fd..2f25e97 100644 --- a/app.py +++ b/app.py @@ -1,8 +1,6 @@ import os -import sys import logging from flask import Flask -from flask import request from flask_restful import Api from werkzeug.routing import BaseConverter from src.resource import Gateway @@ -35,10 +33,6 @@ def __init__(self, url_map, *items): @app.after_request def _build_cors_post_response(response): - print(f"Headers(post response): {request.headers}") - sys.stdout.flush() - # if 'Origin' in request.headers: - # response.headers.add("Access-Control-Allow-Origin", request.headers['Origin']) response.headers.add("Access-Control-Allow-Origin", "*") response.headers.add("Access-Control-Allow-Headers", "*") response.headers.add("Access-Control-Allow-Methods", "*") diff --git a/src/apps/users.py b/src/apps/users.py index 10be24a..647c10b 100644 --- a/src/apps/users.py +++ b/src/apps/users.py @@ -2,7 +2,6 @@ import os import logging import jwt -import sys import requests from flask import make_response @@ -29,17 +28,22 @@ def _get_token(headers: dict): def process_header(headers, body: dict) -> (dict, bool): token = _get_token(headers) - if not token and not (body and "user_id" in body): # Check to not allow to bypass the token + if not token and not (body and "user_id" in body): return body, False newBody = body.copy() if body else {} try: - processToken = jwt.decode(token, key=os.getenv("HASH_SECRET"), algorithms=[os.getenv("HASH_ALGORITHM"), ]) + processToken = jwt.decode(token, key=os.getenv("HASH_SECRET"), + algorithms=[os.getenv("HASH_ALGORITHM"), ]) newBody["user_id"] = processToken.get("id", "") newBody["email"] = processToken.get("email") except jwt.ExpiredSignatureError: - return {"message": "expired token", "status": http.client.UNAUTHORIZED}, True + return {"message": + "expired token", + "status": http.client.UNAUTHORIZED}, True except jwt.InvalidTokenError: - return {"message": "invalid token", "status": http.client.FORBIDDEN}, True + return {"message": + "invalid token", + "status": http.client.FORBIDDEN}, True return newBody, False @@ -61,26 +65,22 @@ def get(self, url, body, headers, query_params): response.status_code) def post(self, url, body, headers, query_params): - print(f"URL: {url}") - sys.stdout.flush() - if not(url.startswith("login")): - print(f"NO ES UN CASO DE LOG IN !!!!!!! {url}") - sys.stdout.flush() - body, error = process_header(headers, body) - if error: - print(f"ES UN CASO DE ERROR(SEGUIMOS EN LOG IN'T ) !!!!!!! {url}") - sys.stdout.flush() - return make_response(body, body.get("status")) + # if not (url.startswith("login")): + # body, error = process_header(headers, body) + # if error: + # return make_response(body, body.get("status")) response = requests.post(f"{self.host}{url}" f"{get_query_params(query_params)}", json=body, headers=headers) logging.info(f"USERS | POST | {url}") logging.debug(f"BODY: {body}") - print(f"headers: {headers}") - sys.stdout.flush() - return make_response(self.getResponseJson(response), - response.status_code) + headers = dict(response.headers) + response = make_response(self.getResponseJson(response), + response.status_code) + if headers.get(TOKEN_FIELD_NAME): + response.headers[TOKEN_FIELD_NAME] = headers.get(TOKEN_FIELD_NAME) + return response def patch(self, url, body, headers, query_params): response = requests.patch(f"{self.host}{url}" From 509b87e8e97cb6bb03c521084fd957e3c58bc0d3 Mon Sep 17 00:00:00 2001 From: violetaperezandrade Date: Sat, 13 Apr 2024 16:03:15 -0300 Subject: [PATCH 3/5] match social to measurements --- src/resource.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/resource.py b/src/resource.py index 9156f1b..3dfea83 100644 --- a/src/resource.py +++ b/src/resource.py @@ -27,7 +27,9 @@ def getExtraData(): "plants": Plants(), "plant-type": Plants(), "logs": Plants(), - "login": Users() + "login": Users(), + # TODO: Add the new service + "socal": Measurements() } From a08b8230cb84c06fc5fe09ff644d3432c7cb06d8 Mon Sep 17 00:00:00 2001 From: violetaperezandrade Date: Sat, 13 Apr 2024 16:24:29 -0300 Subject: [PATCH 4/5] that work arround won't work...add social service --- .env.dist | 1 + src/apps/social.py | 57 ++++++++++++++++++++++++++++++++++++++++++++++ src/resource.py | 3 ++- 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 src/apps/social.py diff --git a/.env.dist b/.env.dist index b02b243..c279995 100644 --- a/.env.dist +++ b/.env.dist @@ -2,5 +2,6 @@ LOGGING_LEVEL= USERS_HOST= MEASUREMENTS_HOST= PLANTS_HOST= +SOCIAL_HOST= JWT_SECRET= HASH_ALGORITHM= \ No newline at end of file diff --git a/src/apps/social.py b/src/apps/social.py new file mode 100644 index 0000000..0b2ea7b --- /dev/null +++ b/src/apps/social.py @@ -0,0 +1,57 @@ +import os +import logging + +import requests +from flask import make_response + + +def get_query_params(queryParam) -> str: + if not queryParam: + return "" + return f"?{str(queryParam, 'utf-8')}" + + +class Social: + def __init__(self): + self.host = os.getenv("SOCIAL_HOST") + + def getResponseJson(self, response): + if response.status_code == 503 or not response.text: + return {"message": "social service is currently unavailable," + " please try again later", "status": 503} + return response.json() + + def get(self, url, body, headers, query_params): + url = f"{self.host}{url}{get_query_params(query_params)}" + logging.info(f"SOCIAL | GET | {url}") + response = requests.get(url, json=body, headers=headers) + return make_response(self.getResponseJson(response), + response.status_code) + + def post(self, url, body, headers, query_params): + response = requests.post(f"{self.host}{url}" + f"{get_query_params(query_params)}", + json=body, + headers=headers) + logging.info(f"SOCIAL | POST | {url}") + logging.debug(f"BODY: {body}") + return make_response(self.getResponseJson(response), + response.status_code) + + def patch(self, url, body, headers, query_params): + response = requests.patch(f"{self.host}{url}" + f"{get_query_params(query_params)}", + json=body, + headers=headers) + logging.info(f"SOCIAL | PATCH | {url}") + logging.debug(f"BODY: {body}") + return make_response(self.getResponseJson(response), + response.status_code) + + def delete(self, url, body, headers, query_params): + response = requests.delete(f"{self.host}{url}" + f"{get_query_params(query_params)}", + headers=headers) + logging.info(f"SOCIAL | DELETE | {url}") + return make_response(self.getResponseJson(response), + response.status_code) diff --git a/src/resource.py b/src/resource.py index 3dfea83..9d09eb2 100644 --- a/src/resource.py +++ b/src/resource.py @@ -5,6 +5,7 @@ from src.apps.users import Users from src.apps.measurements import Measurements from src.apps.plants import Plants +from src.apps.social import Social def getExtraData(): @@ -29,7 +30,7 @@ def getExtraData(): "logs": Plants(), "login": Users(), # TODO: Add the new service - "socal": Measurements() + "social": Social() } From 16b818b077210f7720df48c211e6a5849d0679f6 Mon Sep 17 00:00:00 2001 From: violetaperezandrade Date: Sat, 13 Apr 2024 17:42:23 -0300 Subject: [PATCH 5/5] fix url -.- --- src/resource.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/resource.py b/src/resource.py index 9d09eb2..1e903b9 100644 --- a/src/resource.py +++ b/src/resource.py @@ -27,6 +27,7 @@ def getExtraData(): "device-plant": Measurements(), "plants": Plants(), "plant-type": Plants(), + "plant-types": Plants(), "logs": Plants(), "login": Users(), # TODO: Add the new service