From 009174bc3cb99b8aa37602bce105a2f91b8dfa41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Vit=C3=B3ria=20Silva?= Date: Tue, 4 Jun 2024 16:56:02 +0100 Subject: [PATCH] authlib/joserfc and Jaeger is disable by default [backend] Moved from python-jose to authlib joserfc [backend] Removed python-jose[cryptography] and passlib[bcrypt] python requirements [backend] Removed some unwanted print statements left in the code [README] Updated README file based on backend jose changes. Fixed some typos and added some more information to env variables --- Dockerfile_backend | 2 +- README.md | 17 ++++++------ backend/crud/crud_users.py | 4 --- backend/schemas/schema_access_tokens.py | 37 ++++++++++--------------- docker-compose.yml | 7 +++-- requirements.txt | 5 ++-- 6 files changed, 29 insertions(+), 43 deletions(-) diff --git a/Dockerfile_backend b/Dockerfile_backend index a62f20001..0376960c4 100644 --- a/Dockerfile_backend +++ b/Dockerfile_backend @@ -35,7 +35,7 @@ ENV ACCESS_TOKEN_EXPIRE_MINUTES=30 ENV STRAVA_CLIENT_ID="changeme" ENV STRAVA_CLIENT_SECRET="changeme" ENV STRAVA_AUTH_CODE="changeme" -ENV JAEGER_ENABLED="true" +ENV JAEGER_ENABLED="false" ENV JAEGER_HOST="jaeger" ENV JAEGER_PROTOCOL="http" ENV JAGGER_PORT=4317 diff --git a/README.md b/README.md index 3e34f3a82..f51d3347e 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ Table bellow shows supported environemnt variables. Variables marked with option Environemnt variable | Default value | Optional | Notes --- | --- | --- | --- MY_APP_BACKEND_PROTOCOL | http | Yes | Needs to be https if you want to enable Strava integration. You may need to update this variable based on docker image spin up -MY_APP_BACKEND_HOST | localhost:98 | Yes | Needs to be set and be Internet faced/resolved if you want to enable Strava integration. Strava callback relies on this. You may need to update this variable based on docker image spin up +MY_APP_BACKEND_HOST | localhost:98 | Yes | Needs to be set and be Internet faced/resolved if you want to enable Strava integration. Strava callback relies on this. You may need to update this variable based on docker image spin up (api host or local ip (example: 192.168.1.10:98)) Frontend dependencies: - vue@3.4.24 @@ -84,22 +84,22 @@ Environemnt variable | Default value | Optional | Notes --- | --- | --- | --- DB_HOST | mariadb | Yes | N/A DB_PORT | 3306 | Yes | N/A -DB_USER | gearguardian | Yes | N/A +DB_USER | endurain | Yes | N/A DB_PASSWORD | changeme | `No` | N/A -DB_DATABASE | gearguardian | Yes | N/A +DB_DATABASE | endurain | Yes | N/A SECRET_KEY | changeme | `No` | N/A ALGORITHM | HS256 | Yes | N/A ACCESS_TOKEN_EXPIRE_MINUTES | 30 | Yes | N/A STRAVA_CLIENT_ID | changeme | `No` | N/A STRAVA_CLIENT_SECRET | changeme | `No` | N/A STRAVA_AUTH_CODE | changeme | `No` | N/A -JAEGER_ENABLED | true | Yes | N/A +JAEGER_ENABLED | false | Yes | N/A JAEGER_PROTOCOL | http | Yes | N/A JAEGER_HOST | jaeger | Yes | N/A JAGGER_PORT | 4317 | Yes | N/A STRAVA_DAYS_ACTIVITIES_ONLINK | 30 | Yes | N/A FRONTEND_PROTOCOL | http | Yes | Needs to be set if you want to enable Strava integration. You may need to update this variable based on docker image spin up -FRONTEND_HOST | frontend | Yes | Needs to be set if you want to enable Strava integration. You may need to update this variable based on docker image spin up +FRONTEND_HOST | frontend | Yes | Needs to be set if you want to enable Strava integration. You may need to update this variable based on docker image spin up (frontend host or local ip (example: 192.168.1.10:8080)) FRONTEND_PORT | frontend | Yes | Needs to be set if you want to enable Strava integration. You may need to update this variable based on docker image spin up GEOCODES_MAPS_API | changeme | `No` | Geocode maps offers a free plan consisting of 1 Request/Second. Registration necessary. @@ -108,8 +108,8 @@ Table bellow shows the obligatory environemnt variables for mariadb container. Y Environemnt variable | Default value | Optional | Notes --- | --- | --- | --- MYSQL_ROOT_PASSWORD | changeme | `No` | N/A -MYSQL_DATABASE | gearguardian | `No` | N/A -MYSQL_USER | gearguardian | `No` | N/A +MYSQL_DATABASE | endurain | `No` | N/A +MYSQL_USER | endurain | `No` | N/A MYSQL_PASSWORD | changeme | `No` | N/A Python backend dependencies used: @@ -119,8 +119,6 @@ Python backend dependencies used: - python-dotenv==1.0.1 - sqlalchemy==2.0.30 - mysqlclient==2.2.4 - - python-jose[cryptography]==3.3.0 - - passlib[bcrypt]==1.7.4 - apscheduler==3.10.4 - requests==2.32.2 - stravalib==1.7 @@ -130,6 +128,7 @@ Python backend dependencies used: - python-multipart==0.0.9 - gpxpy==1.6.2 - alembic==1.13.1 + - joserfc==0.11.1 --- # Strava integration diff --git a/backend/crud/crud_users.py b/backend/crud/crud_users.py index 5ca6a8f57..b0531be87 100644 --- a/backend/crud/crud_users.py +++ b/backend/crud/crud_users.py @@ -18,13 +18,9 @@ def delete_user_photo_filesystem(user_id: int): folder = "user_images" file = f"{user_id}.*" - print(os.path.join(folder, file)) - # Find all files matching the pattern files_to_delete = glob.glob(os.path.join(folder, file)) - print(f"Files to delete: {files_to_delete}") - # Remove each file found for file_path in files_to_delete: print(f"Deleting: {file_path}") diff --git a/backend/schemas/schema_access_tokens.py b/backend/schemas/schema_access_tokens.py index 703632f9f..b9b70ae62 100644 --- a/backend/schemas/schema_access_tokens.py +++ b/backend/schemas/schema_access_tokens.py @@ -4,7 +4,9 @@ from pydantic import BaseModel from datetime import datetime, timedelta, timezone from fastapi import Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer -from jose import JWTError, jwt +#from jose import JWTError, jwt +from joserfc import jwt +from joserfc.jwk import OctKey from sqlalchemy.orm import Session from constants import ( @@ -50,33 +52,21 @@ logger = logging.getLogger("myLogger") def decode_token(token: str = Depends(oauth2_scheme)): # Decode the token and return the payload - return jwt.decode(token, JWT_SECRET_KEY, algorithms=[JWT_ALGORITHM]) + return jwt.decode(token, OctKey.import_key(JWT_SECRET_KEY)) def validate_token_expiration(db: Session, token: str = Depends(oauth2_scheme)): # Try to decode the token and check if it is expired try: # Decode the token + # Mark exp claim as required + claims_requests = jwt.JWTClaimsRegistry(exp={"essential": True}) + + # decodes the token payload = decode_token(token) - # Get the expiration timestamp from the payload - expiration_timestamp = payload.get("exp") - - # If the expiration timestamp is None or if it is less than the current time raise an exception and log it - if ( - expiration_timestamp is None - or datetime.utcfromtimestamp(expiration_timestamp) < datetime.utcnow() - ): - logger.warning( - "Token expired | Returning 401 response" - ) - - # Raise an HTTPException with a 401 Unauthorized status code - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, - detail="Token no longer valid", - headers={"WWW-Authenticate": "Bearer"}, - ) + # Validate token exp + claims_requests.validate(payload.claims) except Exception: # Log the error and raise the exception logger.info( @@ -96,7 +86,7 @@ def get_token_user_id(token: str = Depends(oauth2_scheme)): payload = decode_token(token) # Get the user id from the payload - user_id = payload.get("id") + user_id = payload.claims["id"] if user_id is None: # If the user id is None raise an HTTPException with a 401 Unauthorized status code @@ -115,7 +105,7 @@ def get_token_access_type(token: str = Depends(oauth2_scheme)): payload = decode_token(token) # Get the admin access from the payload - access_type = payload.get("access_type") + access_type = payload.claims["access_type"] if access_type is None: # If the access type is None raise an HTTPException with a 401 Unauthorized status code @@ -156,7 +146,8 @@ def create_access_token( to_encode.update({"exp": expire}) # Encode the data and return the token - encoded_jwt = jwt.encode(to_encode, JWT_SECRET_KEY, algorithm=JWT_ALGORITHM) + #encoded_jwt = jwt.encode(to_encode, JWT_SECRET_KEY, algorithm=JWT_ALGORITHM) + encoded_jwt = jwt.encode({"alg": JWT_ALGORITHM}, to_encode, JWT_SECRET_KEY) # Return the token return encoded_jwt diff --git a/docker-compose.yml b/docker-compose.yml index 9f07b0b7a..1f8548a1e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -35,7 +35,7 @@ services: # - /endurain/backend:/app depends_on: - mariadb - - jaeger + - jaeger # optional restart: unless-stopped # mysql mariadb logic @@ -53,7 +53,8 @@ services: - /mariadb:/var/lib/mysql restart: unless-stopped - # Jaeger for opentelemetry + # Jaeger for opentelemetry - optional + # Jaeger is not enabled by default. If you do not need it or want it, you can remove this container jaeger: container_name: jaeger image: jaegertracing/all-in-one:latest @@ -75,7 +76,7 @@ services: - 9411:9411 restart: unless-stopped -# phpmyadmin for DB manipulation +# phpmyadmin for DB manipulation - optional phpmyadmin: container_name: phpmyadmin image: phpmyadmin diff --git a/requirements.txt b/requirements.txt index e2b99c3ea..a7fc46764 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,8 +4,6 @@ uvicorn==0.29.0 python-dotenv==1.0.1 sqlalchemy==2.0.30 mysqlclient==2.2.4 -python-jose[cryptography]==3.3.0 -passlib[bcrypt]==1.7.4 apscheduler==3.10.4 requests==2.32.2 stravalib==1.7 @@ -14,4 +12,5 @@ opentelemetry-instrumentation-fastapi==0.43b0 opentelemetry.exporter.otlp==1.22.0 python-multipart==0.0.9 gpxpy==1.6.2 -alembic==1.13.1 \ No newline at end of file +alembic==1.13.1 +joserfc==0.11.1 \ No newline at end of file