mirror of
https://github.com/Drop-OSS/drop-app.git
synced 2025-11-14 16:51:18 +10:00
chore: Remove unwraps from auth.rs
Signed-off-by: quexeky <git@quexeky.dev>
This commit is contained in:
@ -12,7 +12,10 @@ use crate::{
|
|||||||
app_emit, database::{
|
app_emit, database::{
|
||||||
db::{borrow_db_checked, borrow_db_mut_checked},
|
db::{borrow_db_checked, borrow_db_mut_checked},
|
||||||
models::data::DatabaseAuth,
|
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::{
|
use super::{
|
||||||
@ -51,12 +54,13 @@ struct HandshakeResponse {
|
|||||||
pub fn generate_authorization_header() -> String {
|
pub fn generate_authorization_header() -> String {
|
||||||
let certs = {
|
let certs = {
|
||||||
let db = borrow_db_checked();
|
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 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)
|
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())?
|
Url::parse(handle.base_url.as_str())?
|
||||||
};
|
};
|
||||||
|
|
||||||
let client_id = path_chunks.get(1).unwrap();
|
let client_id = path_chunks
|
||||||
let token = path_chunks.get(2).unwrap();
|
.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 {
|
let body = HandshakeRequestBody {
|
||||||
client_id: (*client_id).to_string(),
|
client_id: (client_id).to_string(),
|
||||||
token: (*token).to_string(),
|
token: (token).to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let endpoint = base_url.join("/api/v1/client/auth/handshake")?;
|
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 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();
|
let mut handle = borrow_db_mut_checked();
|
||||||
handle.auth = Some(DatabaseAuth {
|
handle.auth = Some(DatabaseAuth {
|
||||||
private: response_struct.private,
|
private: response_struct.private,
|
||||||
cert: response_struct.certificate,
|
cert: response_struct.certificate,
|
||||||
client_id: response_struct.id,
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -154,7 +155,7 @@ pub async fn recieve_handshake(app: AppHandle, path: String) {
|
|||||||
|
|
||||||
let (app_status, user) = setup().await;
|
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.status = app_status;
|
||||||
state_lock.user = user;
|
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 endpoint = base_url.join("/api/v1/client/auth/initiate")?;
|
||||||
let body = InitiateRequestBody {
|
let body = InitiateRequestBody {
|
||||||
name: format!("{} (Desktop)", hostname.into_string().unwrap()),
|
name: format!("{} (Desktop)", hostname.display()),
|
||||||
platform: env::consts::OS.to_string(),
|
platform: env::consts::OS.to_string(),
|
||||||
capabilities: HashMap::from([
|
capabilities: HashMap::from([
|
||||||
("peerAPI".to_owned(), CapabilityConfiguration {}),
|
("peerAPI".to_owned(), CapabilityConfiguration {}),
|
||||||
@ -208,12 +209,14 @@ pub async fn setup() -> (AppStatus, Option<User>) {
|
|||||||
let user_result = match fetch_user().await {
|
let user_result = match fetch_user().await {
|
||||||
Ok(data) => data,
|
Ok(data) => data,
|
||||||
Err(RemoteAccessError::FetchError(_)) => {
|
Err(RemoteAccessError::FetchError(_)) => {
|
||||||
let user = get_cached_object::<User>("user").unwrap();
|
let user = get_cached_object::<User>("user").ok();
|
||||||
return (AppStatus::Offline, Some(user));
|
return (AppStatus::Offline, user);
|
||||||
}
|
}
|
||||||
Err(_) => return (AppStatus::SignedInNeedsReauth, None),
|
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));
|
return (AppStatus::SignedIn, Some(user_result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,7 @@ use crate::{
|
|||||||
auth::generate_authorization_header,
|
auth::generate_authorization_header,
|
||||||
requests::generate_url,
|
requests::generate_url,
|
||||||
utils::{DROP_CLIENT_SYNC, DROP_CLIENT_WS_CLIENT},
|
utils::{DROP_CLIENT_SYNC, DROP_CLIENT_WS_CLIENT},
|
||||||
}, AppState, AppStatus
|
}, state_lock, utils::webbrowser_open::webbrowser_open, AppState, AppStatus
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
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)?
|
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())
|
Ok(url.to_string())
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ pub fn sign_out(app: AppHandle) {
|
|||||||
// Update app state
|
// Update app state
|
||||||
{
|
{
|
||||||
let app_state = app.state::<Mutex<AppState>>();
|
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.status = AppStatus::SignedOut;
|
||||||
app_state_handle.user = None;
|
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<(), ()> {
|
pub async fn retry_connect(state: tauri::State<'_, Mutex<AppState<'_>>>) -> Result<(), ()> {
|
||||||
let (app_status, user) = setup().await;
|
let (app_status, user) = setup().await;
|
||||||
|
|
||||||
let mut guard = state.lock().unwrap();
|
let mut guard = state_lock!(state);
|
||||||
guard.status = app_status;
|
guard.status = app_status;
|
||||||
guard.user = user;
|
guard.user = user;
|
||||||
drop(guard);
|
drop(guard);
|
||||||
@ -106,7 +106,7 @@ pub fn auth_initiate() -> Result<(), RemoteAccessError> {
|
|||||||
let complete_redir_url = base_url.join(&redir_url)?;
|
let complete_redir_url = base_url.join(&redir_url)?;
|
||||||
|
|
||||||
debug!("opening web browser to continue authentication");
|
debug!("opening web browser to continue authentication");
|
||||||
webbrowser::open(complete_redir_url.as_ref()).unwrap();
|
webbrowser_open(complete_redir_url.as_ref());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,6 +124,7 @@ pub fn auth_initiate_code(app: AppHandle) -> Result<String, RemoteAccessError> {
|
|||||||
Url::parse(&db_lock.base_url.clone())?
|
Url::parse(&db_lock.base_url.clone())?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
let code = auth_initiate_logic("code".to_string())?;
|
let code = auth_initiate_logic("code".to_string())?;
|
||||||
let header_code = code.clone();
|
let header_code = code.clone();
|
||||||
|
|
||||||
|
|||||||
@ -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 url = format!("{}api/v1/client/object/{object_id}", DB.fetch_base_url());
|
||||||
let response = client.get(url).header("Authorization", header).send().await;
|
let response = client.get(url).header("Authorization", header).send().await;
|
||||||
|
|
||||||
return match response {
|
match response {
|
||||||
Ok(r) => {
|
Ok(r) => {
|
||||||
let resp_builder = ResponseBuilder::new().header(
|
let resp_builder = ResponseBuilder::new().header(
|
||||||
CONTENT_TYPE,
|
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");
|
.expect("Failed to create cached object");
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(resp.into())
|
Ok(resp)
|
||||||
}
|
}
|
||||||
Err(e) => {
|
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 {
|
match cache_result {
|
||||||
Ok(cache_result) => Ok(cache_result.into()),
|
Ok(cache_result) => Ok(cache_result.into()),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use http::{uri::PathAndQuery, Request, Response, StatusCode, Uri};
|
use http::{uri::PathAndQuery, Request, Response, StatusCode, Uri};
|
||||||
use log::warn;
|
use log::{error, warn};
|
||||||
use tauri::UriSchemeResponder;
|
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) {
|
pub async fn handle_server_proto_offline_wrapper(request: Request<Vec<u8>>, responder: UriSchemeResponder) {
|
||||||
responder.respond(match handle_server_proto_offline(request).await {
|
responder.respond(match handle_server_proto_offline(request).await {
|
||||||
Ok(res) => res,
|
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> {
|
async fn handle_server_proto(request: Request<Vec<u8>>) -> Result<Response<Vec<u8>>, StatusCode> {
|
||||||
let db_handle = borrow_db_checked();
|
let db_handle = borrow_db_checked();
|
||||||
let web_token = match &db_handle.auth.as_ref().unwrap().web_token {
|
let auth = match db_handle.auth.as_ref() {
|
||||||
Some(e) => e,
|
Some(auth) => auth,
|
||||||
None => return Err(StatusCode::BAD_REQUEST),
|
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");
|
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"));
|
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.authority = remote_uri.authority().cloned();
|
||||||
new_uri.scheme = remote_uri.scheme().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"];
|
let whitelist_prefix = ["/store", "/api", "/_", "/fonts"];
|
||||||
|
|
||||||
if whitelist_prefix.iter().all(|f| !path.starts_with(f)) {
|
if whitelist_prefix.iter().all(|f| !path.starts_with(f)) {
|
||||||
return match webbrowser::open(&new_uri.to_string()) {
|
webbrowser_open(new_uri.to_string());
|
||||||
Ok(_) => Ok(Response::new(Vec::new())),
|
return 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()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let client = DROP_CLIENT_SYNC.clone();
|
let client = DROP_CLIENT_SYNC.clone();
|
||||||
|
|||||||
@ -1,11 +1,6 @@
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! app_emit {
|
macro_rules! app_emit {
|
||||||
($app:expr, $event:expr, $p:expr) => {
|
($app:expr, $event:expr, $p:expr) => {
|
||||||
match $app.emit($event, $p) {
|
$app.emit($event, $p).expect(&format!("Failed to emit event {}", $event));
|
||||||
Ok(_) => (),
|
|
||||||
Err(e) => {
|
|
||||||
log::error!("Failed to emit event {} with error {}", $event, e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -1,2 +1,3 @@
|
|||||||
mod app_emit;
|
mod app_emit;
|
||||||
mod state_lock;
|
mod state_lock;
|
||||||
|
pub mod webbrowser_open;
|
||||||
|
|||||||
7
src-tauri/src/utils/webbrowser_open.rs
Normal file
7
src-tauri/src/utils/webbrowser_open.rs
Normal 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);
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user