diff --git a/app/controller/Users.py b/app/controller/Users.py index 9ce09f1..e21c7dc 100644 --- a/app/controller/Users.py +++ b/app/controller/Users.py @@ -1,4 +1,4 @@ -from fastapi import status +from fastapi import status, Request from fastapi.encoders import jsonable_encoder from fastapi.responses import JSONResponse from service.Users import UsersService @@ -51,7 +51,8 @@ def handle_login(self, auth_code: str): }, ) - def handle_update_user(self, user_id: int, update_data: dict): + def handle_update_user(self, update_data: dict, request: Request): + user_id = self.users_service.retrieve_user_id(request) self.users_service.update_user(user_id, update_data) return { "message": "User updated successfully", diff --git a/app/exceptions/UserException.py b/app/exceptions/UserException.py index 4da9858..efe3e98 100644 --- a/app/exceptions/UserException.py +++ b/app/exceptions/UserException.py @@ -21,3 +21,17 @@ class InvalidURL(HTTPException): def __init__(self, detail: str): status_code = status.HTTP_400_BAD_REQUEST super().__init__(status_code=status_code, detail=detail) + + +class ForbiddenUser(HTTPException): + def __init__(self): + status_code = status.HTTP_403_FORBIDDEN + detail = "User is not authorized" + super().__init__(status_code=status_code, detail=detail) + + +class UnauthorizedUser(HTTPException): + def __init__(self): + status_code = status.HTTP_401_UNAUTHORIZED + detail = "Invalid credentials" + super().__init__(status_code=status_code, detail=detail) diff --git a/app/main.py b/app/main.py index 203173f..2647e16 100644 --- a/app/main.py +++ b/app/main.py @@ -1,4 +1,4 @@ -from fastapi import FastAPI +from fastapi import FastAPI, Request from controller.Users import UsersController from service.Users import UsersService from repository.Users import UsersRepository @@ -37,6 +37,8 @@ def login_with_google(request: LoginRequest): return users_controller.handle_login(request.auth_code) -@app.patch("/users/{user_id}") -def update_user(user_id: int, update_data: UpdateUserSchema): - return users_controller.handle_update_user(user_id, update_data.dict()) +@app.patch("/users/me") +async def update_user(update_data: UpdateUserSchema, + request: Request): + return users_controller.handle_update_user(update_data.dict(), + request) diff --git a/app/service/Users.py b/app/service/Users.py index b47debd..8c6f145 100644 --- a/app/service/Users.py +++ b/app/service/Users.py @@ -7,6 +7,8 @@ import re import jwt +TOKEN_FIELD_NAME = "x-access-token" + class UsersService: def __init__(self, user_repository: UsersRepository): @@ -32,9 +34,6 @@ def create_user(self, user_data: dict): raise e def update_user(self, user_id: int, update_data: dict): - # TODO: aca habria que chequear a partir del token, session o algo que - # es el propio usuario editando sus datos y no permitir - # que un usuario edite los de un tercero self.get_user(user_id) filtered_update_data = {k: v for k, v in update_data.items() if v is not None} @@ -106,3 +105,19 @@ def _validate_location(self, location): -180 <= location["long"] <= 180: return True return False + + def retrieve_user_id(self, request): + token = self.__get_token(request.headers) + payload = jwt.decode(token, + os.environ["JWT_SECRET"], + algorithms=["HS256"]) + return int(payload.get("user_id")) + + def __get_token(self, 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)