Communities

This commit is contained in:
Alex Emmet 2025-10-26 11:17:52 +01:00
commit 1c08956387
26 changed files with 1988 additions and 338 deletions

View file

@ -3,142 +3,123 @@ use crate::users::user_profile::UserProfile;
use crate::users::user_profile_full::UserProfileFull;
use crate::util::config_util::CONFIG;
use crate::util::file_util::{load_file, save_file};
use base64::{Engine as _, engine::general_purpose};
use der::DerOrd;
use base64::{Engine as _, engine::general_purpose::STANDARD};
use hex;
use json::JsonValue;
use once_cell::sync::Lazy;
use pkcs8::EncodePublicKey;
use pkcs8::spki::SubjectPublicKeyInfoOwned;
use pkcs8::{ObjectIdentifier, PrivateKeyInfo, SubjectPublicKeyInfo, der::Encode};
use rand::Rng;
use rand_core::OsRng;
use rand_core::RngCore;
use rustls::pki_types::SubjectPublicKeyInfoDer;
use sha2::{Digest, Sha256};
use std::io;
use std::sync::Mutex;
use uuid::Uuid;
use x448::{PublicKey, Secret};
use x509::AlgorithmIdentifier;
pub struct UserManager;
static USERS: Lazy<Mutex<Vec<UserProfile>>> = Lazy::new(|| Mutex::new(Vec::new()));
static UNIQUE: Lazy<Mutex<bool>> = Lazy::new(|| Mutex::new(false));
impl UserManager {
pub async fn create_user(username: &str) -> Option<UserProfileFull> {
let user_id = auth_connector::get_register().await.unwrap();
let mut buf = [0u8; 56];
let mut rng = OsRng;
rng.fill_bytes(&mut buf);
let private_key = Secret::from_bytes(&buf).unwrap();
let public_key = PublicKey::from(&private_key);
pub async fn create_user(username: &str) -> Option<UserProfileFull> {
let user_id = auth_connector::get_register().await.unwrap();
let mut buf = [0u8; 56];
let mut rng = OsRng;
rng.fill_bytes(&mut buf);
let private_key = Secret::from_bytes(&buf).unwrap();
let public_key = PublicKey::from(&private_key);
let mut hasher = Sha256::new();
hasher.update(
&general_purpose::STANDARD
.encode(&private_key.as_bytes())
.as_bytes(),
);
let result = hasher.finalize();
let private_key_hash = hex::encode(result);
let mut hasher = Sha256::new();
hasher.update(&STANDARD.encode(&private_key.as_bytes()).as_bytes());
let result = hasher.finalize();
let private_key_hash = hex::encode(result);
let mut bytes = [0u8; 192];
OsRng.fill(bytes.as_mut());
let reset_token = general_purpose::STANDARD.encode(&bytes);
let mut bytes = [0u8; 192];
OsRng.fill(bytes.as_mut());
let reset_token = STANDARD.encode(&bytes);
let up = UserProfile::new(
user_id,
username.to_string(),
None,
general_purpose::STANDARD.encode(&public_key.as_bytes()),
private_key_hash,
reset_token,
);
let up = UserProfile::new(
user_id,
username.to_string(),
None,
STANDARD.encode(&public_key.as_bytes()),
private_key_hash,
reset_token,
);
let up_full = UserProfileFull {
user_profile: up.clone(),
private_key: general_purpose::STANDARD.encode(&private_key.as_bytes()),
};
let up_full = UserProfileFull {
user_profile: up.clone(),
private_key: STANDARD.encode(&private_key.as_bytes()),
};
auth_connector::complete_register(&up, &CONFIG.lock().unwrap().get_iota_id().to_string())
.await;
save_file(
"",
&format!("{}.tu", username),
&format!(
"{}::{}",
user_id,
general_purpose::STANDARD.encode(&private_key.as_bytes())
),
);
auth_connector::complete_register(&up, &CONFIG.lock().unwrap().get_iota_id().to_string()).await;
save_file(
"",
&format!("{}.tu", username),
&format!("{}::{}", user_id, STANDARD.encode(&private_key.as_bytes())),
);
USERS.lock().unwrap().push(up);
Self::save_users().ok();
Some(up_full)
USERS.lock().unwrap().push(up);
save_users().ok();
Some(up_full)
}
pub fn get_user(user_id: Uuid) -> Option<UserProfile> {
USERS
.lock()
.unwrap()
.iter()
.cloned()
.find(|u| u.user_id == user_id)
}
pub fn get_users() -> Vec<UserProfile> {
USERS.lock().unwrap().clone()
}
pub fn add_user(up: UserProfile) {
let mut users = USERS.lock().unwrap();
users.retain(|u| u.user_id != up.user_id);
users.push(up);
*UNIQUE.lock().unwrap() = true;
}
pub fn remove_user(user_id: Uuid) {
let mut users = USERS.lock().unwrap();
users.retain(|u| u.user_id != user_id);
*UNIQUE.lock().unwrap() = true;
}
pub fn save_users() -> io::Result<()> {
*UNIQUE.lock().unwrap() = false;
let users = USERS.lock().unwrap();
let arr: Vec<JsonValue> = users.iter().map(|u| u.to_json()).collect();
let json_str = JsonValue::Array(arr).dump();
save_file("", "users.json", &json_str);
Ok(())
}
pub async fn load_users() -> io::Result<()> {
let content = load_file("", "users.json");
if content.trim().is_empty() {
return Ok(());
}
pub fn get_user(user_id: Uuid) -> Option<UserProfile> {
USERS
.lock()
.unwrap()
.iter()
.cloned()
.find(|u| u.user_id == user_id)
}
pub fn get_users() -> Vec<UserProfile> {
USERS.lock().unwrap().clone()
}
pub fn add_user(up: UserProfile) {
let parsed =
json::parse(&content).map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string()))?;
if let JsonValue::Array(arr) = parsed {
let mut users = USERS.lock().unwrap();
users.retain(|u| u.user_id != up.user_id);
users.push(up);
*UNIQUE.lock().unwrap() = true;
}
pub fn remove_user(user_id: Uuid) {
let mut users = USERS.lock().unwrap();
users.retain(|u| u.user_id != user_id);
*UNIQUE.lock().unwrap() = true;
}
pub fn save_users() -> io::Result<()> {
*UNIQUE.lock().unwrap() = false;
let users = USERS.lock().unwrap();
let arr: Vec<JsonValue> = users.iter().map(|u| u.to_json()).collect();
let json_str = JsonValue::Array(arr).dump();
save_file("", "users.json", &json_str);
Ok(())
}
pub async fn load_users() -> io::Result<()> {
let content = load_file("", "users.json");
if content.trim().is_empty() {
return Ok(());
}
let parsed = json::parse(&content)
.map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string()))?;
if let JsonValue::Array(arr) = parsed {
let mut users = USERS.lock().unwrap();
for j in arr.iter() {
if let Some(up) = UserProfile::from_json(j).await {
users.push(up);
}
for j in arr.iter() {
if let Some(up) = UserProfile::from_json(j).await {
users.push(up);
}
}
if *UNIQUE.lock().unwrap() {
Self::save_users().ok();
}
Ok(())
}
pub fn set_unique(val: bool) {
*UNIQUE.lock().unwrap() = val;
if *UNIQUE.lock().unwrap() {
save_users().ok();
}
Ok(())
}
pub fn set_unique(val: bool) {
*UNIQUE.lock().unwrap() = val;
}