refactor: enforce strict architecture rules and add Pydantic response models
- Update architecture rules to be stricter (API-003 now blocks ALL exception raising in endpoints, not just HTTPException) - Update get_current_vendor_api dependency to guarantee token_vendor_id presence - Remove redundant _get_vendor_from_token helpers from all vendor API files - Move vendor access validation to service layer methods - Add Pydantic response models for media, notification, and payment endpoints - Add get_active_vendor_by_code service method for public vendor lookup - Add get_import_job_for_vendor service method with vendor validation - Update validation script to detect exception raising patterns in endpoints 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -275,7 +275,9 @@ def get_current_vendor_api(
|
||||
Get current vendor user from Authorization header ONLY.
|
||||
|
||||
Used for vendor API endpoints that should not accept cookies.
|
||||
Validates that user still has access to the vendor specified in the token.
|
||||
Validates that:
|
||||
1. Token contains vendor context (token_vendor_id)
|
||||
2. User still has access to the vendor specified in the token
|
||||
|
||||
Args:
|
||||
credentials: Bearer token from Authorization header
|
||||
@@ -285,7 +287,7 @@ def get_current_vendor_api(
|
||||
User: Authenticated vendor user (with token_vendor_id, token_vendor_code, token_vendor_role)
|
||||
|
||||
Raises:
|
||||
InvalidTokenException: If no token or invalid token
|
||||
InvalidTokenException: If no token, invalid token, or missing vendor context
|
||||
InsufficientPermissionsException: If user is not vendor or lost access to vendor
|
||||
"""
|
||||
if not credentials:
|
||||
@@ -302,23 +304,25 @@ def get_current_vendor_api(
|
||||
logger.warning(f"Non-vendor user {user.username} attempted vendor API")
|
||||
raise InsufficientPermissionsException("Vendor privileges required")
|
||||
|
||||
# Validate vendor access if token is vendor-scoped
|
||||
if hasattr(user, "token_vendor_id"):
|
||||
vendor_id = user.token_vendor_id
|
||||
# Require vendor context in token
|
||||
if not hasattr(user, "token_vendor_id"):
|
||||
raise InvalidTokenException("Token missing vendor information. Please login again.")
|
||||
|
||||
# Verify user still has access to this vendor
|
||||
if not user.is_member_of(vendor_id):
|
||||
logger.warning(
|
||||
f"User {user.username} lost access to vendor_id={vendor_id}"
|
||||
)
|
||||
raise InsufficientPermissionsException(
|
||||
"Access to vendor has been revoked. Please login again."
|
||||
)
|
||||
vendor_id = user.token_vendor_id
|
||||
|
||||
logger.debug(
|
||||
f"Vendor API access: user={user.username}, vendor_id={vendor_id}, "
|
||||
f"vendor_code={getattr(user, 'token_vendor_code', 'N/A')}"
|
||||
# Verify user still has access to this vendor
|
||||
if not user.is_member_of(vendor_id):
|
||||
logger.warning(
|
||||
f"User {user.username} lost access to vendor_id={vendor_id}"
|
||||
)
|
||||
raise InsufficientPermissionsException(
|
||||
"Access to vendor has been revoked. Please login again."
|
||||
)
|
||||
|
||||
logger.debug(
|
||||
f"Vendor API access: user={user.username}, vendor_id={vendor_id}, "
|
||||
f"vendor_code={getattr(user, 'token_vendor_code', 'N/A')}"
|
||||
)
|
||||
|
||||
return user
|
||||
|
||||
|
||||
Reference in New Issue
Block a user