Working state before icon/utils fixes - Oct 22

This commit is contained in:
2025-10-21 21:56:54 +02:00
parent a7d9d44a13
commit 5be47b91a2
39 changed files with 6017 additions and 508 deletions

View File

@@ -1,13 +1,18 @@
# app/api/deps.py
"""Summary description ....
"""
Authentication dependencies for FastAPI routes.
This module provides classes and functions for:
- ....
- ....
- ....
Implements dual token storage pattern:
- Checks Authorization header first (for API calls from JavaScript)
- Falls back to cookie (for browser page navigation)
This allows:
- JavaScript API calls: Use localStorage + Authorization header
- Browser page loads: Use HTTP-only cookies
"""
from fastapi import Depends
from typing import Optional
from fastapi import Depends, Request, Cookie
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
from sqlalchemy.orm import Session
@@ -16,7 +21,12 @@ from middleware.auth import AuthManager
from middleware.rate_limiter import RateLimiter
from models.database.vendor import Vendor
from models.database.user import User
from app.exceptions import (AdminRequiredException, VendorNotFoundException, UnauthorizedVendorAccessException)
from app.exceptions import (
AdminRequiredException,
VendorNotFoundException,
UnauthorizedVendorAccessException,
InvalidTokenException
)
# Set auto_error=False to prevent automatic 403 responses
security = HTTPBearer(auto_error=False)
@@ -25,30 +35,107 @@ rate_limiter = RateLimiter()
def get_current_user(
credentials: HTTPAuthorizationCredentials = Depends(security),
db: Session = Depends(get_db),
request: Request,
credentials: Optional[HTTPAuthorizationCredentials] = Depends(security),
admin_token: Optional[str] = Cookie(None), # Check admin_token cookie
db: Session = Depends(get_db),
):
"""Get current authenticated user."""
# Check if credentials are provided
if not credentials:
from app.exceptions.auth import InvalidTokenException
raise InvalidTokenException("Authorization header required")
"""
Get current authenticated user.
return auth_manager.get_current_user(db, credentials)
Checks for token in this priority order:
1. Authorization header (for API calls from JavaScript)
2. admin_token cookie (for browser page navigation)
This dual approach supports:
- API calls: JavaScript adds token from localStorage to Authorization header
- Page navigation: Browser automatically sends cookie
Args:
request: FastAPI request object
credentials: Optional Bearer token from Authorization header
admin_token: Optional token from cookie
db: Database session
Returns:
User: Authenticated user object
Raises:
InvalidTokenException: If no token found or token invalid
"""
token = None
token_source = None
# Priority 1: Authorization header (API calls from JavaScript)
if credentials:
token = credentials.credentials
token_source = "header"
# Priority 2: Cookie (browser page navigation)
elif admin_token:
token = admin_token
token_source = "cookie"
# No token found in either location
if not token:
raise InvalidTokenException("Authorization header or cookie required")
# Log token source for debugging
import logging
logger = logging.getLogger(__name__)
logger.debug(f"Token found in {token_source} for {request.url.path}")
# Create a mock credentials object for auth_manager
mock_credentials = HTTPAuthorizationCredentials(
scheme="Bearer",
credentials=token
)
return auth_manager.get_current_user(db, mock_credentials)
def get_current_admin_user(current_user: User = Depends(get_current_user)):
"""Require admin user."""
"""
Require admin user.
This dependency ensures the current user has admin role.
Used for protecting admin-only routes.
Args:
current_user: User object from get_current_user dependency
Returns:
User: Admin user object
Raises:
AdminRequiredException: If user is not an admin
"""
return auth_manager.require_admin(current_user)
def get_user_vendor(
vendor_code: str,
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db),
vendor_code: str,
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db),
):
"""Get vendor and verify user ownership."""
"""
Get vendor and verify user ownership.
Ensures the current user has access to the specified vendor.
Admin users can access any vendor, regular users only their own.
Args:
vendor_code: Vendor code to look up
current_user: Current authenticated user
db: Database session
Returns:
Vendor: Vendor object if user has access
Raises:
VendorNotFoundException: If vendor doesn't exist
UnauthorizedVendorAccessException: If user doesn't have access
"""
vendor = db.query(Vendor).filter(Vendor.vendor_code == vendor_code.upper()).first()
if not vendor:
raise VendorNotFoundException(vendor_code)
@@ -57,4 +144,3 @@ def get_user_vendor(
raise UnauthorizedVendorAccessException(vendor_code, current_user.id)
return vendor