its-matrix-bot/src/setup.rs

63 lines
1.6 KiB
Rust

use std::io::Write;
use clap::Args;
use color_eyre::{eyre::eyre, Result};
use matrix_sdk::{config::SyncSettings, ruma::UserId, Client, Session};
use tokio::io::AsyncBufReadExt;
use crate::SessionData;
#[derive(Args, Debug)]
pub(crate) struct Setup {
username: Box<UserId>,
#[arg(long, short = 's')]
homeserver_url: Option<String>,
}
async fn login_password_interactive(setup: &Setup, client: &Client) -> Result<Session> {
print!("Enter password for {}: ", setup.username);
std::io::stdout().flush()?;
let stdin = tokio::io::BufReader::new(tokio::io::stdin());
let password = stdin
.lines()
.next_line()
.await?
.ok_or(eyre!("Password is required on first start"))?;
let session = client
.login_username(&setup.username, &password)
.initial_device_display_name("gavel bot")
.send()
.await?
.into();
Ok(session)
}
pub(crate) async fn setup(setup: Setup) -> Result<()> {
let client = {
let mut builder = Client::builder().sled_store(crate::sled_store_path()?, None)?;
if let Some(ref url) = setup.homeserver_url {
builder = builder.homeserver_url(url);
} else {
builder = builder.server_name(setup.username.server_name());
}
builder.build().await?
};
let session = login_password_interactive(&setup, &client).await?;
let data = SessionData {
session,
homeserver_url: setup.homeserver_url,
};
tokio::fs::write(crate::session_path()?, toml::to_vec(&data)?).await?;
client.sync_once(SyncSettings::default()).await?;
Ok(())
}