fix: make FrontendType mandatory in require_module_access
The require_module_access dependency was using path-based detection to determine admin vs vendor authentication, which failed for API routes (/api/v1/admin/*) because it only checked for /admin/*. Changes: - Make frontend_type parameter mandatory (was optional with fallback) - Remove path-based detection logic from require_module_access - Update all 33 module route files to pass explicit FrontendType: - 15 admin routes use FrontendType.ADMIN - 18 vendor routes use FrontendType.VENDOR This ensures authentication method is explicitly declared at route definition time, making it independent of URL structure and future-proof for API version changes. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -54,6 +54,7 @@ from middleware.rate_limiter import RateLimiter
|
||||
from app.modules.tenancy.models import User as UserModel
|
||||
from app.modules.tenancy.models import Vendor
|
||||
from models.schema.auth import UserContext
|
||||
from app.modules.enums import FrontendType
|
||||
|
||||
# Initialize dependencies
|
||||
security = HTTPBearer(auto_error=False) # auto_error=False prevents automatic 403
|
||||
@@ -429,7 +430,7 @@ def get_admin_with_platform_context(
|
||||
# ============================================================================
|
||||
|
||||
|
||||
def require_module_access(module_code: str):
|
||||
def require_module_access(module_code: str, frontend_type: FrontendType):
|
||||
"""
|
||||
Dependency factory for module-based route access control.
|
||||
|
||||
@@ -438,14 +439,18 @@ def require_module_access(module_code: str):
|
||||
tied to a specific menu item.
|
||||
|
||||
Usage:
|
||||
@router.get("/admin/billing/stripe-config")
|
||||
async def stripe_config(
|
||||
current_user: User = Depends(require_module_access("billing")),
|
||||
):
|
||||
...
|
||||
admin_router = APIRouter(
|
||||
dependencies=[Depends(require_module_access("messaging", FrontendType.ADMIN))]
|
||||
)
|
||||
|
||||
vendor_router = APIRouter(
|
||||
dependencies=[Depends(require_module_access("billing", FrontendType.VENDOR))]
|
||||
)
|
||||
|
||||
Args:
|
||||
module_code: Module code to check (e.g., "billing", "marketplace")
|
||||
frontend_type: Frontend type (ADMIN or VENDOR). Required to determine
|
||||
which authentication method to use.
|
||||
|
||||
Returns:
|
||||
Dependency function that validates module access and returns User
|
||||
@@ -459,12 +464,13 @@ def require_module_access(module_code: str):
|
||||
vendor_token: str | None = Cookie(None),
|
||||
db: Session = Depends(get_db),
|
||||
) -> UserContext:
|
||||
# Try admin auth first, then vendor
|
||||
user_context = None
|
||||
platform_id = None
|
||||
|
||||
# Check if this is an admin request
|
||||
if admin_token or (credentials and request.url.path.startswith("/admin")):
|
||||
# Use explicit frontend_type to determine authentication method
|
||||
is_admin_request = frontend_type == FrontendType.ADMIN
|
||||
|
||||
if is_admin_request:
|
||||
try:
|
||||
user_context = get_current_admin_from_cookie_or_header(
|
||||
request, credentials, admin_token, db
|
||||
@@ -477,12 +483,11 @@ def require_module_access(module_code: str):
|
||||
platform = getattr(request.state, "admin_platform", None)
|
||||
if platform:
|
||||
platform_id = platform.id
|
||||
# Note: token_platform_id is not on UserContext, would need to be added
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Check if this is a vendor request
|
||||
if not user_context and (vendor_token or (credentials and "/vendor/" in request.url.path)):
|
||||
# Handle vendor request
|
||||
if not user_context and frontend_type == FrontendType.VENDOR:
|
||||
try:
|
||||
user_context = get_current_vendor_from_cookie_or_header(
|
||||
request, credentials, vendor_token, db
|
||||
|
||||
Reference in New Issue
Block a user