Something went wrong. Try again.
Monorepo for Tangled tangled.org
Something went wrong. Try again.
3.0 kB · 93 lines
Rust
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394use anyhow::Context;use clap::Subcommand;use knot_xrpc::legacy_admin;use serde_json::json;
#[derive(Subcommand)]pub enum AdminCommand { /// Mint an invite code CreateInviteCode, /// Manage knot members Member { #[command(subcommand)] command: MemberCommand, }, /// Manage anonymous users on the knot User { #[command(subcommand)] command: UserCommand, },}
#[derive(Subcommand)]pub enum MemberCommand { /// Add an account as a member. Add { subject: String }, /// Remove a member. Remove { subject: String },}
#[derive(Subcommand)]pub enum UserCommand { /// Ban an account. Ban { subject: String }, /// Unban an account. Unban { subject: String },}
pub async fn run(config: &knot_config::Validated, command: AdminCommand) -> anyhow::Result<()> { let (route, body) = match command { AdminCommand::CreateInviteCode => (legacy_admin::CREATE_INVITE_CODE_ROUTE, None), AdminCommand::Member { command } => { let (route, subject) = match command { MemberCommand::Add { subject } => (legacy_admin::TEMP_ADD_MEMBER_ROUTE, subject), MemberCommand::Remove { subject } => (legacy_admin::REMOVE_MEMBER_ROUTE, subject), }; (route, Some(json!({ "subject": subject }))) } AdminCommand::User { command } => { let (route, subject) = match command { UserCommand::Ban { subject } => (legacy_admin::BAN_USER_ROUTE, subject), UserCommand::Unban { subject } => (legacy_admin::UNBAN_USER_ROUTE, subject), }; (route, Some(json!({ "subject": subject }))) } }; let response = post(config, route, body).await?; println!("{}", serde_json::to_string_pretty(&response)?); Ok(())}
async fn post( config: &knot_config::Validated, route: &str, body: Option<serde_json::Value>,) -> anyhow::Result<serde_json::Value> { let name = config .acl .legacy_admin_secret_env .as_deref() .context("acl.legacy_admin_secret_env isn't configured")?; let secret = zeroize::Zeroizing::new(std::env::var(name).unwrap_or_default()); let secret = secret.trim(); anyhow::ensure!( !secret.is_empty(), "the environment variable {name} is unset or empty" ); let url = format!("https://{}{route}", config.server.hostname); let request = reqwest::Client::new() .post(&url) .basic_auth("admin", Some(secret)); let request = match body { Some(body) => request.json(&body), None => request, }; let response = request .send() .await .with_context(|| format!("request {url}"))?; let status = response.status(); let body = response.text().await.context("read response body")?; anyhow::ensure!(status.is_success(), "{url} responded {status}: {body}"); serde_json::from_str(&body).context("decode response")}