Spaces:
Runtime error
Runtime error
| import os | |
| from datetime import datetime, timedelta, timezone | |
| from itsdangerous import URLSafeTimedSerializer, BadSignature, SignatureExpired | |
| from fastapi import Request, Response | |
| from db import get_user_by_id | |
| SECRET_KEY = os.environ.get("SECRET_KEY", "dev-secret-key-change-in-production") | |
| COOKIE_NAME = "session" | |
| DEFAULT_SESSION_MAX_AGE_DAYS = 7 | |
| SECONDS_PER_DAY = 24 * 3600 | |
| def session_max_age_seconds() -> int: | |
| raw_days = os.environ.get("SESSION_MAX_AGE_DAYS", "").strip() | |
| if not raw_days: | |
| return DEFAULT_SESSION_MAX_AGE_DAYS * SECONDS_PER_DAY | |
| try: | |
| days = int(raw_days) | |
| except ValueError: | |
| return DEFAULT_SESSION_MAX_AGE_DAYS * SECONDS_PER_DAY | |
| if days < 1: | |
| return DEFAULT_SESSION_MAX_AGE_DAYS * SECONDS_PER_DAY | |
| return days * SECONDS_PER_DAY | |
| MAX_AGE = session_max_age_seconds() | |
| _serializer = URLSafeTimedSerializer(SECRET_KEY) | |
| def create_session_token(user_id: int) -> str: | |
| return _serializer.dumps({"user_id": user_id}) | |
| def verify_session_token(token: str) -> int | None: | |
| try: | |
| data = _serializer.loads(token, max_age=MAX_AGE) | |
| return data.get("user_id") | |
| except (BadSignature, SignatureExpired): | |
| return None | |
| def set_session_cookie(response: Response, user_id: int): | |
| token = create_session_token(user_id) | |
| response.set_cookie( | |
| COOKIE_NAME, | |
| token, | |
| max_age=MAX_AGE, | |
| httponly=True, | |
| samesite="lax", | |
| secure=os.environ.get("SECURE_COOKIES", "false").lower() == "true", | |
| ) | |
| def clear_session_cookie(response: Response): | |
| response.delete_cookie(COOKIE_NAME) | |
| def get_current_user(request: Request) -> dict | None: | |
| token = request.cookies.get(COOKIE_NAME) | |
| return get_current_user_from_token(token) | |
| def get_current_user_from_token(token: str | None) -> dict | None: | |
| if not token: | |
| return None | |
| user_id = verify_session_token(token) | |
| if not user_id: | |
| return None | |
| return get_user_by_id(user_id) | |