From: Adam Dullage Date: Wed, 5 Oct 2022 12:20:58 +0000 (+0100) Subject: Added Config class X-Git-Url: http://git.99rst.org/?a=commitdiff_plain;h=ee2ac1491cb6b3233a29cf45c0141596aeab11e4;p=flatnotes.git Added Config class --- diff --git a/flatnotes/auth.py b/flatnotes/auth.py index 23cece7..6c4d7a3 100644 --- a/flatnotes/auth.py +++ b/flatnotes/auth.py @@ -1,15 +1,11 @@ -import os from datetime import datetime, timedelta from fastapi import Depends, HTTPException from fastapi.security import OAuth2PasswordBearer from jose import JWTError, jwt -FLATNOTES_USERNAME = os.environ["FLATNOTES_USERNAME"] -FLATNOTES_PASSWORD = os.environ["FLATNOTES_PASSWORD"] +from config import config -JWT_SECRET_KEY = os.environ["FLATNOTES_SECRET_KEY"] -JWT_EXPIRE_DAYS = int(os.environ.get("FLATNOTES_SESSION_EXPIRY_DAYS", 30)) JWT_ALGORITHM = "HS256" oauth2_scheme = OAuth2PasswordBearer(tokenUrl="api/token") @@ -17,21 +13,25 @@ oauth2_scheme = OAuth2PasswordBearer(tokenUrl="api/token") def create_access_token(data: dict): to_encode = data.copy() - expiry_datetime = datetime.utcnow() + timedelta(days=JWT_EXPIRE_DAYS) + expiry_datetime = datetime.utcnow() + timedelta( + days=config.session_expiry_days + ) to_encode.update({"exp": expiry_datetime}) encoded_jwt = jwt.encode( - to_encode, JWT_SECRET_KEY, algorithm=JWT_ALGORITHM + to_encode, config.session_key, algorithm=JWT_ALGORITHM ) return encoded_jwt async def validate_token(token: str = Depends(oauth2_scheme)): try: - payload = jwt.decode(token, JWT_SECRET_KEY, algorithms=[JWT_ALGORITHM]) + payload = jwt.decode( + token, config.session_key, algorithms=[JWT_ALGORITHM] + ) username = payload.get("sub") - if username is None or username.lower() != FLATNOTES_USERNAME.lower(): + if username is None or username.lower() != config.username.lower(): raise ValueError - return FLATNOTES_USERNAME + return config.username except (JWTError, ValueError): raise HTTPException( status_code=401, diff --git a/flatnotes/config.py b/flatnotes/config.py new file mode 100644 index 0000000..5bec5b8 --- /dev/null +++ b/flatnotes/config.py @@ -0,0 +1,30 @@ +import os + + +class Config: + def __init__(self) -> None: + self.data_path = self.load_data_path() + + self.username = self.load_username() + self.password = self.load_password() + + self.session_key = self.load_session_key() + self.session_expiry_days = self.load_session_expiry_days() + + def load_data_path(self): + return os.environ["FLATNOTES_PATH"] + + def load_username(self): + return os.environ["FLATNOTES_USERNAME"] + + def load_password(self): + return os.environ["FLATNOTES_PASSWORD"] + + def load_session_key(self): + return os.environ["FLATNOTES_SECRET_KEY"] + + def load_session_expiry_days(self): + return int(os.environ.get("FLATNOTES_SESSION_EXPIRY_DAYS", 30)) + + +config = Config() diff --git a/flatnotes/main.py b/flatnotes/main.py index 9c46a88..96e1c73 100644 --- a/flatnotes/main.py +++ b/flatnotes/main.py @@ -3,23 +3,19 @@ import os import secrets from typing import List, Literal -from auth import ( - FLATNOTES_PASSWORD, - FLATNOTES_USERNAME, - create_access_token, - validate_token, -) +from fastapi import Depends, FastAPI, HTTPException +from fastapi.responses import HTMLResponse +from fastapi.staticfiles import StaticFiles + +from auth import create_access_token, validate_token +from config import config from error_responses import ( invalid_title_response, note_not_found_response, title_exists_response, ) -from fastapi import Depends, FastAPI, HTTPException -from fastapi.responses import HTMLResponse -from fastapi.staticfiles import StaticFiles -from models import LoginModel, NoteModel, NotePatchModel, SearchResultModel - from flatnotes import Flatnotes, InvalidTitleError, Note +from models import LoginModel, NoteModel, NotePatchModel, SearchResultModel logging.basicConfig( format="%(asctime)s [%(levelname)s]: %(message)s", @@ -29,22 +25,20 @@ logger = logging.getLogger() logger.setLevel(os.environ.get("LOGLEVEL", "INFO").upper()) app = FastAPI() -flatnotes = Flatnotes(os.environ["FLATNOTES_PATH"]) +flatnotes = Flatnotes(config.data_path) @app.post("/api/token") async def token(data: LoginModel): username_correct = secrets.compare_digest( - FLATNOTES_USERNAME.lower(), data.username.lower() - ) - password_correct = secrets.compare_digest( - FLATNOTES_PASSWORD, data.password + config.username.lower(), data.username.lower() ) + password_correct = secrets.compare_digest(config.password, data.password) if not (username_correct and password_correct): raise HTTPException( status_code=400, detail="Incorrect username or password" ) - access_token = create_access_token(data={"sub": FLATNOTES_USERNAME}) + access_token = create_access_token(data={"sub": config.username}) return {"access_token": access_token, "token_type": "bearer"}