67 lines
1.8 KiB
Rust
67 lines
1.8 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;
|
|
|
|
/// Perform first-time setup using password login
|
|
#[derive(Args, Debug)]
|
|
pub(crate) struct Setup {
|
|
/// The bot's matrix username, e.g. `@mybot:myhomeserver.example`
|
|
username: Box<UserId>,
|
|
/// An optional homeserver base URL. Will attempt to auto-detect if not
|
|
/// specified.
|
|
#[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(())
|
|
}
|