Surface redacted directory bind failures before native onboarding
All checks were successful
All checks were successful
Map uncaught HTTPError from LLDAP login to a structured dependency_unavailable response, add /readyz as the provisioner-to-directory preflight, keep /healthz as process liveness, and run the contract in CI. Auth rejection is not retried during cooldown. NK-WP-0036-T05 remains in progress until the immutable image is published, pinned with /readyz, and one native login/create/password-setup journey is verified. Assistant: grok Assistant-Session: 01a09dc6-3f0e-78f1-a884-c8c703c24ddf
This commit is contained in:
parent
d90e3b27f2
commit
c8e07615c3
9 changed files with 554 additions and 33 deletions
|
|
@ -6,7 +6,7 @@ import os
|
|||
from urllib.parse import parse_qs, urlsplit
|
||||
import secrets
|
||||
|
||||
from provisioner import LLDAPProvisioner, _directory_username, dispatch
|
||||
from provisioner import DependencyFailure, LLDAPProvisioner, _directory_username, dispatch
|
||||
from password_setup import LLDAPPasswordSetter, PasswordSetupGrants
|
||||
|
||||
|
||||
|
|
@ -19,6 +19,17 @@ class Handler(BaseHTTPRequestHandler):
|
|||
path = urlsplit(self.path)
|
||||
if path.path == "/healthz":
|
||||
return self._send(200, {"status": "ok"})
|
||||
if path.path == "/readyz":
|
||||
try:
|
||||
return self._send(200, self.provisioner.preflight())
|
||||
except DependencyFailure as exc:
|
||||
return self._send(503, exc.payload())
|
||||
except RuntimeError:
|
||||
return self._send(503, {
|
||||
"error": "dependency_unavailable",
|
||||
"dependency": "directory",
|
||||
"reason": "unreachable",
|
||||
})
|
||||
if path.path == "/setup/password":
|
||||
token = parse_qs(path.query).get("token", [""])[0]
|
||||
if not self.password_setups.valid(token):
|
||||
|
|
@ -41,6 +52,8 @@ class Handler(BaseHTTPRequestHandler):
|
|||
return self._send(404, {"error": "not_found"})
|
||||
except (ValueError, json.JSONDecodeError) as exc:
|
||||
return self._send(400, {"error": "invalid_request", "message": str(exc)})
|
||||
except DependencyFailure as exc:
|
||||
return self._send(503, exc.payload())
|
||||
except RuntimeError:
|
||||
return self._send(503, {"error": "dependency_unavailable"})
|
||||
response = asdict(result)
|
||||
|
|
@ -64,7 +77,7 @@ class Handler(BaseHTTPRequestHandler):
|
|||
return_to = self.password_setups.consume(token, password)
|
||||
except ValueError as exc:
|
||||
return self._html(400, _setup_page(token, str(exc)))
|
||||
except RuntimeError:
|
||||
except (DependencyFailure, RuntimeError):
|
||||
return self._html(503, _failed_page())
|
||||
return self._html(200, _complete_page(return_to))
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue