cleanup errors

This commit is contained in:
2026-08-01 18:32:14 -04:00
parent 188ce23e67
commit 6a2cef2003
4 changed files with 12 additions and 10 deletions
+2
View File
@@ -4,6 +4,8 @@ use thiserror::Error;
pub enum DomainError { pub enum DomainError {
#[error("database error: {0}")] #[error("database error: {0}")]
Database(String), Database(String),
#[error("password error: {0}")]
Password(String),
#[error("record not found")] #[error("record not found")]
NotFound, NotFound,
#[error("record already exists")] #[error("record already exists")]
+2 -2
View File
@@ -128,8 +128,8 @@ pub trait InvitationRepository: Send + Sync {
#[async_trait] #[async_trait]
pub trait PasswordHasher: Send + Sync { pub trait PasswordHasher: Send + Sync {
fn hash(&self, password: &str) -> Result<String, String>; fn hash(&self, password: &str) -> DomainResult<String>;
fn verify(&self, password: &str, encoded_hash: &str) -> Result<bool, String>; fn verify(&self, password: &str, encoded_hash: &str) -> DomainResult<bool>;
} }
#[async_trait] #[async_trait]
+6 -4
View File
@@ -8,22 +8,24 @@ use argon2::{
use async_trait::async_trait; use async_trait::async_trait;
use rand::RngCore; use rand::RngCore;
use crate::domain::{DomainError, DomainResult};
use crate::ports::{PasswordHasher, TokenGenerator}; use crate::ports::{PasswordHasher, TokenGenerator};
pub struct Argon2PasswordHasher; pub struct Argon2PasswordHasher;
#[async_trait] #[async_trait]
impl PasswordHasher for Argon2PasswordHasher { impl PasswordHasher for Argon2PasswordHasher {
fn hash(&self, password: &str) -> Result<String, String> { fn hash(&self, password: &str) -> DomainResult<String> {
let salt = SaltString::generate(&mut OsRng); let salt = SaltString::generate(&mut OsRng);
Argon2::default() Argon2::default()
.hash_password(password.as_bytes(), &salt) .hash_password(password.as_bytes(), &salt)
.map(|hash| hash.to_string()) .map(|hash| hash.to_string())
.map_err(|error| error.to_string()) .map_err(|error| DomainError::Password(error.to_string()))
} }
fn verify(&self, password: &str, encoded_hash: &str) -> Result<bool, String> { fn verify(&self, password: &str, encoded_hash: &str) -> DomainResult<bool> {
let hash = PasswordHash::new(encoded_hash).map_err(|error| error.to_string())?; let hash = PasswordHash::new(encoded_hash)
.map_err(|error| DomainError::Password(error.to_string()))?;
Ok(Argon2::default() Ok(Argon2::default()
.verify_password(password.as_bytes(), &hash) .verify_password(password.as_bytes(), &hash)
.is_ok()) .is_ok())
+2 -4
View File
@@ -73,7 +73,7 @@ impl AuthService {
if !self.can_register(invite).await? { if !self.can_register(invite).await? {
return Err(DomainError::Conflict); return Err(DomainError::Conflict);
} }
let password_hash = self.hasher.hash(&password).map_err(DomainError::Database)?; let password_hash = self.hasher.hash(&password)?;
let users = Arc::clone(&self.users); let users = Arc::clone(&self.users);
let sessions = Arc::clone(&self.sessions); let sessions = Arc::clone(&self.sessions);
self.db self.db
@@ -104,9 +104,7 @@ impl AuthService {
else { else {
return Ok(None); return Ok(None);
}; };
let valid = hasher let valid = hasher.verify(&password, &password_hash)?;
.verify(&password, &password_hash)
.map_err(DomainError::Database)?;
if !valid { if !valid {
return Ok(None); return Ok(None);
} }