From 1340440fecd79463bad053539c47e65d8da73194 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sun, 31 May 2026 15:45:17 -0400 Subject: [PATCH] Envy (#16) Reviewed-on: http://git.kundeng.us/phoenix/textsender-models/pulls/16 --- Cargo.lock | 44 +++++++++++++++++ Cargo.toml | 2 + src/envy/environment.rs | 106 ++++++++++++++++++++++++++++++++++++++++ src/envy/keys.rs | 53 ++++++++++++++++++++ src/envy/mod.rs | 39 +++++++++++++++ src/envy/utility.rs | 15 ++++++ src/lib.rs | 1 + 7 files changed, 260 insertions(+) create mode 100644 src/envy/environment.rs create mode 100644 src/envy/keys.rs create mode 100644 src/envy/mod.rs create mode 100644 src/envy/utility.rs diff --git a/Cargo.lock b/Cargo.lock index c290f8c..f560d2e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -37,6 +37,27 @@ dependencies = [ "rand_core", ] +[[package]] +name = "const_format" +version = "0.2.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4481a617ad9a412be3b97c5d403fef8ed023103368908b9c50af598ff467cc1e" +dependencies = [ + "const_format_proc_macros", + "konst", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + [[package]] name = "cpufeatures" version = "0.3.0" @@ -56,6 +77,12 @@ dependencies = [ "serde_core", ] +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + [[package]] name = "equivalent" version = "1.0.2" @@ -179,6 +206,21 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "konst" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128133ed7824fcd73d6e7b17957c5eb7bacb885649bd8c69708b2331a10bcefb" +dependencies = [ + "konst_macro_rules", +] + +[[package]] +name = "konst_macro_rules" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4933f3f57a8e9d9da04db23fb153356ecaf00cbd14aee46279c33dc80925c37" + [[package]] name = "leb128fmt" version = "0.1.0" @@ -386,6 +428,8 @@ dependencies = [ name = "textsender_models" version = "0.3.0" dependencies = [ + "const_format", + "dotenvy", "rand", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index 8b2a228..9c2b093 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,8 @@ serde_json = { version = "1.0.149" } rand = { version = "0.10.1" } time = { version = "0.3.47", features = ["formatting", "macros", "parsing", "serde"] } uuid = { version = "1.23.1", features = ["v4", "serde"] } +dotenvy = { version = "0.15.7" } +const_format = { version = "0.2.36" } # josekit = { version = "0.10.3" } # utoipa = { version = "5.4.0", features = ["uuid", "time"] } diff --git a/src/envy/environment.rs b/src/envy/environment.rs new file mode 100644 index 0000000..b05d433 --- /dev/null +++ b/src/envy/environment.rs @@ -0,0 +1,106 @@ +pub async fn get_db_url() -> crate::envy::EnvVar { + dotenvy::dotenv().ok(); + let key = crate::envy::keys::DB_URL; + let value = std::env::var(key).expect(key); + + crate::envy::init_envvar(key, &value) +} + +pub async fn get_secret_main_key() -> crate::envy::EnvVar { + dotenvy::dotenv().ok(); + let key = crate::envy::keys::SECRET_MAIN_KEY; + let value = std::env::var(key).expect(key); + + crate::envy::init_envvar(key, &value) +} + +pub async fn get_service_passphrase() -> crate::envy::EnvVar { + dotenvy::dotenv().ok(); + let key = crate::envy::keys::SERVICE_PASSPHRASE; + let value = std::env::var(key).expect(key); + + crate::envy::init_envvar(key, &value) +} + +pub async fn get_secret_key() -> crate::envy::EnvVar { + dotenvy::dotenv().ok(); + let key = crate::envy::keys::SECRET_KEY; + let value = std::env::var(key).expect(key); + + crate::envy::init_envvar(key, &value) +} + +pub async fn get_root_directory() -> crate::envy::EnvVar { + dotenvy::dotenv().ok(); + let key = crate::envy::keys::ROOT_DIRECTORY; + let value = std::env::var(key).expect(key); + + crate::envy::init_envvar(key, &value) +} + +pub async fn get_app_base_api_url() -> crate::envy::EnvVar { + dotenvy::dotenv().ok(); + let key = crate::envy::keys::TEXTSENDER_BASE_API_URL; + let value = std::env::var(key).expect(key); + + crate::envy::init_envvar(key, &value) +} + +pub async fn get_app_auth_base_api_url() -> crate::envy::EnvVar { + dotenvy::dotenv().ok(); + let key = crate::envy::keys::TEXTSENDER_AUTH_BASE_API_URL; + let value = std::env::var(key).expect(key); + + crate::envy::init_envvar(key, &value) +} + +pub async fn get_app_env() -> crate::envy::EnvVar { + dotenvy::dotenv().ok(); + let key = crate::envy::keys::APP_ENV; + let value = std::env::var(key).expect(key); + + crate::envy::init_envvar(key, &value) +} + +pub async fn get_backend_port() -> crate::envy::EnvVar { + dotenvy::dotenv().ok(); + let key = crate::envy::keys::BACKEND_PORT; + let value = std::env::var(key).expect(key); + crate::envy::init_envvar(key, &value) +} + +pub async fn get_frontend_url() -> crate::envy::EnvVar { + dotenvy::dotenv().ok(); + let key = crate::envy::keys::FRONTEND_URL; + let value = std::env::var(key).expect(key); + + crate::envy::init_envvar(key, &value) +} + +pub async fn get_rust_log() -> crate::envy::EnvVar { + dotenvy::dotenv().ok(); + let key = crate::envy::keys::RUST_LOG; + let value = std::env::var(key).expect(key); + + crate::envy::init_envvar(key, &value) +} + +pub async fn get_allowed_origins() -> crate::envy::EnvVar { + dotenvy::dotenv().ok(); + let key = crate::envy::keys::ALLOWED_ORIGINS; + let value = std::env::var(key).expect(key); + + let mut envvar = crate::envy::init_envvar(key, &value); + crate::envy::init_delimiter(&mut envvar, ','); + + envvar +} + +/// Get environment not specified in the code +pub async fn get_env(environment: &str) -> crate::envy::EnvVar { + dotenvy::dotenv().ok(); + let my_error = format!("{environment} {}", crate::envy::keys::error::GENERAL_ERROR); + let value = std::env::var(environment).expect(&my_error); + + crate::envy::init_envvar(environment, &value) +} diff --git a/src/envy/keys.rs b/src/envy/keys.rs new file mode 100644 index 0000000..24e84a9 --- /dev/null +++ b/src/envy/keys.rs @@ -0,0 +1,53 @@ +/// Environment key for Database management +pub const DB_URL: &str = "DATABASE_URL"; + +/// Environment key for secret main key +/// Used for the textsender app +pub const SECRET_MAIN_KEY: &str = "SECRET_MAIN_KEY"; + +/// Environment key for service logins +pub const SERVICE_PASSPHRASE: &str = "SERVICE_PASSPHRASE"; + +/// Environment key for secret key +/// Generic use of secret key that could be found in various apps +pub const SECRET_KEY: &str = "SECRET_KEY"; + +/// Environment key for root directory for the textsender app +pub const ROOT_DIRECTORY: &str = "ROOT_DIRECTORY"; + +/// Environment key for textsender api url +pub const TEXTSENDER_BASE_API_URL: &str = "TEXTSENDER_BASE_API_URL"; + +/// Environment key for textsender auth api url +pub const TEXTSENDER_AUTH_BASE_API_URL: &str = "TEXTSENDER_AUTH_BASE_API_URL"; + +/// Environment key for App status +pub const APP_ENV: &str = "APP_ENV"; +/// Environment key for backend port. Used for both auth and core functionality +pub const BACKEND_PORT: &str = "BACKEND_PORT"; +/// Environment key for frontend url +pub const FRONTEND_URL: &str = "FRONTEND_URL"; +/// Environment key for application logging +pub const RUST_LOG: &str = "RUST_LOG"; +/// Environment key for allowed origins for CORS support +pub const ALLOWED_ORIGINS: &str = "ALLOWED_ORIGINS"; + +pub mod error { + use const_format::concatcp; + + pub const GENERAL_ERROR: &str = "must not be set in enviornment file"; + pub const DB_URL: &str = concatcp!(super::DB_URL, " ", GENERAL_ERROR); + pub const SECRET_MAIN_KEY: &str = concatcp!(super::SECRET_MAIN_KEY, " ", GENERAL_ERROR); + pub const SERVICE_LOGIN: &str = concatcp!(super::SERVICE_PASSPHRASE, " ", GENERAL_ERROR); + pub const SECRET_KEY: &str = concatcp!(super::SECRET_KEY, " ", GENERAL_ERROR); + pub const ROOT_DIRECTORY: &str = concatcp!(super::ROOT_DIRECTORY, " ", GENERAL_ERROR); + pub const TEXTSENDER_BASE_API_URL: &str = + concatcp!(super::TEXTSENDER_BASE_API_URL, " ", GENERAL_ERROR); + pub const TEXTSENDER_AUTH_BASE_API_URL: &str = + concatcp!(super::TEXTSENDER_AUTH_BASE_API_URL, " ", GENERAL_ERROR); + pub const APP_ENV: &str = concatcp!(super::APP_ENV, " ", GENERAL_ERROR); + pub const BACKEND_PORT: &str = concatcp!(super::BACKEND_PORT, " ", GENERAL_ERROR); + pub const FRONTEND_URL: &str = concatcp!(super::FRONTEND_URL, " ", GENERAL_ERROR); + pub const RUST_LOG: &str = concatcp!(super::RUST_LOG, " ", GENERAL_ERROR); + pub const ALLOWED_ORIGINS: &str = concatcp!(super::ALLOWED_ORIGINS, " ", GENERAL_ERROR); +} diff --git a/src/envy/mod.rs b/src/envy/mod.rs new file mode 100644 index 0000000..d3d1bde --- /dev/null +++ b/src/envy/mod.rs @@ -0,0 +1,39 @@ +pub mod environment; +pub mod keys; +pub mod utility; + +#[derive(Debug, Default, Clone)] +pub struct EnvVar { + pub key: String, + pub value: String, + pub has_delimiter: bool, + pub delimiter: char, +} + +pub fn init_envvar(key: &str, value: &str) -> EnvVar { + EnvVar { + key: key.to_string(), + value: value.to_string(), + has_delimiter: false, + ..Default::default() + } +} + +pub fn init_delimiter(envvar: &mut EnvVar, delimiter: char) { + let mut amount_of_delimiters_found: i32 = 0; + + for v in envvar.value.chars() { + if v == delimiter { + amount_of_delimiters_found += 1; + } + } + + let has_delimiter = amount_of_delimiters_found >= 1; + + if has_delimiter { + envvar.has_delimiter = has_delimiter; + envvar.delimiter = delimiter; + } else { + envvar.has_delimiter = has_delimiter; + } +} diff --git a/src/envy/utility.rs b/src/envy/utility.rs new file mode 100644 index 0000000..6ca8cce --- /dev/null +++ b/src/envy/utility.rs @@ -0,0 +1,15 @@ +/// Take the Environment variable and delimitize it. If the value has a delimiter, +/// extract it into some strings +pub fn delimitize(var: &crate::envy::EnvVar) -> Result, std::io::Error> { + if var.has_delimiter { + Ok(var + .value + .split(var.delimiter) + .map(|c| c.parse::().unwrap()) + .collect()) + } else { + Err(std::io::Error::other( + "Environment variable does not have a delimiter", + )) + } +} diff --git a/src/lib.rs b/src/lib.rs index a2f043b..50bc1b5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ pub mod config; pub mod contact; +pub mod envy; pub mod message; pub mod token; pub mod user;