feat(middleware): harden routing with fail-closed policy, custom subdomain management, and perf fixes
Some checks failed
CI / pytest (push) Waiting to run
CI / ruff (push) Successful in 12s
CI / validate (push) Successful in 26s
CI / dependency-scanning (push) Successful in 31s
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled

- 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:
2026-03-15 18:13:01 +01:00
parent 07fab01f6a
commit 540205402f
38 changed files with 1827 additions and 134 deletions

View File

@@ -172,10 +172,51 @@ class TestStorefrontAccessMiddlewarePassthrough:
call_next.assert_called_once_with(request)
@pytest.mark.asyncio
async def test_no_frontend_type_passes_through(self):
"""Test request with no frontend_type set passes through."""
async def test_no_frontend_type_non_storefront_passes_through(self):
"""Test request with no frontend_type on non-storefront path passes through."""
middleware = StorefrontAccessMiddleware(app=None)
request = _make_request()
request = _make_request(path="/admin/dashboard")
request.state.frontend_type = None
call_next = AsyncMock(return_value=Mock())
await middleware.dispatch(request, call_next)
call_next.assert_called_once_with(request)
@pytest.mark.asyncio
async def test_no_frontend_type_storefront_path_blocked(self):
"""Test request with no frontend_type on storefront path is blocked (fail-closed)."""
middleware = StorefrontAccessMiddleware(app=None)
request = _make_request(path="/storefront/products")
request.state.frontend_type = None
request.state.store = None
call_next = AsyncMock()
with patch("app.templates_config.templates") as mock_templates:
mock_templates.TemplateResponse.return_value = Mock(status_code=403)
await middleware.dispatch(request, call_next)
call_next.assert_not_called()
@pytest.mark.asyncio
async def test_no_frontend_type_storefront_api_blocked_json(self):
"""Test request with no frontend_type on storefront API returns JSON 403."""
middleware = StorefrontAccessMiddleware(app=None)
request = _make_request(path="/api/v1/storefront/cart")
request.state.frontend_type = None
call_next = AsyncMock()
response = await middleware.dispatch(request, call_next)
call_next.assert_not_called()
assert isinstance(response, JSONResponse)
assert response.status_code == 403
@pytest.mark.asyncio
async def test_no_frontend_type_static_passes_through(self):
"""Test request with no frontend_type on static path passes through."""
middleware = StorefrontAccessMiddleware(app=None)
request = _make_request(path="/static/css/style.css")
request.state.frontend_type = None
call_next = AsyncMock(return_value=Mock())