From 565a3edf30613f178894e36991276417f4686afc Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Tue, 5 Nov 2024 18:59:11 +0100 Subject: [PATCH] Refactored api token --- runtime/src/api_token.rs | 68 ++++++++++++++++++++++++++++++++++++++++ runtime/src/lib.rs | 3 +- runtime/src/main.rs | 61 ----------------------------------- 3 files changed, 70 insertions(+), 62 deletions(-) create mode 100644 runtime/src/api_token.rs diff --git a/runtime/src/api_token.rs b/runtime/src/api_token.rs new file mode 100644 index 00000000..6dd805c1 --- /dev/null +++ b/runtime/src/api_token.rs @@ -0,0 +1,68 @@ +use once_cell::sync::Lazy; +use rand::{RngCore, SeedableRng}; +use rocket::http::Status; +use rocket::Request; +use rocket::request::FromRequest; + +pub static API_TOKEN: Lazy = Lazy::new(|| { + let mut token = [0u8; 32]; + let mut rng = rand_chacha::ChaChaRng::from_entropy(); + rng.fill_bytes(&mut token); + APIToken::from_bytes(token.to_vec()) +}); + +pub struct APIToken{ + hex_text: String, +} + +impl APIToken { + fn from_bytes(bytes: Vec) -> Self { + APIToken { + hex_text: bytes.iter().fold(String::new(), |mut result, byte| { + result.push_str(&format!("{:02x}", byte)); + result + }), + } + } + + fn from_hex_text(hex_text: &str) -> Self { + APIToken { + hex_text: hex_text.to_string(), + } + } + + pub(crate) fn to_hex_text(&self) -> &str { + self.hex_text.as_str() + } + + fn validate(&self, received_token: &Self) -> bool { + received_token.to_hex_text() == self.to_hex_text() + } +} + +#[rocket::async_trait] +impl<'r> FromRequest<'r> for APIToken { + type Error = APITokenError; + + async fn from_request(request: &'r Request<'_>) -> RequestOutcome { + let token = request.headers().get_one("token"); + match token { + Some(token) => { + let received_token = APIToken::from_hex_text(token); + if API_TOKEN.validate(&received_token) { + RequestOutcome::Success(received_token) + } else { + RequestOutcome::Error((Status::Unauthorized, APITokenError::Invalid)) + } + } + + None => RequestOutcome::Error((Status::Unauthorized, APITokenError::Missing)), + } + } +} + +#[derive(Debug)] +enum APITokenError { + Missing, + Invalid, +} \ No newline at end of file diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 25001603..2fce4733 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -1,4 +1,5 @@ pub mod encryption; pub mod log; pub mod environment; -pub mod network; \ No newline at end of file +pub mod network; +pub mod api_token; \ No newline at end of file diff --git a/runtime/src/main.rs b/runtime/src/main.rs index 59ac51aa..9a2a6169 100644 --- a/runtime/src/main.rs +++ b/runtime/src/main.rs @@ -64,13 +64,6 @@ static MAIN_WINDOW: Lazy>> = Lazy::new(|| Mutex::new(None)) // The update response coming from the Tauri updater. static CHECK_UPDATE_RESPONSE: Lazy>>> = Lazy::new(|| Mutex::new(None)); -static API_TOKEN: Lazy = Lazy::new(|| { - let mut token = [0u8; 32]; - let mut rng = rand_chacha::ChaChaRng::from_entropy(); - rng.fill_bytes(&mut token); - APIToken::from_bytes(token.to_vec()) -}); - static DATA_DIRECTORY: OnceLock = OnceLock::new(); static CONFIG_DIRECTORY: OnceLock = OnceLock::new(); @@ -382,62 +375,8 @@ async fn main() { } } -struct APIToken{ - hex_text: String, -} - -impl APIToken { - fn from_bytes(bytes: Vec) -> Self { - APIToken { - hex_text: bytes.iter().fold(String::new(), |mut result, byte| { - result.push_str(&format!("{:02x}", byte)); - result - }), - } } - fn from_hex_text(hex_text: &str) -> Self { - APIToken { - hex_text: hex_text.to_string(), - } - } - - fn to_hex_text(&self) -> &str { - self.hex_text.as_str() - } - - fn validate(&self, received_token: &Self) -> bool { - received_token.to_hex_text() == self.to_hex_text() - } -} - -#[rocket::async_trait] -impl<'r> FromRequest<'r> for APIToken { - type Error = APITokenError; - - async fn from_request(request: &'r Request<'_>) -> RequestOutcome { - let token = request.headers().get_one("token"); - match token { - Some(token) => { - let received_token = APIToken::from_hex_text(token); - if API_TOKEN.validate(&received_token) { - RequestOutcome::Success(received_token) - } else { - RequestOutcome::Error((Status::Unauthorized, APITokenError::Invalid)) - } - } - - None => RequestOutcome::Error((Status::Unauthorized, APITokenError::Missing)), - } - } -} - -#[derive(Debug)] -enum APITokenError { - Missing, - Invalid, -} - #[get("/system/dotnet/port")] fn dotnet_port(_token: APIToken) -> String { let dotnet_server_port = *DOTNET_SERVER_PORT;