style: apply black and isort formatting across entire codebase
- Standardize quote style (single to double quotes) - Reorder and group imports alphabetically - Fix line breaks and indentation for consistency - Apply PEP 8 formatting standards Also updated Makefile to exclude both venv and .venv from code quality checks. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
193
app/api/deps.py
193
app/api/deps.py
@@ -34,22 +34,20 @@ The cookie path restrictions prevent cross-context cookie leakage:
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import Depends, Request, Cookie
|
||||
from fastapi import Cookie, Depends, Request
|
||||
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.core.database import get_db
|
||||
from app.exceptions import (AdminRequiredException,
|
||||
InsufficientPermissionsException,
|
||||
InvalidTokenException,
|
||||
UnauthorizedVendorAccessException,
|
||||
VendorNotFoundException)
|
||||
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,
|
||||
InvalidTokenException,
|
||||
InsufficientPermissionsException,
|
||||
VendorNotFoundException,
|
||||
UnauthorizedVendorAccessException
|
||||
)
|
||||
from models.database.vendor import Vendor
|
||||
|
||||
# Initialize dependencies
|
||||
security = HTTPBearer(auto_error=False) # auto_error=False prevents automatic 403
|
||||
@@ -62,11 +60,12 @@ logger = logging.getLogger(__name__)
|
||||
# HELPER FUNCTIONS
|
||||
# ============================================================================
|
||||
|
||||
|
||||
def _get_token_from_request(
|
||||
credentials: Optional[HTTPAuthorizationCredentials],
|
||||
cookie_value: Optional[str],
|
||||
cookie_name: str,
|
||||
request_path: str
|
||||
credentials: Optional[HTTPAuthorizationCredentials],
|
||||
cookie_value: Optional[str],
|
||||
cookie_name: str,
|
||||
request_path: str,
|
||||
) -> tuple[Optional[str], Optional[str]]:
|
||||
"""
|
||||
Extract token from Authorization header or cookie.
|
||||
@@ -108,10 +107,7 @@ def _validate_user_token(token: str, db: Session) -> User:
|
||||
Raises:
|
||||
InvalidTokenException: If token is invalid
|
||||
"""
|
||||
mock_credentials = HTTPAuthorizationCredentials(
|
||||
scheme="Bearer",
|
||||
credentials=token
|
||||
)
|
||||
mock_credentials = HTTPAuthorizationCredentials(scheme="Bearer", credentials=token)
|
||||
return auth_manager.get_current_user(db, mock_credentials)
|
||||
|
||||
|
||||
@@ -119,11 +115,12 @@ def _validate_user_token(token: str, db: Session) -> User:
|
||||
# ADMIN AUTHENTICATION
|
||||
# ============================================================================
|
||||
|
||||
|
||||
def get_current_admin_from_cookie_or_header(
|
||||
request: Request,
|
||||
credentials: Optional[HTTPAuthorizationCredentials] = Depends(security),
|
||||
admin_token: Optional[str] = Cookie(None),
|
||||
db: Session = Depends(get_db),
|
||||
request: Request,
|
||||
credentials: Optional[HTTPAuthorizationCredentials] = Depends(security),
|
||||
admin_token: Optional[str] = Cookie(None),
|
||||
db: Session = Depends(get_db),
|
||||
) -> User:
|
||||
"""
|
||||
Get current admin user from admin_token cookie or Authorization header.
|
||||
@@ -148,10 +145,7 @@ def get_current_admin_from_cookie_or_header(
|
||||
AdminRequiredException: If user is not admin
|
||||
"""
|
||||
token, source = _get_token_from_request(
|
||||
credentials,
|
||||
admin_token,
|
||||
"admin_token",
|
||||
str(request.url.path)
|
||||
credentials, admin_token, "admin_token", str(request.url.path)
|
||||
)
|
||||
|
||||
if not token:
|
||||
@@ -172,8 +166,8 @@ def get_current_admin_from_cookie_or_header(
|
||||
|
||||
|
||||
def get_current_admin_api(
|
||||
credentials: HTTPAuthorizationCredentials = Depends(security),
|
||||
db: Session = Depends(get_db),
|
||||
credentials: HTTPAuthorizationCredentials = Depends(security),
|
||||
db: Session = Depends(get_db),
|
||||
) -> User:
|
||||
"""
|
||||
Get current admin user from Authorization header ONLY.
|
||||
@@ -208,11 +202,12 @@ def get_current_admin_api(
|
||||
# VENDOR AUTHENTICATION
|
||||
# ============================================================================
|
||||
|
||||
|
||||
def get_current_vendor_from_cookie_or_header(
|
||||
request: Request,
|
||||
credentials: Optional[HTTPAuthorizationCredentials] = Depends(security),
|
||||
vendor_token: Optional[str] = Cookie(None),
|
||||
db: Session = Depends(get_db),
|
||||
request: Request,
|
||||
credentials: Optional[HTTPAuthorizationCredentials] = Depends(security),
|
||||
vendor_token: Optional[str] = Cookie(None),
|
||||
db: Session = Depends(get_db),
|
||||
) -> User:
|
||||
"""
|
||||
Get current vendor user from vendor_token cookie or Authorization header.
|
||||
@@ -237,10 +232,7 @@ def get_current_vendor_from_cookie_or_header(
|
||||
InsufficientPermissionsException: If user is not vendor or is admin
|
||||
"""
|
||||
token, source = _get_token_from_request(
|
||||
credentials,
|
||||
vendor_token,
|
||||
"vendor_token",
|
||||
str(request.url.path)
|
||||
credentials, vendor_token, "vendor_token", str(request.url.path)
|
||||
)
|
||||
|
||||
if not token:
|
||||
@@ -270,8 +262,8 @@ def get_current_vendor_from_cookie_or_header(
|
||||
|
||||
|
||||
def get_current_vendor_api(
|
||||
credentials: HTTPAuthorizationCredentials = Depends(security),
|
||||
db: Session = Depends(get_db),
|
||||
credentials: HTTPAuthorizationCredentials = Depends(security),
|
||||
db: Session = Depends(get_db),
|
||||
) -> User:
|
||||
"""
|
||||
Get current vendor user from Authorization header ONLY.
|
||||
@@ -310,11 +302,12 @@ def get_current_vendor_api(
|
||||
# CUSTOMER AUTHENTICATION (SHOP)
|
||||
# ============================================================================
|
||||
|
||||
|
||||
def get_current_customer_from_cookie_or_header(
|
||||
request: Request,
|
||||
credentials: Optional[HTTPAuthorizationCredentials] = Depends(security),
|
||||
customer_token: Optional[str] = Cookie(None),
|
||||
db: Session = Depends(get_db),
|
||||
request: Request,
|
||||
credentials: Optional[HTTPAuthorizationCredentials] = Depends(security),
|
||||
customer_token: Optional[str] = Cookie(None),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Get current customer from customer_token cookie or Authorization header.
|
||||
@@ -338,15 +331,14 @@ def get_current_customer_from_cookie_or_header(
|
||||
Raises:
|
||||
InvalidTokenException: If no token or invalid token
|
||||
"""
|
||||
from models.database.customer import Customer
|
||||
from jose import jwt, JWTError
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from jose import JWTError, jwt
|
||||
|
||||
from models.database.customer import Customer
|
||||
|
||||
token, source = _get_token_from_request(
|
||||
credentials,
|
||||
customer_token,
|
||||
"customer_token",
|
||||
str(request.url.path)
|
||||
credentials, customer_token, "customer_token", str(request.url.path)
|
||||
)
|
||||
|
||||
if not token:
|
||||
@@ -356,9 +348,7 @@ def get_current_customer_from_cookie_or_header(
|
||||
# Decode and validate customer JWT token
|
||||
try:
|
||||
payload = jwt.decode(
|
||||
token,
|
||||
auth_manager.secret_key,
|
||||
algorithms=[auth_manager.algorithm]
|
||||
token, auth_manager.secret_key, algorithms=[auth_manager.algorithm]
|
||||
)
|
||||
|
||||
# Verify this is a customer token
|
||||
@@ -375,7 +365,9 @@ def get_current_customer_from_cookie_or_header(
|
||||
|
||||
# Verify token hasn't expired
|
||||
exp = payload.get("exp")
|
||||
if exp and datetime.fromtimestamp(exp, tz=timezone.utc) < datetime.now(timezone.utc):
|
||||
if exp and datetime.fromtimestamp(exp, tz=timezone.utc) < datetime.now(
|
||||
timezone.utc
|
||||
):
|
||||
logger.warning(f"Expired customer token for customer_id={customer_id}")
|
||||
raise InvalidTokenException("Token has expired")
|
||||
|
||||
@@ -400,8 +392,8 @@ def get_current_customer_from_cookie_or_header(
|
||||
|
||||
|
||||
def get_current_customer_api(
|
||||
credentials: HTTPAuthorizationCredentials = Depends(security),
|
||||
db: Session = Depends(get_db),
|
||||
credentials: HTTPAuthorizationCredentials = Depends(security),
|
||||
db: Session = Depends(get_db),
|
||||
) -> User:
|
||||
"""
|
||||
Get current customer user from Authorization header ONLY.
|
||||
@@ -445,9 +437,10 @@ def get_current_customer_api(
|
||||
# GENERIC AUTHENTICATION (for mixed-use endpoints)
|
||||
# ============================================================================
|
||||
|
||||
|
||||
def get_current_user(
|
||||
credentials: HTTPAuthorizationCredentials = Depends(security),
|
||||
db: Session = Depends(get_db)
|
||||
credentials: HTTPAuthorizationCredentials = Depends(security),
|
||||
db: Session = Depends(get_db),
|
||||
) -> User:
|
||||
"""
|
||||
Get current authenticated user from Authorization header only.
|
||||
@@ -475,10 +468,11 @@ def get_current_user(
|
||||
# VENDOR OWNERSHIP VERIFICATION
|
||||
# ============================================================================
|
||||
|
||||
|
||||
def get_user_vendor(
|
||||
vendor_code: str,
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
vendor_code: str,
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
) -> Vendor:
|
||||
"""
|
||||
Get vendor and verify user ownership/membership.
|
||||
@@ -500,9 +494,7 @@ def get_user_vendor(
|
||||
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()
|
||||
vendor = db.query(Vendor).filter(Vendor.vendor_code == vendor_code.upper()).first()
|
||||
|
||||
if not vendor:
|
||||
raise VendorNotFoundException(vendor_code)
|
||||
@@ -517,10 +509,12 @@ def get_user_vendor(
|
||||
# User doesn't have access to this vendor
|
||||
raise UnauthorizedVendorAccessException(vendor_code, current_user.id)
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# PERMISSIONS CHECKING
|
||||
# ============================================================================
|
||||
|
||||
|
||||
def require_vendor_permission(permission: str):
|
||||
"""
|
||||
Dependency factory to require a specific vendor permission.
|
||||
@@ -535,9 +529,9 @@ def require_vendor_permission(permission: str):
|
||||
"""
|
||||
|
||||
def permission_checker(
|
||||
request: Request,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header),
|
||||
request: Request,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header),
|
||||
) -> User:
|
||||
# Get vendor from request state (set by middleware)
|
||||
vendor = getattr(request.state, "vendor", None)
|
||||
@@ -557,9 +551,9 @@ def require_vendor_permission(permission: str):
|
||||
|
||||
|
||||
def require_vendor_owner(
|
||||
request: Request,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header),
|
||||
request: Request,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header),
|
||||
) -> User:
|
||||
"""
|
||||
Dependency to require vendor owner role.
|
||||
@@ -600,9 +594,9 @@ def require_any_vendor_permission(*permissions: str):
|
||||
"""
|
||||
|
||||
def permission_checker(
|
||||
request: Request,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header),
|
||||
request: Request,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header),
|
||||
) -> User:
|
||||
vendor = getattr(request.state, "vendor", None)
|
||||
if not vendor:
|
||||
@@ -610,8 +604,7 @@ def require_any_vendor_permission(*permissions: str):
|
||||
|
||||
# Check if user has ANY of the required permissions
|
||||
has_permission = any(
|
||||
current_user.has_vendor_permission(vendor.id, perm)
|
||||
for perm in permissions
|
||||
current_user.has_vendor_permission(vendor.id, perm) for perm in permissions
|
||||
)
|
||||
|
||||
if not has_permission:
|
||||
@@ -641,9 +634,9 @@ def require_all_vendor_permissions(*permissions: str):
|
||||
"""
|
||||
|
||||
def permission_checker(
|
||||
request: Request,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header),
|
||||
request: Request,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header),
|
||||
) -> User:
|
||||
vendor = getattr(request.state, "vendor", None)
|
||||
if not vendor:
|
||||
@@ -651,7 +644,8 @@ def require_all_vendor_permissions(*permissions: str):
|
||||
|
||||
# Check if user has ALL required permissions
|
||||
missing_permissions = [
|
||||
perm for perm in permissions
|
||||
perm
|
||||
for perm in permissions
|
||||
if not current_user.has_vendor_permission(vendor.id, perm)
|
||||
]
|
||||
|
||||
@@ -667,8 +661,8 @@ def require_all_vendor_permissions(*permissions: str):
|
||||
|
||||
|
||||
def get_user_permissions(
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header),
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header),
|
||||
) -> list:
|
||||
"""
|
||||
Get all permissions for current user in current vendor.
|
||||
@@ -682,6 +676,7 @@ def get_user_permissions(
|
||||
# If owner, return all permissions
|
||||
if current_user.is_owner_of(vendor.id):
|
||||
from app.core.permissions import VendorPermissions
|
||||
|
||||
return [p.value for p in VendorPermissions]
|
||||
|
||||
# Get permissions from vendor membership
|
||||
@@ -696,11 +691,12 @@ def get_user_permissions(
|
||||
# OPTIONAL AUTHENTICATION (For Login Page Redirects)
|
||||
# ============================================================================
|
||||
|
||||
|
||||
def get_current_admin_optional(
|
||||
request: Request,
|
||||
credentials: Optional[HTTPAuthorizationCredentials] = Depends(security),
|
||||
admin_token: Optional[str] = Cookie(None),
|
||||
db: Session = Depends(get_db),
|
||||
request: Request,
|
||||
credentials: Optional[HTTPAuthorizationCredentials] = Depends(security),
|
||||
admin_token: Optional[str] = Cookie(None),
|
||||
db: Session = Depends(get_db),
|
||||
) -> Optional[User]:
|
||||
"""
|
||||
Get current admin user from admin_token cookie or Authorization header.
|
||||
@@ -723,10 +719,7 @@ def get_current_admin_optional(
|
||||
None: If no token, invalid token, or user is not admin
|
||||
"""
|
||||
token, source = _get_token_from_request(
|
||||
credentials,
|
||||
admin_token,
|
||||
"admin_token",
|
||||
str(request.url.path)
|
||||
credentials, admin_token, "admin_token", str(request.url.path)
|
||||
)
|
||||
|
||||
if not token:
|
||||
@@ -747,10 +740,10 @@ def get_current_admin_optional(
|
||||
|
||||
|
||||
def get_current_vendor_optional(
|
||||
request: Request,
|
||||
credentials: Optional[HTTPAuthorizationCredentials] = Depends(security),
|
||||
vendor_token: Optional[str] = Cookie(None),
|
||||
db: Session = Depends(get_db),
|
||||
request: Request,
|
||||
credentials: Optional[HTTPAuthorizationCredentials] = Depends(security),
|
||||
vendor_token: Optional[str] = Cookie(None),
|
||||
db: Session = Depends(get_db),
|
||||
) -> Optional[User]:
|
||||
"""
|
||||
Get current vendor user from vendor_token cookie or Authorization header.
|
||||
@@ -773,10 +766,7 @@ def get_current_vendor_optional(
|
||||
None: If no token, invalid token, or user is not vendor
|
||||
"""
|
||||
token, source = _get_token_from_request(
|
||||
credentials,
|
||||
vendor_token,
|
||||
"vendor_token",
|
||||
str(request.url.path)
|
||||
credentials, vendor_token, "vendor_token", str(request.url.path)
|
||||
)
|
||||
|
||||
if not token:
|
||||
@@ -797,10 +787,10 @@ def get_current_vendor_optional(
|
||||
|
||||
|
||||
def get_current_customer_optional(
|
||||
request: Request,
|
||||
credentials: Optional[HTTPAuthorizationCredentials] = Depends(security),
|
||||
customer_token: Optional[str] = Cookie(None),
|
||||
db: Session = Depends(get_db),
|
||||
request: Request,
|
||||
credentials: Optional[HTTPAuthorizationCredentials] = Depends(security),
|
||||
customer_token: Optional[str] = Cookie(None),
|
||||
db: Session = Depends(get_db),
|
||||
) -> Optional[User]:
|
||||
"""
|
||||
Get current customer user from customer_token cookie or Authorization header.
|
||||
@@ -823,10 +813,7 @@ def get_current_customer_optional(
|
||||
None: If no token, invalid token, or user is not customer
|
||||
"""
|
||||
token, source = _get_token_from_request(
|
||||
credentials,
|
||||
customer_token,
|
||||
"customer_token",
|
||||
str(request.url.path)
|
||||
credentials, customer_token, "customer_token", str(request.url.path)
|
||||
)
|
||||
|
||||
if not token:
|
||||
@@ -844,5 +831,3 @@ def get_current_customer_optional(
|
||||
pass
|
||||
|
||||
return None
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user