register logic (bricked) user management !! omikron con wait for
response method !!
This commit is contained in:
parent
d289346c63
commit
0d51dc9ac7
16 changed files with 361 additions and 260 deletions
21
Cargo.lock
generated
21
Cargo.lock
generated
|
|
@ -627,6 +627,20 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dashmap"
|
||||||
|
version = "6.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"crossbeam-utils",
|
||||||
|
"hashbrown 0.14.5",
|
||||||
|
"lock_api",
|
||||||
|
"once_cell",
|
||||||
|
"parking_lot_core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "data-encoding"
|
name = "data-encoding"
|
||||||
version = "2.9.0"
|
version = "2.9.0"
|
||||||
|
|
@ -1014,6 +1028,12 @@ dependencies = [
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.14.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.15.5"
|
version = "0.15.5"
|
||||||
|
|
@ -1404,6 +1424,7 @@ dependencies = [
|
||||||
"cmake",
|
"cmake",
|
||||||
"color-eyre",
|
"color-eyre",
|
||||||
"crossterm 0.29.0",
|
"crossterm 0.29.0",
|
||||||
|
"dashmap",
|
||||||
"der",
|
"der",
|
||||||
"futures",
|
"futures",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
|
|
||||||
|
|
@ -55,3 +55,4 @@ ratatui_input = "0.1.3"
|
||||||
tui-textarea = "0.7.0"
|
tui-textarea = "0.7.0"
|
||||||
tui-input = "0.14.0"
|
tui-input = "0.14.0"
|
||||||
pnet = "0.35.0"
|
pnet = "0.35.0"
|
||||||
|
dashmap = "6.1.0"
|
||||||
|
|
|
||||||
|
|
@ -1,158 +0,0 @@
|
||||||
use crate::CONFIG;
|
|
||||||
use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes};
|
|
||||||
use crate::users::user_profile::UserProfile;
|
|
||||||
use json::JsonValue;
|
|
||||||
use json::number::Number;
|
|
||||||
use reqwest::header::CONTENT_TYPE;
|
|
||||||
use reqwest::{Client, Response};
|
|
||||||
use std::time::Duration;
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct AuthUser {
|
|
||||||
pub created_at: i64,
|
|
||||||
pub username: String,
|
|
||||||
pub display: String,
|
|
||||||
pub avatar: String,
|
|
||||||
pub about: String,
|
|
||||||
pub status: String,
|
|
||||||
pub public_key: String,
|
|
||||||
pub sub_level: i32,
|
|
||||||
pub sub_end: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn client() -> Client {
|
|
||||||
Client::builder()
|
|
||||||
.connect_timeout(Duration::from_secs(100))
|
|
||||||
.timeout(Duration::from_secs(150))
|
|
||||||
.build()
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn unregister_user(user_id: i64, reset_token: &str) -> Option<bool> {
|
|
||||||
let url = format!("https:/auth.tensamin.net/api/delete/{}", user_id);
|
|
||||||
let client = client();
|
|
||||||
|
|
||||||
let mut payload = JsonValue::new_object();
|
|
||||||
payload["reset_token"] = reset_token.into();
|
|
||||||
|
|
||||||
let res = client
|
|
||||||
.post(&url)
|
|
||||||
.header(CONTENT_TYPE, "application/json")
|
|
||||||
.body(payload.dump())
|
|
||||||
.send()
|
|
||||||
.await
|
|
||||||
.ok()?;
|
|
||||||
let json = res.text().await.ok()?;
|
|
||||||
let cv = CommunicationValue::from_json(&json);
|
|
||||||
Option::from(cv.is_type(CommunicationType::success))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_user(user_id: i64) -> Option<AuthUser> {
|
|
||||||
let url = format!("https://auth.tensamin.net/api/get/{}", user_id);
|
|
||||||
let client = client();
|
|
||||||
let res = client.get(&url).send().await.ok()?;
|
|
||||||
let json = res.text().await.ok()?;
|
|
||||||
|
|
||||||
let cv = CommunicationValue::from_json(&json);
|
|
||||||
if cv.comm_type != CommunicationType::success {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(AuthUser {
|
|
||||||
created_at: cv
|
|
||||||
.get_data(DataTypes::created_at)
|
|
||||||
.unwrap()
|
|
||||||
.to_string()
|
|
||||||
.parse::<i64>()
|
|
||||||
.unwrap_or(-1),
|
|
||||||
username: cv.get_data(DataTypes::username).unwrap().to_string(),
|
|
||||||
display: cv.get_data(DataTypes::display).unwrap().to_string(),
|
|
||||||
avatar: cv.get_data(DataTypes::avatar).unwrap().to_string(),
|
|
||||||
about: cv.get_data(DataTypes::about).unwrap().to_string(),
|
|
||||||
status: cv.get_data(DataTypes::status).unwrap().to_string(),
|
|
||||||
public_key: cv.get_data(DataTypes::public_key).unwrap().to_string(),
|
|
||||||
sub_level: cv
|
|
||||||
.get_data(DataTypes::sub_level)
|
|
||||||
.unwrap()
|
|
||||||
.to_string()
|
|
||||||
.parse::<i32>()
|
|
||||||
.unwrap_or(-1),
|
|
||||||
sub_end: cv
|
|
||||||
.get_data(DataTypes::sub_end)
|
|
||||||
.unwrap()
|
|
||||||
.to_string()
|
|
||||||
.parse::<i32>()
|
|
||||||
.unwrap_or(-1),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_register() -> Option<i64> {
|
|
||||||
let url = "https://auth.tensamin.net/api/register/init".to_string();
|
|
||||||
let client = client();
|
|
||||||
let res = client.get(&url).send().await.ok()?;
|
|
||||||
let json = res.text().await.ok()?;
|
|
||||||
|
|
||||||
let cv = CommunicationValue::from_json(&json);
|
|
||||||
cv.get_data(DataTypes::user_id)
|
|
||||||
.unwrap_or(&json::JsonValue::Number(Number::from(0)))
|
|
||||||
.as_i64()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn complete_register(user_profile: &UserProfile, iota_id: &str) -> bool {
|
|
||||||
let url = "https://auth.tensamin.net/api/register/complete";
|
|
||||||
let client = client();
|
|
||||||
|
|
||||||
let mut payload = JsonValue::new_object();
|
|
||||||
payload["id"] = user_profile.user_id.into();
|
|
||||||
payload["public_key"] = user_profile.public_key.clone().into();
|
|
||||||
payload["private_key_hash"] = user_profile.private_key_hash.clone().into();
|
|
||||||
payload["username"] = user_profile.username.clone().into();
|
|
||||||
payload["iota_id"] = iota_id.into();
|
|
||||||
payload["reset_token"] = user_profile.reset_token.clone().into();
|
|
||||||
|
|
||||||
let res = client
|
|
||||||
.post(url)
|
|
||||||
.header(CONTENT_TYPE, "application/json")
|
|
||||||
.body(payload.to_string())
|
|
||||||
.send()
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let body = res.text().await.unwrap();
|
|
||||||
|
|
||||||
CommunicationValue::from_json(&body).is_type(CommunicationType::success)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn migrate_user(user_profile: &mut UserProfile) -> bool {
|
|
||||||
let url = format!(
|
|
||||||
"https://auth.tensamin.net/api/change/iota-id/{}",
|
|
||||||
user_profile.user_id
|
|
||||||
);
|
|
||||||
let client = client();
|
|
||||||
|
|
||||||
let mut payload = JsonValue::new_object();
|
|
||||||
payload["iota_id"] = JsonValue::String(CONFIG.read().await.get_iota_id().to_string());
|
|
||||||
payload["reset_token"] = user_profile.reset_token.clone().into();
|
|
||||||
payload["new_token"] = user_profile.randomize_reset_token().into();
|
|
||||||
|
|
||||||
let res = client
|
|
||||||
.post(url)
|
|
||||||
.header(CONTENT_TYPE, "application/json")
|
|
||||||
.body(payload.dump())
|
|
||||||
.send()
|
|
||||||
.await;
|
|
||||||
|
|
||||||
match res {
|
|
||||||
Ok(resp) => handle_response(resp).await,
|
|
||||||
Err(_) => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn handle_response(resp: Response) -> bool {
|
|
||||||
match resp.text().await {
|
|
||||||
Ok(text) => {
|
|
||||||
let cv = CommunicationValue::from_json(&text.to_string());
|
|
||||||
cv.comm_type == CommunicationType::success
|
|
||||||
}
|
|
||||||
Err(_) => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
18
src/auth/auth_user.rs
Normal file
18
src/auth/auth_user.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub struct AuthUser {
|
||||||
|
pub id: i64,
|
||||||
|
pub username: String,
|
||||||
|
pub password_hash: String,
|
||||||
|
pub public_key: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AuthUser {
|
||||||
|
pub fn new(id: i64, username: String, password_hash: String, public_key: String) -> Self {
|
||||||
|
AuthUser {
|
||||||
|
id,
|
||||||
|
username,
|
||||||
|
password_hash,
|
||||||
|
public_key,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use json::JsonValue;
|
use json::JsonValue;
|
||||||
|
|
||||||
use crate::util::file_util::load_file;
|
use crate::util::file_util::load_file;
|
||||||
|
// NOT USED AT MOMENT
|
||||||
pub fn is_private_key_valid(user_id: &i64, key_hash: &str) -> bool {
|
pub fn is_private_key_valid(user_id: &i64, key_hash: &str) -> bool {
|
||||||
let file_contents = load_file("", "users.json");
|
let file_contents = load_file("", "users.json");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,2 @@
|
||||||
pub mod auth_connector;
|
pub mod auth_user;
|
||||||
pub mod crypto_helper;
|
|
||||||
pub mod local_auth;
|
pub mod local_auth;
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
use crate::auth::auth_connector::AuthUser;
|
use crate::auth::auth_user::AuthUser;
|
||||||
use crate::auth::auth_connector::get_user;
|
|
||||||
use crate::communities::community::Community;
|
use crate::communities::community::Community;
|
||||||
use crate::communities::interactables::interactable::Interactable;
|
use crate::communities::interactables::interactable::Interactable;
|
||||||
use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes};
|
use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes};
|
||||||
|
use crate::users::user_manager::get_user;
|
||||||
use aes_gcm::{Aes256Gcm, KeyInit, Nonce, aead::Aead};
|
use aes_gcm::{Aes256Gcm, KeyInit, Nonce, aead::Aead};
|
||||||
use base64::{Engine as _, engine::general_purpose::STANDARD};
|
use base64::{Engine as _, engine::general_purpose::STANDARD};
|
||||||
use futures::SinkExt;
|
use futures::SinkExt;
|
||||||
|
|
@ -121,7 +121,7 @@ impl CommunityConnection {
|
||||||
.as_i64()
|
.as_i64()
|
||||||
.unwrap_or(0);
|
.unwrap_or(0);
|
||||||
|
|
||||||
let Some(user) = get_user(user_id).await else {
|
let Some(user) = get_user(user_id) else {
|
||||||
self.send_error_response(&cv.get_id(), CommunicationType::error_invalid_user_id)
|
self.send_error_response(&cv.get_id(), CommunicationType::error_invalid_user_id)
|
||||||
.await;
|
.await;
|
||||||
return;
|
return;
|
||||||
|
|
@ -129,7 +129,7 @@ impl CommunityConnection {
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut auth_guard = self.auth.write().await;
|
let mut auth_guard = self.auth.write().await;
|
||||||
*auth_guard = Some(user.clone());
|
//*auth_guard = Some(user.clone());
|
||||||
|
|
||||||
let mut user_id_guard = self.user_id.write().await;
|
let mut user_id_guard = self.user_id.write().await;
|
||||||
*user_id_guard = user_id;
|
*user_id_guard = user_id;
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ pub enum DataTypes {
|
||||||
error_type,
|
error_type,
|
||||||
accepted_ids,
|
accepted_ids,
|
||||||
uuid,
|
uuid,
|
||||||
|
register_id,
|
||||||
settings,
|
settings,
|
||||||
settings_name,
|
settings_name,
|
||||||
chat_partner_id,
|
chat_partner_id,
|
||||||
|
|
@ -81,6 +82,8 @@ pub enum DataTypes {
|
||||||
online_status,
|
online_status,
|
||||||
omikron_id,
|
omikron_id,
|
||||||
omikron_connections,
|
omikron_connections,
|
||||||
|
reset_token,
|
||||||
|
new_token,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DataTypes {
|
impl DataTypes {
|
||||||
|
|
@ -90,6 +93,7 @@ impl DataTypes {
|
||||||
match normalized.as_str() {
|
match normalized.as_str() {
|
||||||
"errortype" => DataTypes::error_type,
|
"errortype" => DataTypes::error_type,
|
||||||
"chatpartnerid" => DataTypes::chat_partner_id,
|
"chatpartnerid" => DataTypes::chat_partner_id,
|
||||||
|
"registerid" => DataTypes::register_id,
|
||||||
"uuid" => DataTypes::uuid,
|
"uuid" => DataTypes::uuid,
|
||||||
"settings" => DataTypes::settings,
|
"settings" => DataTypes::settings,
|
||||||
"settingsname" => DataTypes::settings_name,
|
"settingsname" => DataTypes::settings_name,
|
||||||
|
|
@ -161,6 +165,8 @@ impl DataTypes {
|
||||||
"onlinestatus" => DataTypes::online_status,
|
"onlinestatus" => DataTypes::online_status,
|
||||||
"omikronid" => DataTypes::omikron_id,
|
"omikronid" => DataTypes::omikron_id,
|
||||||
"omikronconnections" => DataTypes::omikron_connections,
|
"omikronconnections" => DataTypes::omikron_connections,
|
||||||
|
"resettoken" => DataTypes::reset_token,
|
||||||
|
"newtoken" => DataTypes::new_token,
|
||||||
_ => DataTypes::error_type, // fallback if unknown
|
_ => DataTypes::error_type, // fallback if unknown
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -170,6 +176,8 @@ impl DataTypes {
|
||||||
#[allow(non_camel_case_types, dead_code)]
|
#[allow(non_camel_case_types, dead_code)]
|
||||||
pub enum CommunicationType {
|
pub enum CommunicationType {
|
||||||
error,
|
error,
|
||||||
|
error_internal,
|
||||||
|
error_invalid_data,
|
||||||
error_invalid_user_id,
|
error_invalid_user_id,
|
||||||
error_invalid_omikron_id,
|
error_invalid_omikron_id,
|
||||||
error_not_found,
|
error_not_found,
|
||||||
|
|
@ -206,6 +214,8 @@ pub enum CommunicationType {
|
||||||
register_response,
|
register_response,
|
||||||
identification,
|
identification,
|
||||||
identification_response,
|
identification_response,
|
||||||
|
register_iota,
|
||||||
|
register_iota_success,
|
||||||
ping,
|
ping,
|
||||||
pong,
|
pong,
|
||||||
add_chat,
|
add_chat,
|
||||||
|
|
@ -244,6 +254,12 @@ pub enum CommunicationType {
|
||||||
change_user_data,
|
change_user_data,
|
||||||
change_iota_data,
|
change_iota_data,
|
||||||
|
|
||||||
|
get_register,
|
||||||
|
complete_register_user,
|
||||||
|
complete_register_iota,
|
||||||
|
delete_user,
|
||||||
|
delete_iota,
|
||||||
|
|
||||||
start_register,
|
start_register,
|
||||||
complete_register,
|
complete_register,
|
||||||
}
|
}
|
||||||
|
|
@ -262,6 +278,8 @@ impl CommunicationType {
|
||||||
"function" => CommunicationType::function,
|
"function" => CommunicationType::function,
|
||||||
"update" => CommunicationType::update,
|
"update" => CommunicationType::update,
|
||||||
"createuser" => CommunicationType::create_user,
|
"createuser" => CommunicationType::create_user,
|
||||||
|
"errorinternal" => CommunicationType::error_internal,
|
||||||
|
"errorinvaliddata" => CommunicationType::error_invalid_data,
|
||||||
"errorinvaliduserid" => CommunicationType::error_invalid_user_id,
|
"errorinvaliduserid" => CommunicationType::error_invalid_user_id,
|
||||||
"errorinvalidomikronid" => CommunicationType::error_invalid_omikron_id,
|
"errorinvalidomikronid" => CommunicationType::error_invalid_omikron_id,
|
||||||
"errornotfound" => CommunicationType::error_not_found,
|
"errornotfound" => CommunicationType::error_not_found,
|
||||||
|
|
@ -298,6 +316,8 @@ impl CommunicationType {
|
||||||
"registerresponse" => CommunicationType::register_response,
|
"registerresponse" => CommunicationType::register_response,
|
||||||
"identification" => CommunicationType::identification,
|
"identification" => CommunicationType::identification,
|
||||||
"identificationresponse" => CommunicationType::identification_response,
|
"identificationresponse" => CommunicationType::identification_response,
|
||||||
|
"registeriota" => CommunicationType::register_iota,
|
||||||
|
"registeriotasuccess" => CommunicationType::register_iota_success,
|
||||||
"ping" => CommunicationType::ping,
|
"ping" => CommunicationType::ping,
|
||||||
"pong" => CommunicationType::pong,
|
"pong" => CommunicationType::pong,
|
||||||
"addchat" => CommunicationType::add_chat,
|
"addchat" => CommunicationType::add_chat,
|
||||||
|
|
@ -326,6 +346,12 @@ impl CommunicationType {
|
||||||
"changeuserdata" => CommunicationType::change_user_data,
|
"changeuserdata" => CommunicationType::change_user_data,
|
||||||
"changeiotadata" => CommunicationType::change_iota_data,
|
"changeiotadata" => CommunicationType::change_iota_data,
|
||||||
|
|
||||||
|
"getregister" => CommunicationType::get_register,
|
||||||
|
"completeregisteruser" => CommunicationType::complete_register_user,
|
||||||
|
"completeregisteriota" => CommunicationType::complete_register_iota,
|
||||||
|
"deleteuser" => CommunicationType::delete_user,
|
||||||
|
"deleteiota" => CommunicationType::delete_iota,
|
||||||
|
|
||||||
"startregister" => CommunicationType::start_register,
|
"startregister" => CommunicationType::start_register,
|
||||||
"completeregister" => CommunicationType::complete_register,
|
"completeregister" => CommunicationType::complete_register,
|
||||||
|
|
||||||
|
|
|
||||||
28
src/main.rs
28
src/main.rs
|
|
@ -71,18 +71,6 @@ async fn main() {
|
||||||
|
|
||||||
// BASIC CONFIGURATION
|
// BASIC CONFIGURATION
|
||||||
&CONFIG.write().await.load();
|
&CONFIG.write().await.load();
|
||||||
if !CONFIG.read().await.config.has_key("iota_id") {
|
|
||||||
CONFIG.write().await.change(
|
|
||||||
"iota_id",
|
|
||||||
JsonValue::Number(Number::from(
|
|
||||||
SystemTime::now()
|
|
||||||
.duration_since(UNIX_EPOCH)
|
|
||||||
.unwrap_or(Duration::from_millis(0))
|
|
||||||
.as_millis() as i64,
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
CONFIG.write().await.update();
|
|
||||||
}
|
|
||||||
|
|
||||||
// USER MANAGEMENT
|
// USER MANAGEMENT
|
||||||
if let Err(_) = user_manager::load_users().await {
|
if let Err(_) = user_manager::load_users().await {
|
||||||
|
|
@ -153,21 +141,7 @@ async fn main() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let omikron: Arc<OmikronConnection> = Arc::new(OmikronConnection::new());
|
let omikron: Arc<OmikronConnection> = Arc::new(OmikronConnection::new());
|
||||||
omikron.connect().await;
|
omikron.connect(sb.clone()).await;
|
||||||
omikron
|
|
||||||
.send_message(
|
|
||||||
CommunicationValue::new(CommunicationType::identification)
|
|
||||||
.add_data(DataTypes::user_ids, JsonValue::String(sb.to_string()))
|
|
||||||
.add_data(
|
|
||||||
DataTypes::iota_id,
|
|
||||||
JsonValue::Number(Number::from(CONFIG.read().await.get_iota_id())),
|
|
||||||
)
|
|
||||||
.to_json()
|
|
||||||
.to_string()
|
|
||||||
.as_mut()
|
|
||||||
.to_string(),
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
let mut omikron_connection = OMIKRON_CONNECTION.write().await;
|
let mut omikron_connection = OMIKRON_CONNECTION.write().await;
|
||||||
*omikron_connection = Some(omikron.clone());
|
*omikron_connection = Some(omikron.clone());
|
||||||
log_message_trans("setup_completed");
|
log_message_trans("setup_completed");
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,35 @@
|
||||||
use crate::auth::local_auth;
|
use crate::auth::local_auth;
|
||||||
use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes};
|
use crate::gui::log_panel::{log_cv, log_message_format};
|
||||||
use crate::gui::log_panel::{log_cv, log_message, log_message_format};
|
use crate::{
|
||||||
|
data::communication::{CommunicationType, CommunicationValue, DataTypes},
|
||||||
|
gui::log_panel::{log_message, log_message_trans},
|
||||||
|
util::{config_util::CONFIG, crypto_helper},
|
||||||
|
};
|
||||||
|
use json::JsonValue;
|
||||||
|
|
||||||
use crate::users::contact::Contact;
|
use crate::users::contact::Contact;
|
||||||
use crate::users::user_community_util::UserCommunityUtil;
|
use crate::users::user_community_util::UserCommunityUtil;
|
||||||
use crate::util::chat_files;
|
use crate::util::chats_util::{get_user, mod_user};
|
||||||
use crate::util::chats_util::{get_user, get_users, mod_user};
|
|
||||||
use crate::util::file_util::{get_children, load_file, save_file};
|
use crate::util::file_util::{get_children, load_file, save_file};
|
||||||
|
use crate::util::{chat_files, chats_util};
|
||||||
use crate::{ACTIVE_TASKS, SHUTDOWN};
|
use crate::{ACTIVE_TASKS, SHUTDOWN};
|
||||||
|
use dashmap::DashMap;
|
||||||
use futures::Stream;
|
use futures::Stream;
|
||||||
use futures::stream::{SplitSink, SplitStream};
|
use futures::stream::{SplitSink, SplitStream};
|
||||||
use futures_util::sink::Sink;
|
use futures_util::sink::Sink;
|
||||||
use futures_util::{SinkExt, StreamExt};
|
use futures_util::{SinkExt, StreamExt};
|
||||||
use hyper::upgrade::Upgraded;
|
use hyper::upgrade::Upgraded;
|
||||||
use hyper_util::rt::TokioIo;
|
use hyper_util::rt::TokioIo;
|
||||||
use json::JsonValue;
|
|
||||||
use json::number::Number;
|
use json::number::Number;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::{Arc, LazyLock};
|
use std::sync::{Arc, LazyLock};
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
use tokio::sync::{Mutex, RwLock};
|
use tokio::sync::{Mutex, RwLock, mpsc};
|
||||||
use tokio::time::{Duration, Instant, sleep};
|
use tokio::time::{Duration, Instant, sleep};
|
||||||
use tokio_tungstenite::{connect_async, tungstenite::protocol::Message};
|
use tokio_tungstenite::{connect_async, tungstenite::protocol::Message};
|
||||||
use tungstenite::Utf8Bytes;
|
use tungstenite::Utf8Bytes;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
pub static OMIKRON_CONNECTION: LazyLock<Arc<RwLock<Option<Arc<OmikronConnection>>>>> =
|
pub static OMIKRON_CONNECTION: LazyLock<Arc<RwLock<Option<Arc<OmikronConnection>>>>> =
|
||||||
LazyLock::new(|| Arc::new(RwLock::new(None)));
|
LazyLock::new(|| Arc::new(RwLock::new(None)));
|
||||||
|
|
||||||
|
|
@ -39,7 +46,7 @@ pub struct OmikronConnection {
|
||||||
pub user_id: Arc<RwLock<i64>>,
|
pub user_id: Arc<RwLock<i64>>,
|
||||||
pub(crate) writer:
|
pub(crate) writer:
|
||||||
Arc<Mutex<Option<Box<dyn Sink<Message, Error = tungstenite::Error> + Send + Unpin>>>>,
|
Arc<Mutex<Option<Box<dyn Sink<Message, Error = tungstenite::Error> + Send + Unpin>>>>,
|
||||||
waiting: Arc<Mutex<HashMap<Uuid, Box<dyn Fn(CommunicationValue) + Send + Sync>>>>,
|
waiting: Arc<DashMap<Uuid, Box<dyn Fn(CommunicationValue) + Send + Sync>>>,
|
||||||
pingpong: Arc<Mutex<Option<tokio::task::JoinHandle<()>>>>,
|
pingpong: Arc<Mutex<Option<tokio::task::JoinHandle<()>>>>,
|
||||||
pub last_ping: Arc<Mutex<i64>>,
|
pub last_ping: Arc<Mutex<i64>>,
|
||||||
pub message_send_times: Arc<Mutex<HashMap<Uuid, Instant>>>,
|
pub message_send_times: Arc<Mutex<HashMap<Uuid, Instant>>>,
|
||||||
|
|
@ -52,7 +59,7 @@ impl OmikronConnection {
|
||||||
variant: Arc::new(RwLock::new(ConnectionVariant::Omikron)),
|
variant: Arc::new(RwLock::new(ConnectionVariant::Omikron)),
|
||||||
user_id: Arc::new(RwLock::new(0)),
|
user_id: Arc::new(RwLock::new(0)),
|
||||||
writer: Arc::new(Mutex::new(None)),
|
writer: Arc::new(Mutex::new(None)),
|
||||||
waiting: Arc::new(Mutex::new(HashMap::new())),
|
waiting: Arc::new(DashMap::new()),
|
||||||
pingpong: Arc::new(Mutex::new(None)),
|
pingpong: Arc::new(Mutex::new(None)),
|
||||||
last_ping: Arc::new(Mutex::new(-1)),
|
last_ping: Arc::new(Mutex::new(-1)),
|
||||||
message_send_times: Arc::new(Mutex::new(HashMap::new())),
|
message_send_times: Arc::new(Mutex::new(HashMap::new())),
|
||||||
|
|
@ -68,7 +75,7 @@ impl OmikronConnection {
|
||||||
user_id: Arc::new(RwLock::new(0)),
|
user_id: Arc::new(RwLock::new(0)),
|
||||||
writer: Arc::new(Mutex::new(Some(Box::new(writer)
|
writer: Arc::new(Mutex::new(Some(Box::new(writer)
|
||||||
as Box<dyn Sink<Message, Error = tungstenite::Error> + Send + Unpin>))),
|
as Box<dyn Sink<Message, Error = tungstenite::Error> + Send + Unpin>))),
|
||||||
waiting: Arc::new(Mutex::new(HashMap::new())),
|
waiting: Arc::new(DashMap::new()),
|
||||||
pingpong: Arc::new(Mutex::new(None)),
|
pingpong: Arc::new(Mutex::new(None)),
|
||||||
last_ping: Arc::new(Mutex::new(-1)),
|
last_ping: Arc::new(Mutex::new(-1)),
|
||||||
message_send_times: Arc::new(Mutex::new(HashMap::new())),
|
message_send_times: Arc::new(Mutex::new(HashMap::new())),
|
||||||
|
|
@ -85,54 +92,103 @@ impl OmikronConnection {
|
||||||
*self.is_connected.lock().await
|
*self.is_connected.lock().await
|
||||||
}
|
}
|
||||||
/// Connect loop with retry
|
/// Connect loop with retry
|
||||||
pub async fn connect(self: &Arc<Self>) {
|
pub async fn connect(self: &Arc<Self>, user_ids: String) {
|
||||||
loop {
|
if self.is_connected().await {
|
||||||
if *SHUTDOWN.read().await {
|
return;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
match connect_async("wss://app.tensamin.net/ws/iota/").await {
|
|
||||||
Ok((ws_stream, _)) => {
|
let conf = CONFIG.read().await;
|
||||||
let (write_half, read_half) = ws_stream.split();
|
let iota_id = conf.get_iota_id();
|
||||||
|
let public_key = conf.get_public_key();
|
||||||
|
let private_key = conf.get_private_key();
|
||||||
|
|
||||||
|
if iota_id == 0 || public_key.is_none() || private_key.is_none() {
|
||||||
|
// Registration flow
|
||||||
|
drop(conf); // release read lock
|
||||||
|
log_message_trans("iota_register_new");
|
||||||
|
let key_pair = crypto_helper::generate_keypair();
|
||||||
|
let public_key_base64 = crypto_helper::public_key_to_base64(&key_pair.public);
|
||||||
|
let private_key_base64 = crypto_helper::secret_key_to_base64(&key_pair.secret);
|
||||||
|
|
||||||
|
let mut conf_write = CONFIG.write().await;
|
||||||
|
conf_write.change("public_key", JsonValue::String(public_key_base64.clone()));
|
||||||
|
conf_write.change("private_key", JsonValue::String(private_key_base64));
|
||||||
|
conf_write.update();
|
||||||
|
drop(conf_write);
|
||||||
|
|
||||||
|
if self.connect_internal().await {
|
||||||
|
// a new helper function to just connect
|
||||||
|
self.send_message(
|
||||||
|
CommunicationValue::new(CommunicationType::register_iota)
|
||||||
|
.add_data(DataTypes::public_key, JsonValue::String(public_key_base64))
|
||||||
|
.to_json()
|
||||||
|
.to_string(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Login flow
|
||||||
|
if self.connect_internal().await {
|
||||||
|
self.send_message(
|
||||||
|
CommunicationValue::new(CommunicationType::identification)
|
||||||
|
.add_data(
|
||||||
|
DataTypes::iota_id,
|
||||||
|
JsonValue::Number(json::number::Number::from(iota_id)),
|
||||||
|
)
|
||||||
|
.to_json()
|
||||||
|
.to_string(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn connect_internal(self: &Arc<Self>) -> bool {
|
||||||
|
if self.is_connected().await {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
log_message_trans("omikron_connecting");
|
||||||
|
|
||||||
|
// connect to omikron
|
||||||
|
let conf = CONFIG.read().await;
|
||||||
|
let addr = conf
|
||||||
|
.get("omikron_addr")
|
||||||
|
.as_str()
|
||||||
|
.unwrap_or("wss://app.tensamin.net/ws/iota/");
|
||||||
|
let stream_res = connect_async(addr).await;
|
||||||
|
if let Err(e) = stream_res {
|
||||||
|
log_message(format!("omikron_connection_error {}", e.to_string()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let (stream, _) = stream_res.unwrap();
|
||||||
|
log_message_trans("omikron_connection_success");
|
||||||
|
|
||||||
|
let (write_half, read_half) = stream.split();
|
||||||
|
|
||||||
*self.writer.lock().await = Some(Box::new(write_half));
|
*self.writer.lock().await = Some(Box::new(write_half));
|
||||||
let boxed_reader: Box<
|
let boxed_reader: Box<
|
||||||
dyn Stream<Item = Result<Message, tungstenite::Error>> + Send + Unpin,
|
dyn Stream<Item = Result<Message, tungstenite::Error>> + Send + Unpin,
|
||||||
> = Box::new(read_half);
|
> = Box::new(read_half);
|
||||||
self.clone().spawn_listener(boxed_reader).await;
|
self.spawn_listener(boxed_reader).await;
|
||||||
let cloned_self = self.clone();
|
|
||||||
|
|
||||||
{
|
let mut is_connected = self.is_connected.lock().await;
|
||||||
ACTIVE_TASKS.lock().unwrap().push("PingPong".to_string());
|
*is_connected = true;
|
||||||
}
|
drop(is_connected);
|
||||||
let handle = tokio::spawn(async move {
|
|
||||||
|
let sel_arc_clone = self.clone();
|
||||||
|
tokio::spawn(async move {
|
||||||
loop {
|
loop {
|
||||||
if *SHUTDOWN.read().await {
|
if !sel_arc_clone.is_connected().await {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if *cloned_self.is_connected.lock().await == false {
|
sel_arc_clone.send_ping().await;
|
||||||
break;
|
sleep(Duration::from_secs(10)).await;
|
||||||
}
|
|
||||||
cloned_self.send_ping().await;
|
|
||||||
sleep(Duration::from_secs(1)).await;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
{
|
|
||||||
ACTIVE_TASKS
|
true
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.retain(|t| !t.eq(&"PingPong".to_string()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*self.is_connected.lock().await = true;
|
|
||||||
*self.pingpong.lock().await = Some(handle);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
*self.is_connected.lock().await = false;
|
|
||||||
sleep(Duration::from_secs(2)).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub async fn send_message(&self, msg: String) {
|
pub async fn send_message(&self, msg: String) {
|
||||||
Self::send_message_static(&self.writer, Arc::clone(&self.is_connected), msg).await;
|
Self::send_message_static(&self.writer, Arc::clone(&self.is_connected), msg).await;
|
||||||
}
|
}
|
||||||
|
|
@ -186,7 +242,7 @@ impl OmikronConnection {
|
||||||
}
|
}
|
||||||
pub fn handle_message(
|
pub fn handle_message(
|
||||||
msg: Result<Message, tungstenite::Error>,
|
msg: Result<Message, tungstenite::Error>,
|
||||||
waiting: Arc<Mutex<HashMap<Uuid, Box<dyn Fn(CommunicationValue) + Send + Sync + 'static>>>>,
|
waiting: Arc<DashMap<Uuid, Box<dyn Fn(CommunicationValue) + Send + Sync + 'static>>>,
|
||||||
writer: Arc<
|
writer: Arc<
|
||||||
Mutex<
|
Mutex<
|
||||||
Option<Box<dyn Sink<Message, Error = tungstenite::Error> + Send + Unpin + 'static>>,
|
Option<Box<dyn Sink<Message, Error = tungstenite::Error> + Send + Unpin + 'static>>,
|
||||||
|
|
@ -205,11 +261,86 @@ impl OmikronConnection {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Ok(Message::Text(text)) => {
|
Ok(Message::Text(text)) => {
|
||||||
let mut cv = CommunicationValue::from_json(&text);
|
let cv = CommunicationValue::from_json(&text);
|
||||||
if cv.is_type(CommunicationType::pong) {
|
if cv.is_type(CommunicationType::pong) {
|
||||||
sel.handle_pong(&cv, true).await;
|
sel.handle_pong(&cv, true).await;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if cv.is_type(CommunicationType::challenge) {
|
||||||
|
let conf = CONFIG.read().await;
|
||||||
|
let private_key = conf.get_private_key().unwrap();
|
||||||
|
drop(conf);
|
||||||
|
|
||||||
|
let omikron_public_key = cv
|
||||||
|
.get_data(DataTypes::public_key)
|
||||||
|
.unwrap()
|
||||||
|
.as_str()
|
||||||
|
.unwrap();
|
||||||
|
let encrypted_challenge =
|
||||||
|
cv.get_data(DataTypes::challenge).unwrap().as_str().unwrap();
|
||||||
|
|
||||||
|
let solved_challenge = crypto_helper::decrypt(
|
||||||
|
&private_key,
|
||||||
|
omikron_public_key,
|
||||||
|
encrypted_challenge,
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Ok(decrypted) = solved_challenge {
|
||||||
|
let response =
|
||||||
|
CommunicationValue::new(CommunicationType::challenge_response)
|
||||||
|
.with_id(cv.get_id())
|
||||||
|
.add_data(DataTypes::challenge, JsonValue::String(decrypted));
|
||||||
|
|
||||||
|
sel_arc.send_message(response.to_json().to_string()).await;
|
||||||
|
} else {
|
||||||
|
log_message("Failed to decrypt challenge");
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if cv.is_type(CommunicationType::register_iota_success) {
|
||||||
|
let iota_id = cv
|
||||||
|
.get_data(DataTypes::iota_id)
|
||||||
|
.unwrap()
|
||||||
|
.as_i64()
|
||||||
|
.unwrap_or(0);
|
||||||
|
if iota_id != 0 {
|
||||||
|
let mut conf = CONFIG.write().await;
|
||||||
|
conf.change("iota_id", JsonValue::Number(iota_id.into()));
|
||||||
|
conf.update();
|
||||||
|
log_message(format!("Iota registered with ID: {}", iota_id));
|
||||||
|
|
||||||
|
// Now, proceed to login
|
||||||
|
let login_message =
|
||||||
|
CommunicationValue::new(CommunicationType::identification)
|
||||||
|
.add_data(
|
||||||
|
DataTypes::iota_id,
|
||||||
|
JsonValue::Number(json::number::Number::from(iota_id)),
|
||||||
|
)
|
||||||
|
.to_json()
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
let sel_arc_clone = sel_arc.clone();
|
||||||
|
tokio::spawn(async move {
|
||||||
|
sel_arc_clone.send_message(login_message).await;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
log_message("Iota registration failed.");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if cv.is_type(CommunicationType::identification_response) {
|
||||||
|
if let Some(accepted) = cv.get_data(DataTypes::accepted) {
|
||||||
|
if accepted.as_str().unwrap_or("0") != "0" {
|
||||||
|
log_message(format!("Omikron connected: {}", accepted.to_string()));
|
||||||
|
} else {
|
||||||
|
log_message("omikron_connection_failed");
|
||||||
|
// Maybe add a retry logic here or close the app
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let com = variant.read().await.clone();
|
let com = variant.read().await.clone();
|
||||||
if com == ConnectionVariant::ClientUnauthenticated {
|
if com == ConnectionVariant::ClientUnauthenticated {
|
||||||
if cv.is_type(CommunicationType::identification) {
|
if cv.is_type(CommunicationType::identification) {
|
||||||
|
|
@ -288,8 +419,8 @@ impl OmikronConnection {
|
||||||
// Direct messages //
|
// Direct messages //
|
||||||
// ************************************************ //
|
// ************************************************ //
|
||||||
log_cv(&cv);
|
log_cv(&cv);
|
||||||
if let Some(x) = waiting.lock().await.remove(&cv.get_id()) {
|
if let Some((_, y)) = waiting.remove(&cv.get_id()) {
|
||||||
x(cv);
|
y(cv);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if cv.is_type(CommunicationType::message_other_iota) {
|
if cv.is_type(CommunicationType::message_other_iota) {
|
||||||
|
|
@ -433,7 +564,7 @@ impl OmikronConnection {
|
||||||
|
|
||||||
if cv.is_type(CommunicationType::get_chats) {
|
if cv.is_type(CommunicationType::get_chats) {
|
||||||
let user_id = cv.get_sender();
|
let user_id = cv.get_sender();
|
||||||
let users = get_users(user_id);
|
let users = chats_util::get_users(user_id);
|
||||||
let resp = CommunicationValue::new(CommunicationType::get_chats)
|
let resp = CommunicationValue::new(CommunicationType::get_chats)
|
||||||
.with_id(cv.get_id())
|
.with_id(cv.get_id())
|
||||||
.with_receiver(user_id)
|
.with_receiver(user_id)
|
||||||
|
|
@ -641,4 +772,41 @@ impl OmikronConnection {
|
||||||
*connected.lock().await = false;
|
*connected.lock().await = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub async fn await_response(
|
||||||
|
self: Arc<Self>,
|
||||||
|
cv: &CommunicationValue,
|
||||||
|
timeout_duration: Option<Duration>,
|
||||||
|
) -> Result<CommunicationValue, String> {
|
||||||
|
let (tx, mut rx) = mpsc::channel(1);
|
||||||
|
let msg_id = cv.get_id();
|
||||||
|
|
||||||
|
let task_tx = tx.clone();
|
||||||
|
self.waiting.insert(
|
||||||
|
msg_id,
|
||||||
|
Box::new(move |response_cv| {
|
||||||
|
let inner_tx = task_tx.clone();
|
||||||
|
tokio::spawn(async move {
|
||||||
|
if let Err(e) = inner_tx.send(response_cv).await {
|
||||||
|
log_message(format!("Failed to send response back to awaiter: {}", &e));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.send_message(cv.to_json().to_string()).await;
|
||||||
|
|
||||||
|
let timeout = timeout_duration.unwrap_or(Duration::from_secs(10));
|
||||||
|
|
||||||
|
match tokio::time::timeout(timeout, rx.recv()).await {
|
||||||
|
Ok(Some(response_cv)) => Ok(response_cv),
|
||||||
|
Ok(None) => Err("Failed to receive response, channel was closed.".to_string()),
|
||||||
|
Err(_) => {
|
||||||
|
self.waiting.remove(&msg_id);
|
||||||
|
Err(format!(
|
||||||
|
"Request timed out after {} seconds.",
|
||||||
|
timeout.as_secs()
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::auth::auth_connector::unregister_user;
|
|
||||||
use crate::communities::community::Community;
|
use crate::communities::community::Community;
|
||||||
use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes};
|
use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes};
|
||||||
use crate::gui::log_panel::log_message;
|
use crate::gui::log_panel::log_message;
|
||||||
|
|
@ -108,11 +107,12 @@ pub async fn handle(
|
||||||
"{\"type\":\"error\"}".to_string()
|
"{\"type\":\"error\"}".to_string()
|
||||||
} else {
|
} else {
|
||||||
let uuid = body.unwrap()["uuid"].as_i64().unwrap_or(0);
|
let uuid = body.unwrap()["uuid"].as_i64().unwrap_or(0);
|
||||||
unregister_user(
|
// TODO MOVE TO OMIKRON CONNECTION
|
||||||
|
/*unregister_user(
|
||||||
uuid,
|
uuid,
|
||||||
&user_manager::get_user(uuid).unwrap().reset_token,
|
&user_manager::get_user(uuid).unwrap().reset_token,
|
||||||
)
|
)
|
||||||
.await;
|
.await;*/
|
||||||
user_manager::remove_user(uuid);
|
user_manager::remove_user(uuid);
|
||||||
user_manager::save_users();
|
user_manager::save_users();
|
||||||
"{}".to_string()
|
"{}".to_string()
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,23 @@
|
||||||
use crate::auth::{auth_connector, crypto_helper};
|
use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes};
|
||||||
use crate::gui::log_panel::log_message;
|
use crate::gui::log_panel::log_message;
|
||||||
|
use crate::omikron::omikron_connection::{OMIKRON_CONNECTION, OmikronConnection};
|
||||||
use crate::users::user_profile::UserProfile;
|
use crate::users::user_profile::UserProfile;
|
||||||
use crate::util::config_util::CONFIG;
|
use crate::util::config_util::CONFIG;
|
||||||
|
use crate::util::crypto_helper::{self, public_key_to_base64};
|
||||||
use crate::util::file_util::{load_file, save_file};
|
use crate::util::file_util::{load_file, save_file};
|
||||||
use crate::{RELOAD, SHUTDOWN};
|
use crate::{RELOAD, SHUTDOWN};
|
||||||
use base64::{Engine as _, engine::general_purpose::STANDARD};
|
use base64::{Engine as _, engine::general_purpose::STANDARD};
|
||||||
use hex::{self};
|
use hex::{self};
|
||||||
use json::JsonValue;
|
use json::JsonValue;
|
||||||
|
use json::number::Number;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use rand_core::OsRng;
|
use rand_core::OsRng;
|
||||||
use rand_core::RngCore;
|
use rand_core::RngCore;
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
use std::io::{self};
|
use std::io::{self};
|
||||||
use std::sync::Mutex;
|
use std::sync::{Arc, Mutex};
|
||||||
|
use std::time::Duration;
|
||||||
use x448::{PublicKey, Secret};
|
use x448::{PublicKey, Secret};
|
||||||
|
|
||||||
static USERS: Lazy<Mutex<Vec<UserProfile>>> = Lazy::new(|| Mutex::new(Vec::new()));
|
static USERS: Lazy<Mutex<Vec<UserProfile>>> = Lazy::new(|| Mutex::new(Vec::new()));
|
||||||
|
|
@ -45,7 +49,25 @@ pub async fn load_from_tu(username: &str) -> Result<(), ()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
pub async fn create_user(username: &str) -> (Option<UserProfile>, Option<String>) {
|
pub async fn create_user(username: &str) -> (Option<UserProfile>, Option<String>) {
|
||||||
let user_id = auth_connector::get_register().await.unwrap();
|
let omikron_con: Arc<OmikronConnection> =
|
||||||
|
OMIKRON_CONNECTION.read().await.as_ref().unwrap().clone();
|
||||||
|
let register_cv = if let Ok(register_cv) = omikron_con
|
||||||
|
.clone()
|
||||||
|
.await_response(
|
||||||
|
&CommunicationValue::new(CommunicationType::get_register),
|
||||||
|
Some(Duration::from_secs(20)),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
register_cv
|
||||||
|
} else {
|
||||||
|
return (None, None);
|
||||||
|
};
|
||||||
|
let user_id = register_cv
|
||||||
|
.get_data(DataTypes::register_id)
|
||||||
|
.unwrap_or(&JsonValue::Null)
|
||||||
|
.as_i64()
|
||||||
|
.unwrap_or(0);
|
||||||
let mut buf = [0u8; 56];
|
let mut buf = [0u8; 56];
|
||||||
let mut rng = OsRng;
|
let mut rng = OsRng;
|
||||||
rng.fill_bytes(&mut buf);
|
rng.fill_bytes(&mut buf);
|
||||||
|
|
@ -67,10 +89,31 @@ pub async fn create_user(username: &str) -> (Option<UserProfile>, Option<String>
|
||||||
None,
|
None,
|
||||||
STANDARD.encode(&public_key.as_bytes()),
|
STANDARD.encode(&public_key.as_bytes()),
|
||||||
private_key_hash,
|
private_key_hash,
|
||||||
reset_token,
|
reset_token.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
auth_connector::complete_register(&up, &CONFIG.read().await.get_iota_id().to_string()).await;
|
let cv = CommunicationValue::new(CommunicationType::complete_register_user)
|
||||||
|
.add_data(DataTypes::user_id, JsonValue::Number(Number::from(user_id)))
|
||||||
|
.add_data(DataTypes::username, JsonValue::String(username.to_string()))
|
||||||
|
.add_data(
|
||||||
|
DataTypes::public_key,
|
||||||
|
JsonValue::String(public_key_to_base64(&public_key)),
|
||||||
|
)
|
||||||
|
.add_data(DataTypes::iota_id, JsonValue::Number(Number::from(user_id)))
|
||||||
|
.add_data(DataTypes::reset_token, JsonValue::String(reset_token));
|
||||||
|
|
||||||
|
let response_cv = omikron_con
|
||||||
|
.await_response(&cv, Some(Duration::from_secs(20)))
|
||||||
|
.await;
|
||||||
|
if let Ok(resp) = response_cv {
|
||||||
|
if !resp.is_type(CommunicationType::success) {
|
||||||
|
return (None, None);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return (None, None);
|
||||||
|
}
|
||||||
|
// auth_connector::complete_register(&up, &CONFIG.read().await.get_iota_id().to_string()).await;
|
||||||
|
//
|
||||||
*SHUTDOWN.write().await = true;
|
*SHUTDOWN.write().await = true;
|
||||||
*RELOAD.write().await = true;
|
*RELOAD.write().await = true;
|
||||||
log_message("Created User");
|
log_message("Created User");
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
use crate::auth::auth_connector;
|
|
||||||
use crate::gui::log_panel::log_message;
|
use crate::gui::log_panel::log_message;
|
||||||
use crate::users::user_manager;
|
use crate::users::user_manager;
|
||||||
use crate::util::file_util::{has_file, load_file, used_dir_space};
|
use crate::util::file_util::{has_file, load_file, used_dir_space};
|
||||||
|
|
@ -95,7 +94,8 @@ impl UserProfile {
|
||||||
reset_token,
|
reset_token,
|
||||||
};
|
};
|
||||||
|
|
||||||
if j.has_key("migrate")
|
// TODO: Migrate to Omikron / Wss
|
||||||
|
/* if j.has_key("migrate")
|
||||||
|| j.has_key("migrating")
|
|| j.has_key("migrating")
|
||||||
|| j.has_key("changing")
|
|| j.has_key("changing")
|
||||||
|| j.has_key("move")
|
|| j.has_key("move")
|
||||||
|
|
@ -105,7 +105,7 @@ impl UserProfile {
|
||||||
log_message(format!("[INFO] Migration triggered for {}", up.username));
|
log_message(format!("[INFO] Migration triggered for {}", up.username));
|
||||||
user_manager::set_unique(true);
|
user_manager::set_unique(true);
|
||||||
}
|
}
|
||||||
}
|
} */
|
||||||
|
|
||||||
Some(up)
|
Some(up)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,14 @@ impl ConfigUtil {
|
||||||
self.config["port"].as_u16().unwrap_or(1984)
|
self.config["port"].as_u16().unwrap_or(1984)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_public_key(&self) -> Option<String> {
|
||||||
|
self.config["public_key"].as_str().map(String::from)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_private_key(&self) -> Option<String> {
|
||||||
|
self.config["private_key"].as_str().map(String::from)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get(&self, key: &str) -> &JsonValue {
|
pub fn get(&self, key: &str) -> &JsonValue {
|
||||||
&self.config[key]
|
&self.config[key]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use rand_core::RngCore;
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
use x448::{PublicKey, Secret, SharedSecret};
|
use x448::{PublicKey, Secret, SharedSecret};
|
||||||
|
|
||||||
/// Errors for crypto operations
|
/// Errors for crypto opertions
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum CryptoError {
|
pub enum CryptoError {
|
||||||
Base64Decode(base64::DecodeError),
|
Base64Decode(base64::DecodeError),
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
pub mod chat_files;
|
pub mod chat_files;
|
||||||
pub mod chats_util;
|
pub mod chats_util;
|
||||||
pub mod config_util;
|
pub mod config_util;
|
||||||
|
pub mod crypto_helper;
|
||||||
pub mod file_util;
|
pub mod file_util;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue