fix: drop --server flag from hivectl matrix; discover server_name from homeserver
Add matrix::discover_server_name() via GET /_matrix/key/v2/server (unauthenticated federation endpoint, always returns server_name). hivectl is always talking to the local hive — no reason to require the operator to spell out the server_name.
This commit is contained in:
parent
8757dc615d
commit
c4a8b90236
2 changed files with 42 additions and 35 deletions
|
|
@ -158,16 +158,11 @@ enum MatrixCmd {
|
|||
SyncAdmin,
|
||||
/// Promote a matrix user to homeserver admin via the admin API.
|
||||
/// Uses the hive system admin token at
|
||||
/// `/var/lib/hyperhive/matrix-admin-token`. Requires `--server` to
|
||||
/// be the matrix `server_name` (e.g. `pr1ma.darkest.space`).
|
||||
/// `/var/lib/hyperhive/matrix-admin-token`. The server_name is
|
||||
/// discovered automatically from the running homeserver.
|
||||
PromoteUser {
|
||||
/// Matrix localpart of the user to promote (e.g. `argus`).
|
||||
name: String,
|
||||
/// Matrix server_name embedded in user IDs (`@user:<server>`).
|
||||
/// Falls back to the `HYPERHIVE_MATRIX_SERVER_NAME` env var
|
||||
/// when omitted.
|
||||
#[arg(long)]
|
||||
server: Option<String>,
|
||||
},
|
||||
/// Reset a matrix user's password via the admin API and persist the
|
||||
/// new password to `/var/lib/hyperhive/matrix-creds/<name>-password`
|
||||
|
|
@ -178,10 +173,6 @@ enum MatrixCmd {
|
|||
ResetPassword {
|
||||
/// Matrix localpart of the account to reset (e.g. `argus`).
|
||||
name: String,
|
||||
/// Matrix server_name embedded in user IDs. Falls back to the
|
||||
/// `HYPERHIVE_MATRIX_SERVER_NAME` env var when omitted.
|
||||
#[arg(long)]
|
||||
server: Option<String>,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -284,14 +275,8 @@ async fn main() -> Result<()> {
|
|||
password_stdin,
|
||||
} => matrix_create_user(&name, password.as_deref(), password_stdin).await,
|
||||
MatrixCmd::SyncAdmin => matrix_sync_admin().await,
|
||||
MatrixCmd::PromoteUser { name, server } => {
|
||||
let server_name = resolve_server_name(server.as_deref())?;
|
||||
matrix_promote_user(&name, &server_name).await
|
||||
}
|
||||
MatrixCmd::ResetPassword { name, server } => {
|
||||
let server_name = resolve_server_name(server.as_deref())?;
|
||||
matrix_reset_password(&name, &server_name).await
|
||||
}
|
||||
MatrixCmd::PromoteUser { name } => matrix_promote_user(&name).await,
|
||||
MatrixCmd::ResetPassword { name } => matrix_reset_password(&name).await,
|
||||
},
|
||||
Cmd::Gateway { cmd } => match cmd {
|
||||
GatewayCmd::CreateUser {
|
||||
|
|
@ -441,18 +426,6 @@ async fn matrix_create_user(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Resolve matrix server_name from flag or env var.
|
||||
fn resolve_server_name(flag: Option<&str>) -> Result<String> {
|
||||
if let Some(s) = flag {
|
||||
return Ok(s.to_owned());
|
||||
}
|
||||
std::env::var("HYPERHIVE_MATRIX_SERVER_NAME")
|
||||
.map_err(|_| anyhow::anyhow!(
|
||||
"matrix server_name required — pass --server <name> or \
|
||||
set HYPERHIVE_MATRIX_SERVER_NAME"
|
||||
))
|
||||
}
|
||||
|
||||
async fn matrix_sync_admin() -> Result<()> {
|
||||
if !hive_c0re::matrix::is_present().await {
|
||||
bail!(
|
||||
|
|
@ -477,7 +450,7 @@ async fn matrix_sync_admin() -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
async fn matrix_promote_user(name: &str, server_name: &str) -> Result<()> {
|
||||
async fn matrix_promote_user(name: &str) -> Result<()> {
|
||||
if !hive_c0re::matrix::is_present().await {
|
||||
bail!(
|
||||
"hive-matrix container not running — start it (services.hyperhive.matrix.enable = true) first"
|
||||
|
|
@ -488,14 +461,17 @@ async fn matrix_promote_user(name: &str, server_name: &str) -> Result<()> {
|
|||
.timeout(std::time::Duration::from_secs(30))
|
||||
.build()
|
||||
.context("build reqwest client")?;
|
||||
hive_c0re::matrix::promote_user_to_admin(&client, &admin_token, name, server_name)
|
||||
let server_name = hive_c0re::matrix::discover_server_name(&client)
|
||||
.await
|
||||
.context("discover matrix server_name")?;
|
||||
hive_c0re::matrix::promote_user_to_admin(&client, &admin_token, name, &server_name)
|
||||
.await
|
||||
.with_context(|| format!("matrix promote-user {name}"))?;
|
||||
println!("matrix: promoted @{name}:{server_name} to admin");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn matrix_reset_password(name: &str, server_name: &str) -> Result<()> {
|
||||
async fn matrix_reset_password(name: &str) -> Result<()> {
|
||||
if !hive_c0re::matrix::is_present().await {
|
||||
bail!(
|
||||
"hive-matrix container not running — start it (services.hyperhive.matrix.enable = true) first"
|
||||
|
|
@ -508,11 +484,14 @@ async fn matrix_reset_password(name: &str, server_name: &str) -> Result<()> {
|
|||
.timeout(std::time::Duration::from_secs(30))
|
||||
.build()
|
||||
.context("build reqwest client")?;
|
||||
let server_name = hive_c0re::matrix::discover_server_name(&client)
|
||||
.await
|
||||
.context("discover matrix server_name")?;
|
||||
hive_c0re::matrix::reset_user_password(
|
||||
&client,
|
||||
&admin_token,
|
||||
name,
|
||||
server_name,
|
||||
&server_name,
|
||||
&new_password,
|
||||
)
|
||||
.await
|
||||
|
|
|
|||
|
|
@ -598,6 +598,34 @@ pub async fn reset_user_password(
|
|||
)
|
||||
}
|
||||
|
||||
/// Discover the matrix `server_name` from the running homeserver via
|
||||
/// `GET /_matrix/key/v2/server` (unauthenticated federation key endpoint).
|
||||
/// The response JSON always includes `"server_name"` per the matrix spec.
|
||||
pub async fn discover_server_name(client: &reqwest::Client) -> Result<String> {
|
||||
let url = format!("{MATRIX_HTTP}/_matrix/key/v2/server");
|
||||
let resp = client
|
||||
.get(&url)
|
||||
.send()
|
||||
.await
|
||||
.context("matrix: GET /_matrix/key/v2/server")?;
|
||||
let status = resp.status();
|
||||
let body = resp
|
||||
.json::<serde_json::Value>()
|
||||
.await
|
||||
.context("matrix: parse /_matrix/key/v2/server response")?;
|
||||
if !status.is_success() {
|
||||
anyhow::bail!(
|
||||
"matrix: /_matrix/key/v2/server returned HTTP {status}, body: {body}"
|
||||
);
|
||||
}
|
||||
body["server_name"]
|
||||
.as_str()
|
||||
.map(str::to_owned)
|
||||
.with_context(|| {
|
||||
format!("matrix: /_matrix/key/v2/server response missing server_name field: {body}")
|
||||
})
|
||||
}
|
||||
|
||||
/// Read the hive admin access token from disk. Returns an error if it
|
||||
/// is absent — callers should gate their admin-API calls on this.
|
||||
pub fn read_admin_token() -> Result<String> {
|
||||
|
|
|
|||
Loading…
Reference in a new issue