feat(middleware): harden routing with fail-closed policy, custom subdomain management, and perf fixes
- Fix IPv6 host parsing with _strip_port() utility - Remove dangerous StorePlatform→Store.subdomain silent fallback - Close storefront gate bypass when frontend_type is None - Add custom subdomain management UI and API for stores - Add domain health diagnostic tool - Convert db.add() in loops to db.add_all() (24 PERF-006 fixes) - Add tests for all new functionality (18 subdomain service tests) - Add .github templates for validator compliance Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -83,6 +83,11 @@ def _is_static_request(path: str) -> bool:
|
||||
return "favicon.ico" in lower
|
||||
|
||||
|
||||
def _looks_like_storefront(path: str) -> bool:
|
||||
"""Return True if path belongs to the storefront surface."""
|
||||
return path.startswith(("/storefront/", "/api/v1/storefront/"))
|
||||
|
||||
|
||||
class StorefrontAccessMiddleware(BaseHTTPMiddleware):
|
||||
"""
|
||||
Gate storefront requests behind an active subscription.
|
||||
@@ -94,6 +99,25 @@ class StorefrontAccessMiddleware(BaseHTTPMiddleware):
|
||||
async def dispatch(self, request: Request, call_next) -> Response:
|
||||
frontend_type = getattr(request.state, "frontend_type", None)
|
||||
|
||||
# Safety net: if frontend_type is None (upstream middleware failed) but
|
||||
# the path looks like a storefront path, block instead of letting it
|
||||
# through — a None frontend_type must never bypass the gate.
|
||||
if frontend_type is None and _looks_like_storefront(request.url.path):
|
||||
logger.error(
|
||||
"[STOREFRONT_ACCESS] frontend_type is None on storefront path "
|
||||
f"'{request.url.path}' — blocking (fail-closed). "
|
||||
"Check middleware chain ordering."
|
||||
)
|
||||
if request.url.path.startswith("/api/"):
|
||||
return JSONResponse(
|
||||
status_code=403,
|
||||
content={
|
||||
"error": "storefront_not_available",
|
||||
"reason": "middleware_misconfigured",
|
||||
},
|
||||
)
|
||||
return self._render_unavailable(request, "not_found")
|
||||
|
||||
# Only gate storefront requests
|
||||
if frontend_type != FrontendType.STOREFRONT:
|
||||
return await call_next(request)
|
||||
|
||||
Reference in New Issue
Block a user