feat: M2 — management REST API with OpenAPI doc (control-pane groundwork)
A versioned control-plane REST API (/api/v1) on its own port (default 127.0.0.1:47990) serving host info, runtime status, paired-client management, the pairing PIN flow, and session control (stop / force-IDR). The OpenAPI 3.1 document is generated from the handlers by utoipa, served live at /api/v1/openapi.json (+ Scalar docs at /api/docs), printable via `lumen-host openapi`, and checked in at docs/api/openapi.json for client codegen — a test fails if it drifts, mirroring the cbindgen header rule. Auth: optional bearer token (--mgmt-token / LUMEN_MGMT_TOKEN), enforced on everything but /health, and mandatory for non-loopback binds. PinGate gains a waiter count so the API can report pin_pending; logs moved to stderr so stdout stays machine-readable. Supersedes the web.rs stub. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -42,6 +42,11 @@ impl ServerIdentity {
|
||||
(c, k)
|
||||
}
|
||||
};
|
||||
Self::from_pems(cert_pem, key_pem)
|
||||
}
|
||||
|
||||
/// Build an identity from PEMs (no I/O).
|
||||
pub fn from_pems(cert_pem: String, key_pem: String) -> Result<ServerIdentity> {
|
||||
let priv_key = RsaPrivateKey::from_pkcs8_pem(&key_pem).context("parse host private key")?;
|
||||
let signing_key = SigningKey::<Sha256>::new(priv_key);
|
||||
let signature = cert_signature(&cert_pem)?;
|
||||
@@ -52,6 +57,12 @@ impl ServerIdentity {
|
||||
signing_key,
|
||||
})
|
||||
}
|
||||
|
||||
/// Throwaway in-memory identity — nothing touches the config dir (used by tests).
|
||||
pub fn ephemeral() -> Result<ServerIdentity> {
|
||||
let (cert_pem, key_pem) = generate()?;
|
||||
Self::from_pems(cert_pem, key_pem)
|
||||
}
|
||||
}
|
||||
|
||||
fn generate() -> Result<(String, String)> {
|
||||
|
||||
Reference in New Issue
Block a user