feature (accounts): implemented an account manager
This commit is contained in:
parent
30e1f4cd6b
commit
a3cb8b8e20
|
@ -1,5 +1,5 @@
|
|||
target/
|
||||
data/
|
||||
userdata/
|
||||
|
||||
# IDE stuff
|
||||
.idea
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
use std::fs;
|
||||
use std::path::Path;
|
||||
use matrix_sdk::{Client,
|
||||
config::SyncSettings,
|
||||
ruma::{user_id,
|
||||
events::room::message::SyncRoomMessageEvent,
|
||||
exports::serde_json},
|
||||
Session};
|
||||
use anyhow::{Error, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::app;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Account {
|
||||
homeserver: String,
|
||||
id: u32,
|
||||
|
||||
session: Session,
|
||||
sync_token: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct AccountManager {
|
||||
selected_account_index: u32,
|
||||
accounts: Vec<Account>,
|
||||
}
|
||||
|
||||
impl AccountManager {
|
||||
pub fn new() -> Self {
|
||||
let json_file: &Path = Path::new("userdata/accounts.json");
|
||||
return if json_file.exists() {
|
||||
let serialized = fs::read_to_string(json_file).expect("ailed to read json");
|
||||
serde_json::from_str(&serialized).expect("failed to deserialize json")
|
||||
} else {
|
||||
Self {
|
||||
selected_account_index: 0,
|
||||
accounts: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn add(&mut self, homeserver: &str, username: &str, password: &str) -> Result<Client> {
|
||||
let client = Client::builder()
|
||||
.homeserver_url(homeserver)
|
||||
.sled_store("userdata/data", Some("supersecure"))?
|
||||
.build()
|
||||
.await?;
|
||||
|
||||
client
|
||||
.login_username(username, password)
|
||||
.initial_device_display_name("Trinitrix")
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
let session = client.session().expect("failed to get session");
|
||||
|
||||
println!("logged in as {username} device ID: {}", session.device_id.as_str());
|
||||
|
||||
|
||||
let account = Account {
|
||||
homeserver: homeserver.to_string(),
|
||||
id: self.accounts.len() as u32,
|
||||
session,
|
||||
sync_token: None
|
||||
};
|
||||
|
||||
self.logout(&client).await?;
|
||||
self.selected_account_index = account.id;
|
||||
self.accounts.push(account);
|
||||
|
||||
self.save()?;
|
||||
|
||||
Ok(client)
|
||||
}
|
||||
|
||||
pub async fn login(&mut self, account_id:u32) -> Result<Client> {
|
||||
let account = match self.get(account_id) {
|
||||
None => return Err(Error::msg("Invalid account ID")),
|
||||
Some(a) => a,
|
||||
};
|
||||
|
||||
let client = Client::builder()
|
||||
.homeserver_url(&account.homeserver)
|
||||
.sled_store("userdata/data", Some("supersecure"))?
|
||||
.build()
|
||||
.await?;
|
||||
|
||||
client.restore_login(account.session.clone()).await?;
|
||||
|
||||
println!("restored account: {} device ID: {}", &account.session.user_id, &account.session.device_id);
|
||||
|
||||
self.logout(&client).await?;
|
||||
self.selected_account_index = account_id;
|
||||
|
||||
Ok(client)
|
||||
}
|
||||
|
||||
pub async fn logout(&mut self, client: &Client) -> Result<()> {
|
||||
// idk, do some matrix related stuff in here or something like that
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get(&self, id: u32) -> Option<&Account> {
|
||||
return self.accounts.get(id as usize);
|
||||
}
|
||||
|
||||
pub fn current(&self) -> Option<&Account> {
|
||||
return self.accounts.get(self.selected_account_index as usize);
|
||||
}
|
||||
|
||||
pub fn save(&self) -> Result<()>{
|
||||
let serialized = serde_json::to_string(self as &AccountManager)?;
|
||||
fs::write("userdata/accounts.json", serialized)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
use matrix_sdk::{Client, config::SyncSettings, ruma::{user_id, events::room::message::SyncRoomMessageEvent}, Session};
|
||||
use anyhow::{Error, Result};
|
||||
use matrix_sdk::ruma::exports::serde_json;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Account {
|
||||
homeserver: String,
|
||||
|
||||
session: Session,
|
||||
sync_token: Option<String>,
|
||||
}
|
||||
|
||||
pub async fn account_add(homeserver:&str, username:&str, password:&str) -> anyhow::Result<Account> {
|
||||
let client = Client::builder()
|
||||
.homeserver_url(homeserver)
|
||||
.sled_store("data", Some("supersecure"))?
|
||||
.build()
|
||||
.await?;
|
||||
|
||||
client
|
||||
.login_username(username, password)
|
||||
.initial_device_display_name("Trinitrix")
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
let session = match client.session() {
|
||||
None => return Err(Error::msg("session is None")),
|
||||
Some(s) => s,
|
||||
};
|
||||
|
||||
println!("logged in as {username} device ID: {}", session.device_id.as_str());
|
||||
|
||||
let account = Account {
|
||||
homeserver: homeserver.to_string(),
|
||||
session,
|
||||
sync_token: None
|
||||
};
|
||||
|
||||
let serialized_account = serde_json::to_string(&account)?;
|
||||
println!("serialized account: {}", serialized_account);
|
||||
// TODO: save serialized account info in userdata dir
|
||||
|
||||
Ok(account)
|
||||
}
|
||||
|
||||
pub async fn account_login(account: Account) -> anyhow::Result<()> {
|
||||
let client = Client::builder()
|
||||
.homeserver_url(account.homeserver)
|
||||
.sled_store("data", Some("supersecure"))?
|
||||
.build()
|
||||
.await?;
|
||||
|
||||
client.restore_login(account.session.clone()).await?;
|
||||
|
||||
println!("restored account: {} device ID: {}", &account.session.user_id, &account.session.device_id);
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
use crate::accounts;
|
||||
|
||||
use matrix_sdk::{Client};
|
||||
use accounts::Account;
|
||||
use crate::accounts::AccountManager;
|
||||
|
||||
pub struct App {
|
||||
pub account_manager: accounts::AccountManager,
|
||||
pub client: Option<Client>,
|
||||
}
|
||||
|
||||
impl App {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
account_manager: AccountManager::new(),
|
||||
client: None
|
||||
}
|
||||
}
|
||||
}
|
10
src/main.rs
10
src/main.rs
|
@ -1,5 +1,6 @@
|
|||
mod ui;
|
||||
mod accounts;
|
||||
mod app;
|
||||
|
||||
use matrix_sdk::ruma::exports::serde_json;
|
||||
use tokio::time::{sleep, Duration};
|
||||
|
@ -8,12 +9,13 @@ use tokio::time::{sleep, Duration};
|
|||
async fn main() -> anyhow::Result<()> {
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
// accounts::account_add("https://nerdcult.net", "test", "abcd1234").await?;
|
||||
let mut app = app::App::new();
|
||||
|
||||
let serialized_account = "{\"homeserver\":\"https://nerdcult.net\",\"session\":{\"access_token\":\"U2XH1vfu3dJTTPV7BIeZh2yGiMN49vBF\",\"user_id\":\"@test:nerdcult.net\",\"device_id\":\"UsdqFbcEC3\"},\"sync_token\":null}";
|
||||
let account: accounts::Account = serde_json::from_str(serialized_account)?;
|
||||
let client = app.account_manager.add("https://nerdcult.net", "test", "abcd1234").await?;
|
||||
app.client = Some(client);
|
||||
|
||||
accounts::account_login(account).await?;
|
||||
// let client = app.account_manager.login(0).await?;
|
||||
// app.client = Some(client);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Reference in New Issue