From 3e148b92bfa81dd36c3516f5b47185c55d47c795 Mon Sep 17 00:00:00 2001 From: hanfi <ccc@spahan.ch> Date: Mon, 24 Jul 2023 10:13:27 +0200 Subject: [PATCH] add auth for worker endpoints --- backend/config.py | 3 +++ backend/main.py | 33 +++++++++++++++++++++++++++++++-- requirements.txt | 1 + 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/backend/config.py b/backend/config.py index 313984a..d2da3f0 100644 --- a/backend/config.py +++ b/backend/config.py @@ -8,6 +8,9 @@ class Settings(BaseSettings): backend_url: str = "http://localhost:8000" customer_url: str = "http://localhost:3000" worker_url: str = "http://localhost:3002" + shared_secret: str = "worker_secret" + signing_key: str = "2d18526256a001bc0553c9957897d75d" + token_lifetime: int = 60 # auth token lifetime class Config: env_file = ".env" diff --git a/backend/main.py b/backend/main.py index 82d1274..fc61189 100644 --- a/backend/main.py +++ b/backend/main.py @@ -1,7 +1,10 @@ +import datetime from uuid import UUID -from fastapi import Depends, FastAPI, HTTPException, Request +from fastapi import Depends, FastAPI, HTTPException, Request, status from fastapi.middleware.cors import CORSMiddleware +from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm +from itsdangerous.serializer import Serializer from slowapi import Limiter, _rate_limit_exceeded_handler from slowapi.errors import RateLimitExceeded from slowapi.util import get_remote_address @@ -26,6 +29,8 @@ app.add_middleware( limiter = Limiter(key_func=get_remote_address) app.state.limiter = limiter app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler) +oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") +oauth2_tokener = Serializer(settings.signing_key) # Dependency @@ -66,7 +71,16 @@ def get_item(item_uuid: str, db: Session = Depends(get_db)): @app.get("/items", response_model=list[schemas.Item]) -def get_items(db: Session = Depends(get_db)): +def get_items(token: str = Depends(oauth2_scheme), db: Session = Depends(get_db)): + if ( + datetime.datetime.fromtimestamp(oauth2_tokener.loads(token)) + < datetime.datetime.now() + ): + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="Invalid authentication credentials", + headers={"WWW-Authenticate": "Bearer"}, + ) return utils.get_stored_items(db) @@ -92,3 +106,18 @@ def checkin_item_by_uuid(checkin: schemas.ItemCheckin, db: Session = Depends(get if storage is None: raise HTTPException(status_code=404, detail="Storage not found") return utils.receive_item(db, item, storage) + + +@app.post("/token") +def verify_supporter(form_data: OAuth2PasswordRequestForm = Depends()): + if form_data.password != settings.shared_secret: + raise HTTPException(status_code=400, detail="Incorrect username or password") + return { + "access_token": oauth2_tokener.dumps( + ( + datetime.datetime.now() + + datetime.timedelta(minutes=settings.token_lifetime) + ).timestamp() + ), + "token_type": "bearer", + } diff --git a/requirements.txt b/requirements.txt index cba80ad..0b0bc39 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,3 +5,4 @@ python-multipart==0.0.6 SQLAlchemy==2.0.9 uvicorn[standard]==0.21.1 slowapi==0.1.8 +itsdangerous==2.1.2 -- GitLab