proto(woo): blocking setup gate; require X-Woo-* on Woo HTTP routes

Full-screen WooSetupGate on App mount when this browser lacks device WP
user + app password. Save + Test Woo dismisses only after a successful
test. Publish/test-woo auth failures reopen the gate.

Server: client_for_request requires X-Woo-* on publish, taxonomy sync,
and test-woo (401 woo_device_creds_required); health probe keeps
Settings. Optional SLAB_WOO_ALLOW_SETTINGS_FALLBACK for legacy tests.

See PROTOTYPE.md.
This commit is contained in:
grokbot_ty
2026-09-26 19:20:16 -07:00
parent 2f6335ec26
commit 2f9b8ebd02
16 changed files with 600 additions and 58 deletions
+16 -1
View File
@@ -21,6 +21,7 @@ from .woo import (
WooClient,
WooConnectionError,
WooCredentialsMissing,
WooDeviceCredsRequired,
WooError,
WooForbiddenError,
client_for_request,
@@ -124,6 +125,12 @@ def _attr_id_from_synced(attrs: dict, slug: str, name: str) -> int | None:
def _classify(e: Exception) -> tuple[str, str, bool]:
"""Return (code, plain message, recoverable). PUBLISH-36/37/38."""
if isinstance(e, WooDeviceCredsRequired):
return (
"woo_device_creds_required",
"Enter this device's WordPress user and application password.",
False,
)
if isinstance(e, WooCredentialsMissing):
return "woo_unconfigured", "Woo is not configured. Set the store credentials in Settings.", False
if isinstance(e, WooAuthError):
@@ -152,9 +159,17 @@ async def publish(slab_id: str, request: Request) -> dict:
if not ready:
return JSONResponse(status_code=422, content=_error("unpublishable", "Slab is not ready", {"missing": missing}))
# 2. SKU lookup (PUBLISH-15) — stop if it exists in the store.
# Per-request Woo creds: X-Woo-* headers → Settings fallback (never persisted).
# Per-request Woo creds: require X-Woo-* device headers (no Settings fallback).
try:
client = client_for_request(conn, request.headers)
except WooDeviceCredsRequired as e:
return JSONResponse(
status_code=401,
content=_error(
"woo_device_creds_required",
"Enter this device's WordPress user and application password.",
),
)
except WooCredentialsMissing as e:
return JSONResponse(status_code=422, content=_error("woo_unconfigured", str(e)))
try: