docserver/src/users/NO/user_id.rs

263 lines
9.9 KiB
Rust
Raw Normal View History

2023-07-19 04:00:41 +01:00
use std::{
io::Write,
// sync::Arc,
fmt::Debug,
fs,
path::{Path, PathBuf},
io::{Error, ErrorKind},
};
use log::error;
// use async_session::{MemoryStore, Session, SessionStore};
use serde::{Deserialize, Serialize};
//use tiitls_utils::logs::file;
use uuid::Uuid;
use crate::defs::{
FILE_SCHEME,
SID_SETTINGS_FILE,
SID_REQUESTS_FILE,
SID_TRACE_FILE,
// SID_UI_FILE,
// UI_SETTINGS_FILE,
// SidSettings,
Config as SessionsConfig,
TraceData,
UserAction,
};
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
pub struct UserId(Uuid);
impl UserId {
#[allow(dead_code)]
pub fn new() -> Self {
Self(Uuid::new_v4())
}
pub fn from(data: &str) -> Option<Self> {
match Uuid::parse_str(data) {
Ok(uuid) => Some(Self(uuid)),
Err(_) => None,
}
}
}
impl std::fmt::Display for UserId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl UserId {
/// Log user actions to config.user_store_access|reqs_store_file/user_id/config.user_store_access path
/// Add a line with timestamp
/// It also get ReqHeaderMap to add more data ?
#[allow(dead_code)]
pub fn log_user_id_action(&self, action: UserAction, sessions_config: &SessionsConfig) -> std::io::Result<()> {
let id_path = format!("{}/{}",
sessions_config.users_store_uri.replace(FILE_SCHEME, ""),
self);
if ! Path::new(&id_path).exists() {
fs::create_dir(&id_path)?;
}
let now = chrono::Utc::now().timestamp().to_string();
let (log_data, file_path) = match action {
UserAction::Access => (
format!("{}\n",now),
format!("{}/{}",&id_path,sessions_config.user_store_access)
),
UserAction::Log(info) => (
format!("notity:{}:{}\n",now,info),
format!("{}/{}",&id_path,sessions_config.user_store_access)
),
UserAction::Request(info) => (
format!("req:{}:{}\n",now,info),
format!("{}/{}",&id_path,sessions_config.user_store_access)
),
UserAction::View(info) => (
format!("view:{}:{}\n",now,info),
format!("{}/{}",&id_path,sessions_config.user_store_access)
),
UserAction::List(info) => (
format!("list:{}:{}\n",now,info),
format!("{}/{}",&id_path,sessions_config.user_store_access)
),
UserAction::Profile(info) => (
format!("profile:{}:{}\n",now,info),
format!("{}/{}",&id_path,sessions_config.user_store_access)
),
UserAction::Other => (
format!("other:{}::\n",now),
format!("{}/{}",&id_path,sessions_config.user_store_access)
),
};
self.write_data(&file_path, &log_data, false)
// if ! Path::new(&file_path).exists() {
// fs::write(&file_path, log_data)?;
// } else {
// let access_id_file = fs::OpenOptions::new()
// .write(true)
// .append(true) // This is needed to append to file
// .open(&file_path);
// if let Ok(mut file) = access_id_file {
// let _ = file.write_all(log_data.as_bytes())?;
// }
// }
// Ok(())
}
fn id_path(&self, file: &str, sessions_config: &SessionsConfig) -> String {
format!("{}/{}/{}",
sessions_config.users_store_uri.replace(FILE_SCHEME, ""),
self,file)
}
#[allow(dead_code)]
fn write_data(&self, file_path: &str, data: &str, overwrite: bool) -> std::io::Result<()> {
let check_path = |path: &Path| -> std::io::Result<()> {
if ! Path::new(&path).exists() {
if let Err(e) = std::fs::create_dir(&path) {
return Err(Error::new( ErrorKind::InvalidInput,
format!("Error create path {}: {}",&path.display(), e)
));
// std::process::exit(2)
}
}
Ok(())
};
if file_path.is_empty() || data.is_empty() {
return Err(Error::new(
ErrorKind::InvalidInput,
format!("Error save {}",&file_path)
));
}
if ! Path::new(&file_path).exists() {
let path = PathBuf::from(&file_path);
if let Some(dir_path) = path.parent() {
if ! Path::new(&dir_path).exists() {
if let Some(parent_dir_path) = dir_path.parent() {
if ! Path::new(&parent_dir_path).exists() {
let res = check_path(&parent_dir_path);
if res.is_err() { return res; }
}
}
let res = check_path(&dir_path);
if res.is_err() { return res; }
}
}
}
if overwrite || ! Path::new(&file_path).exists() {
fs::write(&file_path, data)?;
println!("Overwrite: {}",&file_path);
} else {
let sid_settings_file = fs::OpenOptions::new()
.write(true)
.append(true) // This is needed to append to file
.open(&file_path);
if let Ok(mut file) = sid_settings_file {
file.write_all(data.as_bytes())?;
}
println!("write: {}",&file_path);
}
Ok(())
}
#[allow(dead_code)]
pub fn sid_settings_path(&self, sessions_config: &SessionsConfig) -> String {
self.id_path(SID_SETTINGS_FILE, sessions_config)
}
#[allow(dead_code)]
pub fn sid_settings_content(&self, sessions_config: &SessionsConfig) -> String {
let file_path = self.sid_settings_path(sessions_config);
if ! Path::new(&file_path).exists() {
String::from("")
} else {
match std::fs::read_to_string(&file_path) {
Ok(content) => content,
Err(e) => {
error!("Error read {}: {}",&file_path,e);
String::from("")
}
}
}
}
// pub fn sid_settings(&self, sessions_config: &SessionsConfig) -> SidSettings {
// let file_path = self.id_path(SID_SETTINGS_FILE, sessions_config);
// if Path::new(&file_path).exists() {
// match std::fs::read_to_string(&file_path) {
// Ok(content) => sessions_config.sid_settings.from_json(&content,&file_path),
// Err(e) => {
// error!("Error read {}: {}",&file_path,e);
// sessions_config.sid_settings.to_owned()
// }
// }
// } else {
// //dbg!(&sessions_config.sid_settings);
// sessions_config.sid_settings.to_owned()
// }
// }
// pub fn save_sid_settings(&self, sid_settings: SidSettings, sessions_config: &SessionsConfig) -> std::io::Result<()> {
// let file_path = self.id_path(SID_SETTINGS_FILE, sessions_config);
// let data = sid_settings.to_json();
// self.write_data(&file_path, &data, true)
// }
#[allow(dead_code)]
pub fn save_trace_data(&self, trace_data: TraceData, sessions_config: &SessionsConfig) -> std::io::Result<()> {
// let file_curenv_path = self.id_path(&format!("{}/{}",trace_data.server,SID_CURENV_FILE), sessions_config);
// let res_curenv = self.write_data(&file_curenv_path, &trace_data.curenv, true);
// let _ = res_curenv.as_ref().unwrap_or_else(|e|{
// println!("Error save trace curenv: {}",&e);
// &()
// });
// if res_curenv.is_err() {
// return res_curenv;
// }
// if trace_data.ui.len() > 0 {
// let file_ui_path = self.id_path(&format!("{}/{}",trace_data.server,SID_UI_FILE), sessions_config);
// let res_ui = self.write_data(&file_ui_path, &trace_data.ui, true);
// let _ = res_ui.as_ref().unwrap_or_else(|e|{
// println!("Error save trace ui: {}",&e);
// &()
// });
// if res_ui.is_err() { return res_ui; }
// }
let file_trace_path = self.id_path(&format!("{}/{}",trace_data.server,SID_TRACE_FILE), sessions_config);
let contents = trace_data.contents_to_json();
let mut result = Ok(());
let lines = contents.len() - 1;
for (idx, line) in contents.iter().enumerate() {
let prfx = if idx == 0 && Path::new(&file_trace_path).exists() {
",\n"
} else {
""
};
let sfx = if idx == lines {
""
} else {
",\n"
};
result = self.write_data(
&file_trace_path,
format!("{}{}{}",&prfx,&line,&sfx).as_str(),
false
);
let _ = result.as_ref().unwrap_or_else(|e|{
println!("Error save trace contets: {} line {}",&e, &idx);
&()
});
if result.is_err() {
break;
}
}
result
}
#[allow(dead_code)]
pub fn save_sid_request(&self, data: &str, sessions_config: &SessionsConfig) -> std::io::Result<()> {
let file_path = self.id_path(SID_REQUESTS_FILE, sessions_config);
println!("---- {}",&file_path);
self.write_data(&file_path, &data, false)
}
#[allow(dead_code)]
pub fn read_sid_requests(&self, sessions_config: &SessionsConfig) -> Result<Vec<String>, Box<dyn std::error::Error>> {
let file_path = self.id_path(SID_REQUESTS_FILE, sessions_config);
let data = fs::read_to_string(file_path)?;
Ok(data.split("\n").map(|s| s.to_string()).collect())
}
}