WealthFromAI/data-science-ml-document-generation-api-2fd7
0
1"""
2Simple JWT auth — swap for OAuth2/API keys in production.
3"""
4import os
5from datetime import datetime, timedelta, timezone
6from typing import Optional
7from fastapi import Depends, HTTPException, status
8from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
9from jose import JWTError, jwt
10from passlib.context import CryptContext
11
12SECRET_KEY = os.getenv("SECRET_KEY", "changeme-in-production-please")
13ALGORITHM = os.getenv("ALGORITHM", "HS256")
14EXPIRE_MINUTES = int(os.getenv("ACCESS_TOKEN_EXPIRE_MINUTES", "30"))
15
16pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
17security = HTTPBearer()
18
19# Demo users — replace with real DB lookup
20USERS: dict[str, str] = {
21 "admin": pwd_context.hash("admin123"),
22 "demo": pwd_context.hash("demo123"),
23}
24
25
26def verify_password(username: str, password: str) -> bool:
27 hashed = USERS.get(username)
28 if not hashed:
29 return False
30 return pwd_context.verify(password, hashed)
31
32
33def create_access_token(data: dict) -> str:
34 to_encode = data.copy()
35 expire = datetime.now(timezone.utc) + timedelta(minutes=EXPIRE_MINUTES)
36 to_encode["exp"] = expire
37 return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
38
39
40def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(security)) -> str:
41 token = credentials.credentials
42 try:
43 payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
44 username: Optional[str] = payload.get("sub")
45 if not username:
46 raise HTTPException(status_code=401, detail="Invalid token payload")
47 return username
48 except JWTError:
49 raise HTTPException(
50 status_code=status.HTTP_401_UNAUTHORIZED,
51 detail="Invalid or expired token",
52 headers={"WWW-Authenticate": "Bearer"},
53 )
54 