91 lines
2.2 KiB
Rust
91 lines
2.2 KiB
Rust
use std::path::{Path, PathBuf};
|
|
|
|
use matrix_sdk::{
|
|
config::ClientConfig,
|
|
reqwest::Url,
|
|
ruma::{DeviceIdBox, UserId},
|
|
Client,
|
|
};
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Session {
|
|
/// The homeserver URL
|
|
pub homeserver: Url,
|
|
/// Access token for authentication
|
|
pub access_token: String,
|
|
/// The user's mxid.
|
|
pub user_id: UserId,
|
|
/// The user's device ID.
|
|
pub device_id: DeviceIdBox,
|
|
}
|
|
|
|
/// Create a matrix client and log it in to the server at the given URL with the
|
|
/// given credentials.
|
|
pub async fn login(url: &str, user: &str, password: &str) -> Result<Client, LoginError> {
|
|
let url: Url =
|
|
if !url.contains("://") { format!("https://{}", url).parse() } else { url.parse() }?;
|
|
let client = Client::new_with_config(url.clone(), config()?)?;
|
|
let response = client.login(user, password, None, None).await?;
|
|
let session = Session {
|
|
homeserver: url,
|
|
access_token: response.access_token,
|
|
user_id: response.user_id,
|
|
device_id: response.device_id,
|
|
};
|
|
Ok(client)
|
|
}
|
|
|
|
/// Errors that can happen when logging in
|
|
#[derive(Debug)]
|
|
pub enum LoginError {
|
|
/// Invalid URL
|
|
Url(url::ParseError),
|
|
/// Matrix SDK error
|
|
Sdk(matrix_sdk::Error),
|
|
/// I/O error
|
|
Io(std::io::Error),
|
|
}
|
|
|
|
impl std::fmt::Display for LoginError {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
match self {
|
|
LoginError::Url(_) => write!(f, "Invalid homeserver address"),
|
|
LoginError::Sdk(e) => write!(f, "{}", e),
|
|
LoginError::Io(e) => write!(f, "Filesystem error: {}", e),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl std::error::Error for LoginError {}
|
|
|
|
impl From<url::ParseError> for LoginError {
|
|
fn from(e: url::ParseError) -> Self {
|
|
LoginError::Url(e)
|
|
}
|
|
}
|
|
|
|
impl From<matrix_sdk::Error> for LoginError {
|
|
fn from(e: matrix_sdk::Error) -> Self {
|
|
LoginError::Sdk(e)
|
|
}
|
|
}
|
|
|
|
impl From<std::io::Error> for LoginError {
|
|
fn from(e: std::io::Error) -> Self {
|
|
LoginError::Io(e)
|
|
}
|
|
}
|
|
|
|
/// Configuration for `Clients`.
|
|
fn config() -> Result<ClientConfig, std::io::Error> {
|
|
Ok(ClientConfig::new().store_path(&path()?))
|
|
}
|
|
|
|
/// The path the the sdk store should be put in.
|
|
fn path() -> Result<PathBuf, std::io::Error> {
|
|
let path = Path::new(&std::env::var_os("HOME").unwrap()).join(".config").join("retrix");
|
|
std::fs::create_dir_all(&path)?;
|
|
Ok(path)
|
|
}
|