retrix/src/matrix.rs

97 lines
2.6 KiB
Rust
Raw Normal View History

2020-11-24 16:11:27 +01:00
use matrix_sdk::{
2020-11-24 21:49:06 +01:00
identifiers::DeviceId, identifiers::UserId, reqwest::Url, Client, ClientConfig, SyncSettings,
2020-11-24 16:11:27 +01:00
};
use serde::{Deserialize, Serialize};
2020-11-23 17:18:05 +01:00
2020-11-24 16:11:27 +01:00
pub type Error = anyhow::Error;
// Needed to be able to serialize `Session`s. Should be done with serde remote.
#[derive(Debug, Clone, Deserialize, Serialize)]
2020-11-24 21:49:06 +01:00
pub struct Session {
2020-11-24 16:11:27 +01:00
access_token: String,
user_id: UserId,
device_id: Box<DeviceId>,
2020-11-24 21:49:06 +01:00
homeserver: String,
2020-11-24 16:11:27 +01:00
}
2020-11-24 21:49:06 +01:00
impl From<Session> for matrix_sdk::Session {
2020-11-24 16:11:27 +01:00
fn from(s: Session) -> Self {
Self {
access_token: s.access_token,
user_id: s.user_id,
device_id: s.device_id,
}
}
}
2020-11-24 09:12:24 +01:00
2020-11-24 21:49:06 +01:00
/// Login with credentials, creating a new authentication session
2020-11-24 09:12:24 +01:00
pub async fn login(
2020-11-23 17:18:05 +01:00
username: &str,
password: &str,
server: &str,
2020-11-24 09:12:24 +01:00
) -> Result<(Client, Session), Error> {
2020-11-23 17:18:05 +01:00
let url = Url::parse(server)?;
2020-11-24 21:49:06 +01:00
let client = client(url)?;
2020-11-24 16:11:27 +01:00
2020-11-24 21:49:06 +01:00
let response = client
.login(
username,
password,
None,
Some(&format!("retrix@{}", hostname::get()?.to_string_lossy())),
)
.await?;
let session = Session {
access_token: response.access_token,
user_id: response.user_id,
device_id: response.device_id,
homeserver: server.to_owned(),
2020-11-24 09:12:24 +01:00
};
2020-11-24 21:49:06 +01:00
write_session(&session)?;
2020-11-24 16:11:27 +01:00
client.sync_once(SyncSettings::new()).await?;
2020-11-23 17:18:05 +01:00
2020-11-24 09:12:24 +01:00
Ok((client, session))
2020-11-23 17:18:05 +01:00
}
2020-11-24 16:11:27 +01:00
2020-11-24 21:49:06 +01:00
pub async fn restore_login(session: Session) -> Result<(Client, Session), Error> {
let url = Url::parse(&session.homeserver)?;
let client = client(url)?;
client.restore_login(session.clone().into()).await?;
client.sync_once(SyncSettings::new()).await?;
Ok((client, session))
}
/// Create a matrix client handler with the desired configuration
fn client(url: Url) -> Result<Client, matrix_sdk::Error> {
let config = ClientConfig::new().store_path(&dirs::config_dir().unwrap().join("retrix"));
Client::new_with_config(url, config)
}
2020-11-24 16:11:27 +01:00
/// File path to store session data in
fn session_path() -> std::path::PathBuf {
dirs::config_dir()
.unwrap()
.join("retrix")
.join("session.toml")
}
/// Read session data from config file
2020-11-24 21:49:06 +01:00
pub fn get_session() -> Result<Option<Session>, Error> {
2020-11-24 16:11:27 +01:00
let path = session_path();
if !path.is_file() {
return Ok(None);
}
2020-11-24 21:49:06 +01:00
let session: Session = toml::from_slice(&std::fs::read(path)?)?;
Ok(Some(session))
2020-11-24 16:11:27 +01:00
}
/// Save session data to config file
2020-11-24 21:49:06 +01:00
fn write_session(session: &Session) -> Result<(), Error> {
2020-11-24 16:11:27 +01:00
let serialized = toml::to_string(&session)?;
2020-11-24 21:49:06 +01:00
std::fs::write(session_path(), serialized)?;
2020-11-24 16:11:27 +01:00
Ok(())
}