swarm-secret-client: carry the homeserver with the credential, not on the notice
A delivered matrix account needs two things: the token and the homeserver it
belongs to. Only the token was stored, so the homeserver had to ride on the
queue notice — and a notice is not persistence. Re-delivering a credential
(agent moved, hive re-provisioned, token rotated) has to reconstruct it from
somewhere, and there is nowhere; keeping it separately at swarm level would be
a second store for one logical object, free to drift from the first.
So `Credential` grows a `homeserver` field and `read`/`write` carry the whole
object rather than a bare string.
`value` keeps its name. `nix/host-modules/glue-matrix-bao-token.nix` reads the
store with `bao kv get -field=value` and is the only nix reader of it, checked
rather than assumed — so this had to be an addition, never a rename.
Two compatibility properties, both of which fail silently if broken:
KV2 keeps every prior version, so objects written before this field existed
are still decoded by this type. What tolerates their absence is the field
being `Option` — a bare `String` would not fail as a migration, every stored
credential would become unreadable at once. The new test pins that, with a
presence control so the arm is about absence being tolerated rather than the
field being ignored.
`skip_serializing_if` keeps a token-only credential serialising to exactly the
bytes the previous version wrote, with no `homeserver` key rather than a null,
which is what that nix reader would otherwise trip over. The existing test
pinning `{"value":"t"}` proves it and became the control for free.
Mutation testing earned its place here: `#[serde(default)]` was in the first
draft and its comment claimed it was what made old objects decode. Dropping it
changed nothing — serde already decodes a missing field to `None` for an
optional type — so the attribute was redundant and the comment was wrong about
its own mechanism. Both removed rather than left to mislead the next reader.
The delivery half needed no change: `write_agent_matrix_token` already took a
homeserver and already wrote the `matrix-account-<name>.json` sidecar beside
the token. `deliver` simply stops passing `None`. A credential stored without
one still works exactly as before — no sidecar, and the account needs a
configured entry.
Refs #3726
This commit is contained in:
parent
7396903994
commit
d1c0963fbd
2 changed files with 64 additions and 15 deletions
|
|
@ -42,7 +42,7 @@ pub async fn deliver(notice: &CredentialNotice, cert_role: &str) -> Result<()> {
|
|||
let store = SecretStore::from_env(cert_role)
|
||||
.await
|
||||
.context("connecting to the swarm secret store")?;
|
||||
let value = store
|
||||
let credential = store
|
||||
.read(&secret_path)
|
||||
.await
|
||||
.with_context(|| format!("reading {secret_path} from the store"))?;
|
||||
|
|
@ -52,11 +52,18 @@ pub async fn deliver(notice: &CredentialNotice, cert_role: &str) -> Result<()> {
|
|||
// arrives owned by `hive-core` at 0600 — the daemon wakes on it appearing
|
||||
// and cannot read it. hive-priv also builds the filename, so the name the
|
||||
// watcher globs for is decided in one place now.
|
||||
//
|
||||
// A homeserver is passed through when the stored credential carries one;
|
||||
// hive-priv then writes the `matrix-account-<name>.json` sidecar beside the
|
||||
// token, which is how the daemon discovers an extra account's homeserver
|
||||
// without a static `matrixAccounts` entry. Credentials written before that
|
||||
// field existed carry `None`, and the sidecar is simply not written — the
|
||||
// account then needs a configured entry, exactly as it did before.
|
||||
crate::priv_client::write_agent_matrix_token(
|
||||
agent.as_str(),
|
||||
&value,
|
||||
&credential.value,
|
||||
Some(¬ice.account),
|
||||
None,
|
||||
credential.homeserver.as_deref(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue