Added system/info endpoint, implement tagging

This commit is contained in:
2025-04-13 09:11:52 -04:00
parent c354ea6d78
commit d5bc4cafb8
17 changed files with 143 additions and 22 deletions

76
api/src/account/mod.rs Normal file
View File

@@ -0,0 +1,76 @@
use argon2::{
password_hash::{rand_core::OsRng, SaltString},
Argon2, PasswordHash, PasswordHasher, PasswordVerifier,
};
use rand::distr::Alphanumeric;
use rand::prelude::*;
use rand_chacha::ChaCha20Rng;
mod auth;
mod routes;
mod session;
pub use auth::*;
pub use session::*;
pub use routes::init_routes;
use crate::error::{Error, ApiResult};
pub fn csprng(take: usize) -> String {
// Generate a CSPRNG 128-bit (16 byte) ID using alphanumeric characters (a-z, A-Z, 0-9)
let rng = ChaCha20Rng::from_os_rng();
rng
.sample_iter(Alphanumeric)
.take(take)
.map(char::from)
.collect()
}
pub fn hash(string: &str) -> ApiResult<String> {
let salt = SaltString::generate(&mut OsRng);
let hash = Argon2::default()
.hash_password(string.as_bytes(), &salt)?
.to_string();
Ok(hash)
}
pub fn verify_hash(string: &str, hashed_string: &str) -> bool {
let bytes = string.as_bytes();
let parsed_hash = match PasswordHash::new(hashed_string) {
Ok(h) => h,
Err(err) => {
log::error!(
"Failed to construct PasswordHash from '{}': {}",
hashed_string,
err
);
return false;
}
};
Argon2::default()
.verify_password(bytes, &parsed_hash)
.is_ok()
}
pub fn verify_role(auth: &Auth, role: &str) -> ApiResult<()> {
if auth.user.role == role {
Ok(())
} else {
Err(Error {
status: 403,
details: "User does not have permission to perform this action.".to_string(),
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_hash() {
let password = hash("password").unwrap();
assert!(!verify_hash(&password, "bad_password"));
assert!(verify_hash("password", &password));
}
}