chore: Remove unwraps from auth.rs

Signed-off-by: quexeky <git@quexeky.dev>
This commit is contained in:
quexeky
2025-09-09 16:13:16 +10:00
parent ddde547c08
commit 83dc773b10
7 changed files with 67 additions and 57 deletions

View File

@ -12,7 +12,10 @@ use crate::{
app_emit, database::{
db::{borrow_db_checked, borrow_db_mut_checked},
models::data::DatabaseAuth,
}, error::{drop_server_error::DropServerError, remote_access_error::RemoteAccessError}, remote::{requests::make_authenticated_get, utils::{DROP_CLIENT_ASYNC, DROP_CLIENT_SYNC}}, AppState, AppStatus, User
}, error::{drop_server_error::DropServerError, remote_access_error::RemoteAccessError}, remote::{
requests::make_authenticated_get,
utils::{DROP_CLIENT_ASYNC, DROP_CLIENT_SYNC},
}, state_lock, AppState, AppStatus, User
};
use super::{
@ -51,12 +54,13 @@ struct HandshakeResponse {
pub fn generate_authorization_header() -> String {
let certs = {
let db = borrow_db_checked();
db.auth.clone().unwrap()
db.auth.clone().expect("Authorisation not initialised")
};
let nonce = Utc::now().timestamp_millis().to_string();
let signature = sign_nonce(certs.private, nonce.clone()).unwrap();
let signature =
sign_nonce(certs.private, nonce.clone()).expect("Failed to generate authorisation header");
format!("Nonce {} {} {}", certs.client_id, nonce, signature)
}
@ -94,11 +98,15 @@ async fn recieve_handshake_logic(app: &AppHandle, path: String) -> Result<(), Re
Url::parse(handle.base_url.as_str())?
};
let client_id = path_chunks.get(1).unwrap();
let token = path_chunks.get(2).unwrap();
let client_id = path_chunks
.get(1)
.expect("Failed to get client id from path chunks");
let token = path_chunks
.get(2)
.expect("Failed to get token from path chunks");
let body = HandshakeRequestBody {
client_id: (*client_id).to_string(),
token: (*token).to_string(),
client_id: (client_id).to_string(),
token: (token).to_string(),
};
let endpoint = base_url.join("/api/v1/client/auth/handshake")?;
@ -110,31 +118,24 @@ async fn recieve_handshake_logic(app: &AppHandle, path: String) -> Result<(), Re
}
let response_struct: HandshakeResponse = response.json().await?;
{
let web_token = {
let header = generate_authorization_header();
let token = client
.post(base_url.join("/api/v1/client/user/webtoken")?)
.header("Authorization", header)
.send()
.await?;
token.text().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
web_token: Some(web_token), // gets created later
});
}
let web_token = {
let header = generate_authorization_header();
let token = client
.post(base_url.join("/api/v1/client/user/webtoken").unwrap())
.header("Authorization", header)
.send()
.await
.unwrap();
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);
Ok(())
}
@ -154,7 +155,7 @@ pub async fn recieve_handshake(app: AppHandle, path: String) {
let (app_status, user) = setup().await;
let mut state_lock = app_state.lock().unwrap();
let mut state_lock = state_lock!(app_state);
state_lock.status = app_status;
state_lock.user = user;
@ -174,7 +175,7 @@ pub fn auth_initiate_logic(mode: String) -> Result<String, RemoteAccessError> {
let endpoint = base_url.join("/api/v1/client/auth/initiate")?;
let body = InitiateRequestBody {
name: format!("{} (Desktop)", hostname.into_string().unwrap()),
name: format!("{} (Desktop)", hostname.display()),
platform: env::consts::OS.to_string(),
capabilities: HashMap::from([
("peerAPI".to_owned(), CapabilityConfiguration {}),
@ -208,12 +209,14 @@ pub async fn setup() -> (AppStatus, Option<User>) {
let user_result = match fetch_user().await {
Ok(data) => data,
Err(RemoteAccessError::FetchError(_)) => {
let user = get_cached_object::<User>("user").unwrap();
return (AppStatus::Offline, Some(user));
let user = get_cached_object::<User>("user").ok();
return (AppStatus::Offline, user);
}
Err(_) => return (AppStatus::SignedInNeedsReauth, None),
};
cache_object("user", &user_result).unwrap();
if let Err(e) = cache_object("user", &user_result) {
warn!("Could not cache user object with error {e}");
}
return (AppStatus::SignedIn, Some(user_result));
}

View File

@ -12,7 +12,7 @@ use crate::{
auth::generate_authorization_header,
requests::generate_url,
utils::{DROP_CLIENT_SYNC, DROP_CLIENT_WS_CLIENT},
}, AppState, AppStatus
}, state_lock, utils::webbrowser_open::webbrowser_open, AppState, AppStatus
};
use super::{
@ -37,7 +37,7 @@ pub fn gen_drop_url(path: String) -> Result<String, RemoteAccessError> {
Url::parse(&handle.base_url).map_err(RemoteAccessError::ParsingError)?
};
let url = base_url.join(&path).unwrap();
let url = base_url.join(&path)?;
Ok(url.to_string())
}
@ -74,7 +74,7 @@ pub fn sign_out(app: AppHandle) {
// Update app state
{
let app_state = app.state::<Mutex<AppState>>();
let mut app_state_handle = app_state.lock().unwrap();
let mut app_state_handle = state_lock!(app_state);
app_state_handle.status = AppStatus::SignedOut;
app_state_handle.user = None;
}
@ -87,7 +87,7 @@ pub fn sign_out(app: AppHandle) {
pub async fn retry_connect(state: tauri::State<'_, Mutex<AppState<'_>>>) -> Result<(), ()> {
let (app_status, user) = setup().await;
let mut guard = state.lock().unwrap();
let mut guard = state_lock!(state);
guard.status = app_status;
guard.user = user;
drop(guard);
@ -106,7 +106,7 @@ pub fn auth_initiate() -> Result<(), RemoteAccessError> {
let complete_redir_url = base_url.join(&redir_url)?;
debug!("opening web browser to continue authentication");
webbrowser::open(complete_redir_url.as_ref()).unwrap();
webbrowser_open(complete_redir_url.as_ref());
Ok(())
}
@ -124,6 +124,7 @@ pub fn auth_initiate_code(app: AppHandle) -> Result<String, RemoteAccessError> {
Url::parse(&db_lock.base_url.clone())?
};
let code = auth_initiate_logic("code".to_string())?;
let header_code = code.clone();

View File

@ -36,7 +36,7 @@ pub async fn fetch_object(request: http::Request<Vec<u8>>) -> Result<Response<Ve
let url = format!("{}api/v1/client/object/{object_id}", DB.fetch_base_url());
let response = client.get(url).header("Authorization", header).send().await;
return match response {
match response {
Ok(r) => {
let resp_builder = ResponseBuilder::new().header(
CONTENT_TYPE,
@ -59,10 +59,10 @@ pub async fn fetch_object(request: http::Request<Vec<u8>>) -> Result<Response<Ve
.expect("Failed to create cached object");
}
Ok(resp.into())
Ok(resp)
}
Err(e) => {
debug!("Object fetch failed with error {}. Attempting to download from cache", e);
debug!("Object fetch failed with error {e}. Attempting to download from cache");
match cache_result {
Ok(cache_result) => Ok(cache_result.into()),
Err(e) => {

View File

@ -1,15 +1,15 @@
use std::str::FromStr;
use http::{uri::PathAndQuery, Request, Response, StatusCode, Uri};
use log::warn;
use log::{error, warn};
use tauri::UriSchemeResponder;
use crate::{database::db::borrow_db_checked, remote::utils::DROP_CLIENT_SYNC};
use crate::{database::db::borrow_db_checked, remote::utils::DROP_CLIENT_SYNC, utils::webbrowser_open::webbrowser_open};
pub async fn handle_server_proto_offline_wrapper(request: Request<Vec<u8>>, responder: UriSchemeResponder) {
responder.respond(match handle_server_proto_offline(request).await {
Ok(res) => res,
Err(e) => unreachable!()
Err(_) => unreachable!()
});
}
@ -33,9 +33,16 @@ pub async fn handle_server_proto_wrapper(request: Request<Vec<u8>>, responder: U
async fn handle_server_proto(request: Request<Vec<u8>>) -> Result<Response<Vec<u8>>, StatusCode> {
let db_handle = borrow_db_checked();
let web_token = match &db_handle.auth.as_ref().unwrap().web_token {
Some(e) => e,
None => return Err(StatusCode::BAD_REQUEST),
let auth = match db_handle.auth.as_ref() {
Some(auth) => auth,
None => {
error!("Could not find auth in database");
return Err(StatusCode::UNAUTHORIZED)
}
};
let web_token = match &auth.web_token {
Some(token) => token,
None => return Err(StatusCode::UNAUTHORIZED),
};
let remote_uri = db_handle.base_url.parse::<Uri>().expect("Failed to parse base url");
@ -46,18 +53,14 @@ async fn handle_server_proto(request: Request<Vec<u8>>) -> Result<Response<Vec<u
Some(PathAndQuery::from_str(&format!("{path}?noWrapper=true")).expect("Failed to parse request path in proto"));
new_uri.authority = remote_uri.authority().cloned();
new_uri.scheme = remote_uri.scheme().cloned();
let new_uri = Uri::from_parts(new_uri).expect(&format!("Failed to build new uri from parts"));
let err_msg = &format!("Failed to build new uri from parts {new_uri:?}");
let new_uri = Uri::from_parts(new_uri).expect(err_msg);
let whitelist_prefix = ["/store", "/api", "/_", "/fonts"];
if whitelist_prefix.iter().all(|f| !path.starts_with(f)) {
return match webbrowser::open(&new_uri.to_string()) {
Ok(_) => Ok(Response::new(Vec::new())),
Err(e) => {
warn!("Could not open web browser to link {new_uri} with error {e}");
Ok(Response::new(Vec::new()))
}
}
webbrowser_open(new_uri.to_string());
return Ok(Response::new(Vec::new()))
}
let client = DROP_CLIENT_SYNC.clone();

View File

@ -1,11 +1,6 @@
#[macro_export]
macro_rules! app_emit {
($app:expr, $event:expr, $p:expr) => {
match $app.emit($event, $p) {
Ok(_) => (),
Err(e) => {
log::error!("Failed to emit event {} with error {}", $event, e);
}
};
$app.emit($event, $p).expect(&format!("Failed to emit event {}", $event));
};
}

View File

@ -1,2 +1,3 @@
mod app_emit;
mod state_lock;
pub mod webbrowser_open;

View File

@ -0,0 +1,7 @@
use log::warn;
pub fn webbrowser_open<T: AsRef<str>>(url: T) {
if let Err(e) = webbrowser::open(url.as_ref()) {
warn!("Could not open web browser to url {} with error {}", url.as_ref(), e);
};
}