Compare commits

..
Author SHA1 Message Date
phoenix 9210c3b7ae Warning fix
textsender_models PR / Clippy (pull_request) Successful in 1m27s
textsender_models PR / Rustfmt (pull_request) Successful in 1m8s
textsender_models PR / Check (pull_request) Successful in 1m16s
Release Tagging / release (pull_request) Successful in 1m24s
2026-06-27 17:17:27 -04:00
phoenix 9ea37e56f0 cargo update
textsender_models PR / Rustfmt (pull_request) Successful in 1m0s
Release Tagging / release (pull_request) Successful in 27s
textsender_models PR / Check (pull_request) Successful in 1m27s
textsender_models PR / Clippy (pull_request) Failing after 1m47s
2026-06-27 17:12:50 -04:00
phoenix 6e91320709 Refactor
textsender_models PR / Rustfmt (pull_request) Successful in 1m1s
textsender_models PR / Check (pull_request) Successful in 1m27s
Release Tagging / release (pull_request) Successful in 32s
textsender_models PR / Clippy (pull_request) Failing after 1m22s
2026-06-23 01:34:37 -04:00
phoenix 7736f79649 Test is workng
textsender_models PR / Rustfmt (pull_request) Successful in 53s
textsender_models PR / Check (pull_request) Successful in 1m5s
textsender_models PR / Clippy (pull_request) Successful in 1m22s
Release Tagging / release (pull_request) Successful in 34s
2026-06-23 00:19:32 -04:00
phoenix 1eb659d865 Added test
textsender_models PR / Rustfmt (pull_request) Successful in 36s
textsender_models PR / Check (pull_request) Successful in 1m5s
textsender_models PR / Clippy (pull_request) Successful in 57s
Release Tagging / release (pull_request) Failing after 33s
2026-06-22 23:58:44 -04:00
phoenix 3ea92ae64e bump: textsender_models
textsender_models PR / Check (pull_request) Successful in 1m22s
textsender_models PR / Clippy (pull_request) Successful in 1m34s
Release Tagging / release (pull_request) Successful in 36s
textsender_models PR / Rustfmt (pull_request) Successful in 32s
2026-06-22 23:14:00 -04:00
phoenix 0e8e0db284 Refactored function 2026-06-22 23:13:17 -04:00
phoenix 720f3d8f75 Adding function to load twilio config
textsender_models PR / Rustfmt (pull_request) Successful in 1m2s
textsender_models PR / Check (pull_request) Successful in 1m10s
textsender_models PR / Clippy (pull_request) Successful in 1m25s
Release Tagging / release (pull_request) Successful in 37s
2026-06-21 17:57:02 -04:00
phoenix 7e5bc016b1 Making field optional
textsender_models PR / Rustfmt (pull_request) Successful in 54s
textsender_models PR / Clippy (pull_request) Successful in 1m13s
Release Tagging / release (pull_request) Successful in 27s
textsender_models PR / Check (pull_request) Successful in 1m54s
2026-06-20 16:33:13 -04:00
phoenix 384dd41690 bump: textsender_models
textsender_models PR / Check (pull_request) Successful in 1m32s
textsender_models PR / Clippy (pull_request) Successful in 1m31s
textsender_models PR / Rustfmt (pull_request) Successful in 47s
Release Tagging / release (pull_request) Successful in 33s
2026-06-20 12:55:02 -04:00
phoenix f246676203 Changed type of response field to serde_json::Value 2026-06-20 12:54:55 -04:00
phoenix 47e6c85fc7 bump: textsender_models
textsender_models PR / Rustfmt (pull_request) Successful in 1m4s
textsender_models PR / Check (pull_request) Successful in 1m25s
Release Tagging / release (pull_request) Successful in 33s
textsender_models PR / Clippy (pull_request) Successful in 1m8s
2026-06-18 14:27:43 -04:00
phoenix 82370ad63a Added sqlx crate 2026-06-18 14:27:18 -04:00
phoenix e5ab4aa426 Adding sqlx::FromRow trait
textsender_models PR / Check (pull_request) Has been cancelled
textsender_models PR / Rustfmt (pull_request) Has been cancelled
textsender_models PR / Clippy (pull_request) Has been cancelled
Release Tagging / release (pull_request) Successful in 40s
2026-06-18 14:26:37 -04:00
phoenix ad632fca16 bump: textsender_models
textsender_models PR / Rustfmt (pull_request) Successful in 40s
textsender_models PR / Check (pull_request) Successful in 44s
Release Tagging / release (pull_request) Successful in 28s
textsender_models PR / Clippy (pull_request) Successful in 58s
2026-06-17 16:41:53 -04:00
phoenix 86febdab0d Fix field access issue 2026-06-17 16:41:46 -04:00
phoenix 7534e8652f Updating workflows
textsender_models PR / Rustfmt (pull_request) Successful in 36s
Release Tagging / release (pull_request) Successful in 33s
textsender_models PR / Clippy (pull_request) Successful in 1m12s
textsender_models PR / Check (pull_request) Successful in 1m39s
2026-06-17 16:17:38 -04:00
phoenix c4b2c19f77 Some refactoring
textsender_models PR / Rustfmt (pull_request) Successful in 35s
Release Tagging / release (pull_request) Successful in 38s
textsender_models PR / Check (pull_request) Successful in 1m34s
textsender_models PR / Clippy (pull_request) Successful in 1m33s
2026-06-17 16:15:35 -04:00
phoenix 890d03bdf3 Adding to macros and refactoring 2026-06-17 16:12:07 -04:00
15 changed files with 572 additions and 422 deletions
+7 -7
View File
@@ -1,4 +1,4 @@
name: schedtxt_models PR
name: textsender_models PR
on:
pull_request:
@@ -14,10 +14,10 @@ jobs:
name: Check
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.97
toolchain: 1.96
- uses: Swatinem/rust-cache@v2
- run: cargo check
@@ -25,10 +25,10 @@ jobs:
name: Rustfmt
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.97
toolchain: 1.96
- uses: Swatinem/rust-cache@v2
- run: rustup component add rustfmt
- run: cargo fmt --all -- --check
@@ -37,10 +37,10 @@ jobs:
name: Clippy
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.97
toolchain: 1.96
- uses: Swatinem/rust-cache@v2
- run: rustup component add clippy
- run: cargo clippy -- -D warnings
+2 -2
View File
@@ -13,14 +13,14 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@v6
uses: actions/checkout@v5
with:
fetch-depth: 0 # Important for git describe --tags
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: 1.97
toolchain: 1.96
components: cargo
- name: Extract Version from Cargo.toml
+10 -10
View File
@@ -14,10 +14,10 @@ jobs:
name: Check
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.97
toolchain: 1.96
- uses: Swatinem/rust-cache@v2
- run: cargo check
@@ -25,10 +25,10 @@ jobs:
name: Test Suite
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.97
toolchain: 1.96
- uses: Swatinem/rust-cache@v2
- run: cargo test
@@ -36,10 +36,10 @@ jobs:
name: Rustfmt
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.97
toolchain: 1.96
- uses: Swatinem/rust-cache@v2
- run: rustup component add rustfmt
- run: cargo fmt --all -- --check
@@ -48,10 +48,10 @@ jobs:
name: Clippy
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.97
toolchain: 1.96
- uses: Swatinem/rust-cache@v2
- run: rustup component add clippy
- run: cargo clippy -- -D warnings
@@ -60,9 +60,9 @@ jobs:
name: build
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.97
toolchain: 1.96
- uses: Swatinem/rust-cache@v2
- run: cargo build
Generated
+470 -195
View File
File diff suppressed because it is too large Load Diff
+7 -8
View File
@@ -1,17 +1,16 @@
[package]
name = "schedtxt_models"
version = "0.5.3"
name = "textsender_models"
version = "0.4.10"
edition = "2024"
rust-version = "1.97"
license = "MIT"
description = "Models used for the schedtxt project"
rust-version = "1.96"
description = "Models used for the textsender project"
[dependencies]
serde = { version = "1.0.228", features = ["derive"] }
serde_json = { version = "1.0.150" }
time = { version = "0.3.53", features = ["formatting", "macros", "parsing", "serde"] }
sqlx = { version = "0.9.0", features = ["runtime-tokio", "tls-native-tls", "postgres", "time", "uuid"] }
uuid = { version = "1.23.5", features = ["v4", "serde"] }
time = { version = "0.3.49", features = ["formatting", "macros", "parsing", "serde"] }
sqlx = { version = "0.8.6", features = ["postgres", "runtime-tokio-native-tls", "time", "uuid"] }
uuid = { version = "1.23.3", features = ["v4", "serde"] }
dotenvy = { version = "0.15.7" }
const_format = { version = "0.2.36" }
josekit = { version = "0.10.3" }
-22
View File
@@ -1,22 +0,0 @@
Copyright (c) 2026 Kun Deng.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
-2
View File
@@ -1,2 +0,0 @@
# schedtxt_models
Models library for the `schedtxt` project.
+6 -5
View File
@@ -20,11 +20,12 @@ impl TwilioConfig {
}
}
pub fn load_config() -> Result<TwilioConfig, std::io::Error> {
let auth_sid_var = crate::envy::environment::get_env("TWILIO_AUTH_SID");
let service_sid_var = crate::envy::environment::get_env("TWILIO_SERVICE_SID");
let auth_token_var = crate::envy::environment::get_env("TWILIO_AUTH_TOKEN");
let phone_number_var = crate::envy::environment::get_env("TWILIO_PHONE_NUMBER");
// TODO: Remove the async at a later point
pub async fn load_config() -> Result<TwilioConfig, std::io::Error> {
let auth_sid_var = crate::envy::environment::get_env("TWILIO_AUTH_SID").await;
let service_sid_var = crate::envy::environment::get_env("TWILIO_SERVICE_SID").await;
let auth_token_var = crate::envy::environment::get_env("TWILIO_AUTH_TOKEN").await;
let phone_number_var = crate::envy::environment::get_env("TWILIO_PHONE_NUMBER").await;
if auth_sid_var.value.is_empty()
|| service_sid_var.value.is_empty()
+3
View File
@@ -4,10 +4,13 @@
pub struct Contact {
#[serde(skip_serializing_if = "crate::init::is_uuid_nil")]
pub id: Option<uuid::Uuid>,
// empty?
#[serde(skip_serializing_if = "Option::is_none")]
pub firstname: Option<String>,
// empty?
#[serde(skip_serializing_if = "Option::is_none")]
pub lastname: Option<String>,
// empty?
#[serde(skip_serializing_if = "Option::is_none")]
pub nickname: Option<String>,
pub phone_number: String,
+18 -16
View File
@@ -1,4 +1,6 @@
pub fn get_db_url() -> crate::envy::EnvVar {
// TODO: Functions does not need to be async
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);
@@ -6,7 +8,7 @@ pub fn get_db_url() -> crate::envy::EnvVar {
crate::envy::init_envvar(key, &value)
}
pub fn get_secret_main_key() -> crate::envy::EnvVar {
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);
@@ -14,7 +16,7 @@ pub fn get_secret_main_key() -> crate::envy::EnvVar {
crate::envy::init_envvar(key, &value)
}
pub fn get_service_passphrase() -> crate::envy::EnvVar {
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);
@@ -22,7 +24,7 @@ pub fn get_service_passphrase() -> crate::envy::EnvVar {
crate::envy::init_envvar(key, &value)
}
pub fn get_secret_key() -> crate::envy::EnvVar {
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);
@@ -30,7 +32,7 @@ pub fn get_secret_key() -> crate::envy::EnvVar {
crate::envy::init_envvar(key, &value)
}
pub fn get_root_directory() -> crate::envy::EnvVar {
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);
@@ -38,23 +40,23 @@ pub fn get_root_directory() -> crate::envy::EnvVar {
crate::envy::init_envvar(key, &value)
}
pub fn get_app_base_api_url() -> crate::envy::EnvVar {
pub async fn get_app_base_api_url() -> crate::envy::EnvVar {
dotenvy::dotenv().ok();
let key = crate::envy::keys::SCHEDTXT_BASE_API_URL;
let key = crate::envy::keys::TEXTSENDER_BASE_API_URL;
let value = std::env::var(key).expect(key);
crate::envy::init_envvar(key, &value)
}
pub fn get_app_auth_base_api_url() -> crate::envy::EnvVar {
pub async fn get_app_auth_base_api_url() -> crate::envy::EnvVar {
dotenvy::dotenv().ok();
let key = crate::envy::keys::SCHEDTXT_AUTH_BASE_API_URL;
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 fn get_app_env() -> crate::envy::EnvVar {
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);
@@ -62,14 +64,14 @@ pub fn get_app_env() -> crate::envy::EnvVar {
crate::envy::init_envvar(key, &value)
}
pub fn get_backend_port() -> crate::envy::EnvVar {
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 fn get_frontend_url() -> crate::envy::EnvVar {
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);
@@ -77,7 +79,7 @@ pub fn get_frontend_url() -> crate::envy::EnvVar {
crate::envy::init_envvar(key, &value)
}
pub fn get_rust_log() -> crate::envy::EnvVar {
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);
@@ -85,7 +87,7 @@ pub fn get_rust_log() -> crate::envy::EnvVar {
crate::envy::init_envvar(key, &value)
}
pub fn get_allowed_origins() -> crate::envy::EnvVar {
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);
@@ -96,8 +98,8 @@ pub fn get_allowed_origins() -> crate::envy::EnvVar {
envvar
}
/// Get environment not specified in the library
pub fn get_env(environment: &str) -> crate::envy::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);
+8 -8
View File
@@ -2,7 +2,7 @@
pub const DB_URL: &str = "DATABASE_URL";
/// Environment key for secret main key
/// Used for the schedtxt app
/// Used for the textsender app
pub const SECRET_MAIN_KEY: &str = "SECRET_MAIN_KEY";
/// Environment key for service logins
@@ -15,11 +15,11 @@ 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 schedtxt api url
pub const SCHEDTXT_BASE_API_URL: &str = "SCHEDTXT_BASE_API_URL";
/// 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 SCHEDTXT_AUTH_BASE_API_URL: &str = "SCHEDTXT_AUTH_BASE_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";
@@ -41,10 +41,10 @@ pub mod 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 SCHEDTXT_BASE_API_URL: &str =
concatcp!(super::SCHEDTXT_BASE_API_URL, " ", GENERAL_ERROR);
pub const SCHEDTXT_AUTH_BASE_API_URL: &str =
concatcp!(super::SCHEDTXT_AUTH_BASE_API_URL, " ", 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);
+8 -26
View File
@@ -20,17 +20,16 @@ pub fn init_envvar(key: &str, value: &str) -> EnvVar {
}
pub fn init_delimiter(envvar: &mut EnvVar, delimiter: char) {
let amount_of_delimiters_found: i32 = {
let mut count = 0;
for v in envvar.value.chars() {
if v == delimiter {
count += 1;
}
}
let mut amount_of_delimiters_found: i32 = 0;
for v in envvar.value.chars() {
if v == delimiter {
amount_of_delimiters_found += 1;
}
}
count
};
let has_delimiter = amount_of_delimiters_found >= 1;
if has_delimiter {
envvar.has_delimiter = has_delimiter;
envvar.delimiter = delimiter;
@@ -38,20 +37,3 @@ pub fn init_delimiter(envvar: &mut EnvVar, delimiter: char) {
envvar.has_delimiter = has_delimiter;
}
}
#[cfg(test)]
mod tests {
#[test]
fn test_init_delimiter() {
let delimiter: char = ',';
let value = format!("red,green,white,black");
let mut env_var = super::EnvVar {
key: String::from("COLORS"),
value: value.clone(),
..Default::default()
};
super::init_delimiter(&mut env_var, delimiter);
assert_eq!(value, env_var.value, "Colors do not match");
}
}
+3 -41
View File
@@ -2,52 +2,14 @@
/// extract it into some strings
pub fn delimitize(var: &crate::envy::EnvVar) -> Result<Vec<String>, std::io::Error> {
if var.has_delimiter {
let values: Vec<String> = match var
Ok(var
.value
.split(var.delimiter)
.map(|c| c.parse::<String>())
.collect()
{
Ok(v) => v,
Err(err) => {
return Err(std::io::Error::other(err));
}
};
Ok(values)
.map(|c| c.parse::<String>().unwrap())
.collect())
} else {
Err(std::io::Error::other(
"Environment variable does not have a delimiter",
))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_delimitize() {
let envvar = crate::envy::EnvVar {
key: "OCEANS".to_string(),
value: "Atlantic|Pacific|Indian|Arctic".to_string(),
has_delimiter: true,
delimiter: '|',
};
let all_values = vec![
"Atlantic".to_string(),
"Pacific".to_string(),
"Indian".to_string(),
"Arctic".to_string(),
];
match delimitize(&envvar) {
Ok(values) => {
assert_eq!(values, all_values, "Failure in delimitizing EnvVar values");
}
Err(err) => {
assert!(false, "Error delimitizing: {err:?}");
}
}
}
}
+26 -80
View File
@@ -78,32 +78,37 @@ pub struct CreateTokenResult {
}
pub fn create_token(
key: &str,
token_resource: TokenResource,
key: &String,
token_resource: &TokenResource,
duration: time::Duration,
) -> Result<CreateTokenResult, josekit::JoseError> {
let mut header = josekit::jws::JwsHeader::new();
header.set_token_type(TOKEN_TYPE);
match init_payload(token_resource, duration) {
Ok((payload, issued, expire)) => {
let signer = match josekit::jws::alg::hmac::HmacJwsAlgorithm::Hs256
let mut payload = josekit::jwt::JwtPayload::new();
payload.set_subject(&token_resource.message);
payload.set_issuer(&token_resource.issuer);
payload.set_audience(token_resource.audiences.clone());
if !token_resource.user_id.is_nil() {
match payload.set_claim("user_id", Some(serde_json::json!(token_resource.user_id))) {
Ok(_) => {}
Err(err) => {
return Err(err);
}
}
}
match get_issued() {
Ok(issued) => {
let expire = issued + duration;
payload.set_issued_at(&util::time_to_std_time(&issued).unwrap());
payload.set_expires_at(&util::time_to_std_time(&expire).unwrap());
let signer = josekit::jws::alg::hmac::HmacJwsAlgorithm::Hs256
.signer_from_bytes(key.as_bytes())
{
Ok(signer) => signer,
Err(err) => {
return Err(err);
}
};
let access_token = match josekit::jwt::encode_with_signer(&payload, &header, &signer) {
Ok(access_token) => access_token,
Err(err) => {
return Err(err);
}
};
.unwrap();
Ok(CreateTokenResult {
access_token,
access_token: josekit::jwt::encode_with_signer(&payload, &header, &signer).unwrap(),
issued: issued.unix_timestamp(),
expires_in: expire.unix_timestamp(),
token_issued: issued,
@@ -113,69 +118,10 @@ pub fn create_token(
}
}
fn init_payload(
token_resource: TokenResource,
duration: time::Duration,
) -> Result<
(
josekit::jwt::JwtPayload,
time::OffsetDateTime,
time::OffsetDateTime,
),
josekit::JoseError,
> {
let mut payload = josekit::jwt::JwtPayload::new();
payload.set_subject(token_resource.message);
payload.set_issuer(token_resource.issuer);
payload.set_audience(token_resource.audiences);
if !token_resource.user_id.is_nil() {
match payload.set_claim("user_id", Some(serde_json::json!(token_resource.user_id))) {
Ok(_) => {}
Err(err) => {
return Err(err);
}
}
}
match init_payload_issued(&mut payload, duration) {
Ok((issued, expire)) => Ok((payload, issued, expire)),
Err(err) => Err(err),
}
}
fn init_payload_issued(
payload: &mut josekit::jwt::JwtPayload,
duration: time::Duration,
) -> Result<(time::OffsetDateTime, time::OffsetDateTime), josekit::JoseError> {
match get_issued() {
Ok(issued) => {
let expire = issued + duration;
let issued_at = match util::time_to_std_time(&issued) {
Ok(issued_at) => issued_at,
Err(err) => {
return Err(josekit::JoseError::InvalidClaim(err.into()));
}
};
let expires_at = match util::time_to_std_time(&expire) {
Ok(expires_at) => expires_at,
Err(err) => {
return Err(josekit::JoseError::InvalidClaim(err.into()));
}
};
payload.set_issued_at(&issued_at);
payload.set_expires_at(&expires_at);
Ok((issued, expire))
}
Err(err) => Err(josekit::JoseError::InvalidClaim(err.into())),
}
}
#[cfg(test)]
mod tests {
const TEST_MESSAGE: &str = "Testing for schedtxt";
const TEST_ISSUER: &str = "schedtxt-test";
const TEST_MESSAGE: &str = "Testing for textsender";
const TEST_ISSUER: &str = "textsender-test";
const TEST_AUDIENCE: &str = "area-test";
const TEST_USER_ID: uuid::Uuid = uuid::uuid!("9ab1c75f-d184-4913-ae99-544b4dcfcb41");
const TEST_KEY: &str = "8342nhf7ycrt4983q7ryfc93w478ryfc3w9487ryfc342w98i7cy";
@@ -192,7 +138,7 @@ mod tests {
let token_duration = time::Duration::minutes(30);
let key = String::from(TEST_KEY);
match super::create_token(&key, token_resource, token_duration) {
match super::create_token(&key, &token_resource, token_duration) {
Ok(cst) => match time::OffsetDateTime::from_unix_timestamp(cst.issued) {
Ok(d_result) => {
let they_match = {
+4
View File
@@ -6,7 +6,9 @@ pub struct User {
pub phone_number: String,
pub username: String,
pub password: String,
// Firstname is a pointer
pub firstname: String,
// Lastname is a pointer
pub lastname: String,
#[serde(with = "time::serde::rfc3339::option")]
pub created: Option<time::OffsetDateTime>,
@@ -25,6 +27,7 @@ pub struct ServiceUser {
pub passphrase: String,
#[serde(with = "time::serde::rfc3339::option")]
pub created: Option<time::OffsetDateTime>,
// When serializing to json, if empty do not populate
#[serde(with = "time::serde::rfc3339::option")]
pub last_login: Option<time::OffsetDateTime>,
#[serde(skip)]
@@ -78,6 +81,7 @@ pub struct UserProfile {
#[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize, sqlx::FromRow)]
pub struct Salt {
// #[serde(skip_serializing_if = "crate::init::is_uuid_nil")]
pub id: uuid::Uuid,
#[serde(skip_serializing_if = "String::is_empty")]
pub salt: String,