feat: more refactoring (broken)

This commit is contained in:
DecDuck
2025-09-16 15:09:43 +10:00
parent ab219670dc
commit 43b56462d6
28 changed files with 429 additions and 155 deletions
+1 -1
View File
@@ -6,7 +6,7 @@ edition = "2024"
[dependencies]
bitcode = "0.6.7"
chrono = "0.4.42"
drop-database = { path = "../drop-database" }
drop-consts = { path = "../drop-consts" }
drop-errors = { path = "../drop-errors" }
droplet-rs = "0.7.3"
gethostname = "1.0.2"
+35 -46
View File
@@ -1,15 +1,16 @@
use std::{collections::HashMap, env, sync::Mutex};
use chrono::Utc;
use drop_database::{borrow_db_checked, borrow_db_mut_checked, models::data::DatabaseAuth, runtime_models::User};
use drop_errors::{drop_server_error::DropServerError, remote_access_error::RemoteAccessError};
use drop_errors::{drop_server_error::ServerError, remote_access_error::RemoteAccessError};
use droplet_rs::ssl::sign_nonce;
use gethostname::gethostname;
use log::{debug, error, warn};
use serde::{Deserialize, Serialize};
use url::Url;
use crate::{requests::make_authenticated_get, utils::{DROP_CLIENT_ASYNC, DROP_CLIENT_SYNC}};
use crate::{
requests::make_authenticated_get, utils::{DROP_CLIENT_ASYNC, DROP_CLIENT_SYNC}, DropRemoteAuth, DropRemoteContext
};
use super::requests::generate_url;
@@ -41,23 +42,24 @@ struct HandshakeResponse {
id: String,
}
pub fn generate_authorization_header() -> String {
let certs = {
let db = borrow_db_checked();
db.auth.clone().unwrap()
pub fn generate_authorization_header(context: &DropRemoteContext) -> String {
let auth = if let Some(auth) = &context.auth {
auth
} else {
return "".to_owned();
};
let nonce = Utc::now().timestamp_millis().to_string();
let signature = sign_nonce(certs.private, nonce.clone()).unwrap();
let signature = sign_nonce(auth.private.clone(), nonce.clone()).unwrap();
format!("Nonce {} {} {}", certs.client_id, nonce, signature)
format!("Nonce {} {} {}", auth.client_id, nonce, signature)
}
pub async fn fetch_user() -> Result<User, RemoteAccessError> {
let response = make_authenticated_get(generate_url(&["/api/v1/client/user"], &[])?).await?;
pub async fn fetch_user(context: &DropRemoteContext) -> Result<Vec<u8>, RemoteAccessError> {
let response =
make_authenticated_get(context, generate_url(context, &["/api/v1/client/user"], &[])?).await?;
if response.status() != 200 {
let err: DropServerError = response.json().await?;
let err: ServerError = response.json().await?;
warn!("{err:?}");
if err.status_message == "Nonce expired" {
@@ -68,25 +70,24 @@ pub async fn fetch_user() -> Result<User, RemoteAccessError> {
}
response
.json::<User>()
.bytes()
.await
.map_err(std::convert::Into::into)
.map(|v| v.to_vec())
}
pub async fn recieve_handshake_logic(path: String) -> Result<(), RemoteAccessError> {
pub async fn recieve_handshake_logic(
context: &mut DropRemoteContext,
path: String,
) -> Result<(), RemoteAccessError> {
let path_chunks: Vec<&str> = path.split('/').collect();
if path_chunks.len() != 3 {
// app.emit("auth/failed", ()).unwrap();
// app.emit("auth/failed", ()).unwrap();
return Err(RemoteAccessError::HandshakeFailed(
"failed to parse token".to_string(),
));
}
let base_url = {
let handle = borrow_db_checked();
Url::parse(handle.base_url.as_str())?
};
let client_id = path_chunks.get(1).unwrap();
let token = path_chunks.get(2).unwrap();
let body = HandshakeRequestBody {
@@ -94,7 +95,7 @@ pub async fn recieve_handshake_logic(path: String) -> Result<(), RemoteAccessErr
token: (*token).to_string(),
};
let endpoint = base_url.join("/api/v1/client/auth/handshake")?;
let endpoint = generate_url(context, &["/api/v1/client/auth/handshake"], &[])?;
let client = DROP_CLIENT_ASYNC.clone();
let response = client.post(endpoint).json(&body).send().await?;
debug!("handshake responsded with {}", response.status().as_u16());
@@ -103,20 +104,10 @@ pub async fn recieve_handshake_logic(path: String) -> Result<(), RemoteAccessErr
}
let response_struct: HandshakeResponse = response.json().await?;
{
let mut handle = borrow_db_mut_checked();
handle.auth = Some(DatabaseAuth {
private: response_struct.private,
cert: response_struct.certificate,
client_id: response_struct.id,
web_token: None, // gets created later
});
}
let web_token = {
let header = generate_authorization_header();
let header = generate_authorization_header(context);
let token = client
.post(base_url.join("/api/v1/client/user/webtoken").unwrap())
.post(generate_url(context, &["/api/v1/client/user/webtoken"], &[])?)
.header("Authorization", header)
.send()
.await
@@ -125,22 +116,20 @@ pub async fn recieve_handshake_logic(path: String) -> Result<(), RemoteAccessErr
token.text().await.unwrap()
};
let mut handle = borrow_db_mut_checked();
let mut_auth = handle.auth.as_mut().unwrap();
mut_auth.web_token = Some(web_token);
context.auth = Some(DropRemoteAuth {
private: response_struct.private,
cert: response_struct.certificate,
client_id: response_struct.id,
web_token: web_token,
});
Ok(())
}
pub fn auth_initiate_logic(mode: String) -> Result<String, RemoteAccessError> {
let base_url = {
let db_lock = borrow_db_checked();
Url::parse(&db_lock.base_url.clone())?
};
pub fn auth_initiate_logic(context: &DropRemoteContext, mode: String) -> Result<String, RemoteAccessError> {
let hostname = gethostname();
let endpoint = base_url.join("/api/v1/client/auth/initiate")?;
let endpoint = generate_url(context, &["/api/v1/client/auth/initiate"], &[])?;
let body = InitiateRequestBody {
name: format!("{} (Desktop)", hostname.into_string().unwrap()),
platform: env::consts::OS.to_string(),
@@ -155,7 +144,7 @@ pub fn auth_initiate_logic(mode: String) -> Result<String, RemoteAccessError> {
let response = client.post(endpoint.to_string()).json(&body).send()?;
if response.status() != 200 {
let data: DropServerError = response.json()?;
let data: ServerError = response.json()?;
error!("could not start handshake: {}", data.status_message);
return Err(RemoteAccessError::HandshakeFailed(data.status_message));
@@ -164,4 +153,4 @@ pub fn auth_initiate_logic(mode: String) -> Result<String, RemoteAccessError> {
let response = response.text()?;
Ok(response)
}
}
+7 -10
View File
@@ -6,7 +6,7 @@ use std::{
};
use bitcode::{Decode, DecodeOwned, Encode};
use drop_database::{borrow_db_checked, models::data::Database};
use drop_consts::CACHE_DIR;
use drop_errors::remote_access_error::RemoteAccessError;
use http::{Response, header::CONTENT_TYPE, response::Builder as ResponseBuilder};
@@ -57,36 +57,33 @@ fn delete_sync(base: &Path, key: &str) -> io::Result<()> {
}
pub fn cache_object<D: Encode>(key: &str, data: &D) -> Result<(), RemoteAccessError> {
cache_object_db(key, data, &borrow_db_checked())
cache_object_db(key, data)
}
pub fn cache_object_db<D: Encode>(
key: &str,
data: &D,
database: &Database,
) -> Result<(), RemoteAccessError> {
let bytes = bitcode::encode(data);
write_sync(&database.cache_dir, key, bytes).map_err(RemoteAccessError::Cache)
write_sync(&CACHE_DIR, key, bytes).map_err(RemoteAccessError::Cache)
}
pub fn get_cached_object<D: Encode + DecodeOwned>(key: &str) -> Result<D, RemoteAccessError> {
get_cached_object_db::<D>(key, &borrow_db_checked())
get_cached_object_db::<D>(key)
}
pub fn get_cached_object_db<D: DecodeOwned>(
key: &str,
db: &Database,
) -> Result<D, RemoteAccessError> {
let bytes = read_sync(&db.cache_dir, key).map_err(RemoteAccessError::Cache)?;
let bytes = read_sync(&CACHE_DIR, key).map_err(RemoteAccessError::Cache)?;
let data =
bitcode::decode::<D>(&bytes).map_err(|e| RemoteAccessError::Cache(io::Error::other(e)))?;
Ok(data)
}
pub fn clear_cached_object(key: &str) -> Result<(), RemoteAccessError> {
clear_cached_object_db(key, &borrow_db_checked())
clear_cached_object_db(key)
}
pub fn clear_cached_object_db(
key: &str,
db: &Database,
) -> Result<(), RemoteAccessError> {
delete_sync(&db.cache_dir, key).map_err(RemoteAccessError::Cache)?;
delete_sync(&CACHE_DIR, key).map_err(RemoteAccessError::Cache)?;
Ok(())
}
+5 -6
View File
@@ -1,17 +1,16 @@
use drop_database::{db::DatabaseImpls as _, DB};
use http::{header::CONTENT_TYPE, response::Builder as ResponseBuilder};
use http::{header::CONTENT_TYPE, response::Builder as ResponseBuilder, Request};
use log::warn;
use tauri::UriSchemeResponder;
use crate::utils::DROP_CLIENT_ASYNC;
use crate::{requests::generate_url, utils::DROP_CLIENT_ASYNC, DropRemoteContext};
use super::{
auth::generate_authorization_header,
cache::{ObjectCache, cache_object, get_cached_object},
};
pub async fn fetch_object(request: http::Request<Vec<u8>>, responder: UriSchemeResponder) {
pub async fn fetch_object(context: &DropRemoteContext, request: Request<Vec<u8>>, responder: UriSchemeResponder) {
// Drop leading /
let object_id = &request.uri().path()[1..];
@@ -23,9 +22,9 @@ pub async fn fetch_object(request: http::Request<Vec<u8>>, responder: UriSchemeR
return;
}
let header = generate_authorization_header();
let header = generate_authorization_header(context);
let client = DROP_CLIENT_ASYNC.clone();
let url = format!("{}api/v1/client/object/{object_id}", DB.fetch_base_url());
let url = generate_url(context, &["/api/v1/client/object", object_id], &[]).expect("failed to generated object url");
let response = client.get(url).header("Authorization", header).send().await;
if response.is_err() {
+24
View File
@@ -1,5 +1,29 @@
use serde::{Deserialize, Serialize};
use url::Url;
pub mod auth;
pub mod cache;
pub mod fetch_object;
pub mod requests;
pub mod utils;
#[derive(Serialize, Deserialize, Clone)]
struct DropRemoteAuth {
private: String,
cert: String,
client_id: String,
web_token: String,
}
#[derive(Serialize, Deserialize, Clone)]
pub struct DropRemoteContext {
base_url: Url,
auth: Option<DropRemoteAuth>,
}
impl DropRemoteContext {
pub fn new(base_url: Url) -> Self {
DropRemoteContext { base_url, auth: None }
}
}
+5 -5
View File
@@ -1,14 +1,14 @@
use drop_database::{db::DatabaseImpls as _, DB};
use drop_errors::remote_access_error::RemoteAccessError;
use url::Url;
use crate::{auth::generate_authorization_header, utils::DROP_CLIENT_ASYNC};
use crate::{auth::generate_authorization_header, utils::DROP_CLIENT_ASYNC, DropRemoteContext};
pub fn generate_url<T: AsRef<str>>(
context: &DropRemoteContext,
path_components: &[T],
query: &[(T, T)],
) -> Result<Url, RemoteAccessError> {
let mut base_url = DB.fetch_base_url();
let mut base_url = context.base_url.clone();
for endpoint in path_components {
base_url = base_url.join(endpoint.as_ref())?;
}
@@ -21,10 +21,10 @@ pub fn generate_url<T: AsRef<str>>(
Ok(base_url)
}
pub async fn make_authenticated_get(url: Url) -> Result<reqwest::Response, reqwest::Error> {
pub async fn make_authenticated_get(context: &DropRemoteContext, url: Url) -> Result<reqwest::Response, reqwest::Error> {
DROP_CLIENT_ASYNC
.get(url)
.header("Authorization", generate_authorization_header())
.header("Authorization", generate_authorization_header(context))
.send()
.await
}
+1 -2
View File
@@ -4,10 +4,9 @@ use std::{
sync::LazyLock,
};
use drop_database::db::DATA_ROOT_DIR;
use drop_consts::DATA_ROOT_DIR;
use log::{debug, info};
use reqwest::Certificate;
use serde::Deserialize;
static DROP_CERT_BUNDLE: LazyLock<Vec<Certificate>> = LazyLock::new(fetch_certificates);
pub static DROP_CLIENT_SYNC: LazyLock<reqwest::blocking::Client> = LazyLock::new(get_client_sync);