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:
@@ -36,6 +36,31 @@ MAIN_PLATFORM_CODE = "main"
|
||||
_LOCAL_HOSTS = {"localhost", "127.0.0.1", "testserver"}
|
||||
|
||||
|
||||
def _strip_port(host: str) -> str:
|
||||
"""
|
||||
Remove port from host, handling IPv6 bracket notation.
|
||||
|
||||
Examples:
|
||||
"localhost:8000" → "localhost"
|
||||
"[::1]:8000" → "::1"
|
||||
"[::1]" → "::1"
|
||||
"example.com" → "example.com"
|
||||
"192.168.1.1:80" → "192.168.1.1"
|
||||
"""
|
||||
if not host:
|
||||
return host
|
||||
# IPv6 with brackets: [::1]:8000 or [::1]
|
||||
if host.startswith("["):
|
||||
bracket_end = host.find("]")
|
||||
if bracket_end != -1:
|
||||
return host[1:bracket_end]
|
||||
return host # malformed, return as-is
|
||||
# Regular host:port
|
||||
if ":" in host:
|
||||
return host.split(":")[0]
|
||||
return host
|
||||
|
||||
|
||||
class PlatformContextManager:
|
||||
"""Manages platform context detection for multi-platform routing."""
|
||||
|
||||
@@ -62,7 +87,7 @@ class PlatformContextManager:
|
||||
path = request.url.path
|
||||
|
||||
# Remove port from host if present (e.g., localhost:9999 -> localhost)
|
||||
host_without_port = host.split(":")[0] if ":" in host else host
|
||||
host_without_port = _strip_port(host)
|
||||
|
||||
# Skip platform detection for admin routes - admin is global
|
||||
if FrontendDetector.is_admin(host, path):
|
||||
@@ -359,7 +384,7 @@ class PlatformContextMiddleware:
|
||||
# For storefront API requests on localhost, the path doesn't contain
|
||||
# /platforms/{code}/, so extract platform from the Referer header instead.
|
||||
# e.g., Referer: http://localhost:8000/platforms/loyalty/storefront/FASHIONHUB/...
|
||||
host_without_port = host.split(":")[0] if ":" in host else host
|
||||
host_without_port = _strip_port(host)
|
||||
if (
|
||||
host_without_port in _LOCAL_HOSTS
|
||||
and path.startswith("/api/v1/storefront/")
|
||||
@@ -450,7 +475,7 @@ class PlatformContextMiddleware:
|
||||
- /platforms/oms/pricing → OMS platform pricing
|
||||
- /platforms/loyalty/ → Loyalty platform homepage
|
||||
"""
|
||||
host_without_port = host.split(":")[0] if ":" in host else host
|
||||
host_without_port = _strip_port(host)
|
||||
|
||||
# Method 1: Domain-based (production)
|
||||
if host_without_port and host_without_port not in _LOCAL_HOSTS:
|
||||
|
||||
Reference in New Issue
Block a user