Add password hashing/verify function
This commit is contained in:
parent
663cc6effc
commit
1fb1e853f5
4 changed files with 54 additions and 2 deletions
|
@ -6,11 +6,13 @@ edition.workspace = true
|
||||||
repository.workspace = true
|
repository.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
argon2 = "0.5.3"
|
||||||
|
axum = "0.8.4"
|
||||||
|
clap = {workspace = true, features = ["derive"]}
|
||||||
dpts-core = {workspace = true}
|
dpts-core = {workspace = true}
|
||||||
chrono = {workspace = true}
|
chrono = {workspace = true}
|
||||||
clap = {workspace = true, features = ["derive"]}
|
|
||||||
axum = "0.8.4"
|
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
thiserror.workspace = true
|
thiserror.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
toml.workspace = true
|
toml.workspace = true
|
||||||
|
rand = "0.9.1"
|
||||||
|
|
45
dpts-server/src/auth.rs
Normal file
45
dpts-server/src/auth.rs
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
use argon2::{
|
||||||
|
Argon2,
|
||||||
|
PasswordHasher,
|
||||||
|
PasswordVerifier,
|
||||||
|
password_hash::{
|
||||||
|
Salt,
|
||||||
|
SaltString,
|
||||||
|
PasswordHash,
|
||||||
|
rand_core::OsRng,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
use chrono::format::parse;
|
||||||
|
use crate::error::Error;
|
||||||
|
use tokio::sync::OnceCell;
|
||||||
|
|
||||||
|
pub fn try_hash_password(password: &str) -> Result<String, Error> {
|
||||||
|
let mut rng = OsRng::default();
|
||||||
|
let salt_string= SaltString::generate(&mut rng);
|
||||||
|
let salt = salt_string.as_salt();
|
||||||
|
let hash = Argon2::default().hash_password(password.as_bytes(), salt).or(Err(Error::PasswordHash("Hashing password with salt".to_string())))?;
|
||||||
|
Ok(hash.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn try_verify_password(password: &str, password_hash: &str) -> Result<bool, Error> {
|
||||||
|
let parsed_hash = PasswordHash::new(password_hash).or(Err(Error::PasswordHash("Failed to parse password hash string".to_string())))?;
|
||||||
|
match Argon2::default().verify_password(password.as_bytes(), &parsed_hash) {
|
||||||
|
Ok(_) => Ok(true),
|
||||||
|
Err(_) => Ok(false),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use argon2::password_hash::rand_core::OsRng;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
#[test]
|
||||||
|
fn test_password() {
|
||||||
|
let valid_password = "valid";
|
||||||
|
let invalid_password = "invalid";
|
||||||
|
let hash = try_hash_password(valid_password).unwrap();
|
||||||
|
assert!(try_verify_password(valid_password, &hash).unwrap());
|
||||||
|
assert!(!try_verify_password(invalid_password, &hash).unwrap());
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,11 @@
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
#[error("Uninitialized OnceCell: {0}")]
|
||||||
|
UninitializedOnceCell(String),
|
||||||
#[error("Parse int error")]
|
#[error("Parse int error")]
|
||||||
ParseInt(#[from] std::num::ParseIntError),
|
ParseInt(#[from] std::num::ParseIntError),
|
||||||
|
#[error("Argon2 Password hash error: {0}")]
|
||||||
|
PasswordHash(String),
|
||||||
#[error("Parse toml error")]
|
#[error("Parse toml error")]
|
||||||
TomlDe(#[from] toml::de::Error),
|
TomlDe(#[from] toml::de::Error),
|
||||||
#[error("Missing config value: ({0})")]
|
#[error("Missing config value: ({0})")]
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
mod args;
|
mod args;
|
||||||
|
mod auth;
|
||||||
mod config;
|
mod config;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub use args::Args;
|
pub use args::Args;
|
Loading…
Add table
Reference in a new issue