hivectl matrix create-user: --password / --password-stdin for operator accounts (#663)
This commit is contained in:
parent
18253bf2f5
commit
5d1909bb5c
2 changed files with 115 additions and 20 deletions
|
|
@ -169,19 +169,33 @@ async fn register_post(
|
|||
Ok((status, json))
|
||||
}
|
||||
|
||||
/// Run the matrix-spec UIAA flow to register `agent` and return the
|
||||
/// resulting access token. Two round-trips: first POST elicits the
|
||||
/// 401 + session id, second POST supplies the registration token in
|
||||
/// the `auth` block. If the homeserver returns 200 on the first POST
|
||||
/// (no flow stages required — `allow_registration` with no token), we
|
||||
/// take the access token directly.
|
||||
/// Generate a throwaway random password for matrix UIAA registration.
|
||||
/// `PASSWORD_BYTES` raw bytes ⇒ 64-char hex string. Agents authenticate
|
||||
/// by `access_token` so the password is protocol overhead we never
|
||||
/// persist; the operator path in `hivectl` (#663) lets the caller
|
||||
/// supply a real password instead so they can log into a matrix web
|
||||
/// client (`m.login.password`).
|
||||
pub fn random_password() -> Result<String> {
|
||||
random_hex(PASSWORD_BYTES)
|
||||
}
|
||||
|
||||
/// Run the matrix-spec UIAA flow to register `agent` with the given
|
||||
/// `password` and return the resulting access token. Two round-trips:
|
||||
/// first POST elicits the 401 + session id, second POST supplies the
|
||||
/// registration token in the `auth` block. If the homeserver returns
|
||||
/// 200 on the first POST (no flow stages required — `allow_registration`
|
||||
/// with no token), we take the access token directly.
|
||||
///
|
||||
/// Caller picks the password: agents use [`random_password`] (throwaway
|
||||
/// — they auth by `access_token`), operators on the `hivectl` path
|
||||
/// supply their own so they can log into matrix web clients (#663).
|
||||
async fn register_user(
|
||||
client: &reqwest::Client,
|
||||
agent: &str,
|
||||
register_token: &str,
|
||||
password: &str,
|
||||
) -> Result<String> {
|
||||
let localpart = user_localpart(agent);
|
||||
let password = random_hex(PASSWORD_BYTES)?;
|
||||
let initial = serde_json::json!({
|
||||
"username": localpart,
|
||||
"password": password,
|
||||
|
|
@ -252,7 +266,8 @@ pub async fn ensure_user_for(
|
|||
tracing::debug!(%name, "matrix: token already present");
|
||||
return Ok(());
|
||||
}
|
||||
let access_token = register_user(client, name, register_token).await?;
|
||||
let password = random_password()?;
|
||||
let access_token = register_user(client, name, register_token, &password).await?;
|
||||
if let Some(parent) = path.parent() {
|
||||
std::fs::create_dir_all(parent).ok();
|
||||
}
|
||||
|
|
@ -263,18 +278,24 @@ pub async fn ensure_user_for(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Register a matrix account for `name` and return the freshly-minted
|
||||
/// access token. Unlike [`ensure_user_for`], the token is **not**
|
||||
/// persisted to disk — the caller is responsible for storing it. Used
|
||||
/// by `hivectl matrix create-user` for human (non-agent) accounts so
|
||||
/// we don't create stray `/var/lib/hyperhive/agents/<name>/` directories
|
||||
/// for users that aren't agents (#662).
|
||||
/// Register a matrix account for `name` with the supplied `password`
|
||||
/// and return the freshly-minted access token. Unlike [`ensure_user_for`],
|
||||
/// the token is **not** persisted to disk — the caller is responsible
|
||||
/// for storing it. Used by `hivectl matrix create-user` for human
|
||||
/// (non-agent) accounts so we don't create stray
|
||||
/// `/var/lib/hyperhive/agents/<name>/` directories for users that
|
||||
/// aren't agents (#662). For operator accounts the caller passes a
|
||||
/// real password so the operator can `m.login.password` into matrix
|
||||
/// web clients afterwards (#663); for headless agent re-provisioning
|
||||
/// the caller can pass [`random_password`] to keep the existing
|
||||
/// throwaway behaviour.
|
||||
pub async fn provision_user_token(
|
||||
client: &reqwest::Client,
|
||||
name: &str,
|
||||
register_token: &str,
|
||||
password: &str,
|
||||
) -> Result<String> {
|
||||
register_user(client, name, register_token).await
|
||||
register_user(client, name, register_token, password).await
|
||||
}
|
||||
|
||||
/// Per-agent matrix sync: ensure the agent has a matrix account + token.
|
||||
|
|
|
|||
Loading…
Reference in a new issue