Can set Matrix access token
This commit is contained in:
126
src/user.rs
126
src/user.rs
@ -1,9 +1,135 @@
|
||||
use crate::app_config::AppConfig;
|
||||
use crate::utils::curr_time;
|
||||
use s3::error::S3Error;
|
||||
use s3::request::ResponseData;
|
||||
use s3::{Bucket, BucketConfiguration};
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum UserError {
|
||||
#[error("failed to fetch user configuration: {0}")]
|
||||
FetchUserConfig(S3Error),
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||
pub struct UserID(pub String);
|
||||
|
||||
impl UserID {
|
||||
fn conf_path_in_bucket(&self) -> String {
|
||||
format!("confs/{}.json", urlencoding::encode(&self.0))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||
pub struct User {
|
||||
pub id: UserID,
|
||||
pub name: String,
|
||||
pub email: String,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
pub struct UserConfig {
|
||||
/// Target user ID
|
||||
pub user_id: UserID,
|
||||
|
||||
/// Configuration creation time
|
||||
pub created: u64,
|
||||
|
||||
/// Configuration last update time
|
||||
pub updated: u64,
|
||||
|
||||
/// Current user matrix token
|
||||
pub matrix_token: String,
|
||||
}
|
||||
|
||||
impl UserConfig {
|
||||
/// Create S3 bucket if required
|
||||
pub async fn create_bucket_if_required() -> anyhow::Result<()> {
|
||||
if AppConfig::get().s3_skip_auto_create_bucket {
|
||||
log::debug!("Skipping bucket existence check");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let bucket = AppConfig::get().s3_bucket()?;
|
||||
|
||||
match bucket.location().await {
|
||||
Ok(_) => {
|
||||
log::debug!("The bucket already exists.");
|
||||
return Ok(());
|
||||
}
|
||||
Err(S3Error::HttpFailWithBody(404, s)) if s.contains("<Code>NoSuchKey</Code>") => {
|
||||
log::warn!("Failed to fetch bucket location, but it seems that bucket exists.");
|
||||
return Ok(());
|
||||
}
|
||||
Err(S3Error::HttpFailWithBody(404, s)) if s.contains("<Code>NoSuchBucket</Code>") => {
|
||||
log::warn!("The bucket does not seem to exists, trying to create it!")
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Got unexpected error when querying bucket info: {}", e);
|
||||
return Err(e.into());
|
||||
}
|
||||
}
|
||||
|
||||
Bucket::create_with_path_style(
|
||||
&bucket.name,
|
||||
bucket.region,
|
||||
AppConfig::get().s3_credentials()?,
|
||||
BucketConfiguration::private(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get current user configuration
|
||||
pub async fn load(user_id: &UserID) -> anyhow::Result<Self> {
|
||||
let res: Result<ResponseData, S3Error> = AppConfig::get()
|
||||
.s3_bucket()?
|
||||
.get_object(user_id.conf_path_in_bucket())
|
||||
.await;
|
||||
|
||||
match res {
|
||||
Ok(res) => Ok(serde_json::from_slice(res.as_slice())?),
|
||||
Err(S3Error::HttpFailWithBody(404, _)) => {
|
||||
log::warn!("User configuration does not exists, generating a new one...");
|
||||
Ok(Self {
|
||||
user_id: user_id.clone(),
|
||||
created: curr_time()?,
|
||||
updated: curr_time()?,
|
||||
matrix_token: "".to_string(),
|
||||
})
|
||||
}
|
||||
Err(e) => Err(UserError::FetchUserConfig(e).into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Set user configuration
|
||||
pub async fn save(&mut self) -> anyhow::Result<()> {
|
||||
log::info!("Saving new configuration for user {:?}", self.user_id);
|
||||
|
||||
self.updated = curr_time()?;
|
||||
|
||||
// Save updated configuration
|
||||
AppConfig::get()
|
||||
.s3_bucket()?
|
||||
.put_object(
|
||||
self.user_id.conf_path_in_bucket(),
|
||||
&serde_json::to_vec(self)?,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get current user matrix token, in an obfuscated form
|
||||
pub fn obfuscated_matrix_token(&self) -> String {
|
||||
self.matrix_token
|
||||
.chars()
|
||||
.enumerate()
|
||||
.map(|(num, c)| match num {
|
||||
0 | 1 => c,
|
||||
_ => 'X',
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user