diff options
| author | Owen Jacobson <owen@grimoire.ca> | 2025-08-24 01:12:06 -0400 |
|---|---|---|
| committer | Owen Jacobson <owen@grimoire.ca> | 2025-08-24 04:50:49 -0400 |
| commit | fd6a74e8ca1f5ded2a760b8ac644124862d80d54 (patch) | |
| tree | 1da22665c0259c3a4ed63bb7acef4a6e81365dbe /src/user | |
| parent | 97e4c1d25f6ee17959adc23cacd8361dcd42e519 (diff) | |
Hoist `password` out to the top level.
Having this buried under `crate::user` makes it hard to split up the roles `user` fulfils right now. Moving it out to its own module makes it a bit tidier to reuse it in a separate, authentication-only way.
Diffstat (limited to 'src/user')
| -rw-r--r-- | src/user/app.rs | 4 | ||||
| -rw-r--r-- | src/user/create.rs | 3 | ||||
| -rw-r--r-- | src/user/handlers/login/mod.rs | 3 | ||||
| -rw-r--r-- | src/user/handlers/password/mod.rs | 3 | ||||
| -rw-r--r-- | src/user/mod.rs | 3 | ||||
| -rw-r--r-- | src/user/password.rs | 65 | ||||
| -rw-r--r-- | src/user/repo.rs | 3 |
7 files changed, 11 insertions, 73 deletions
diff --git a/src/user/app.rs b/src/user/app.rs index 2ab356f..5f58981 100644 --- a/src/user/app.rs +++ b/src/user/app.rs @@ -1,10 +1,10 @@ use sqlx::sqlite::SqlitePool; use super::{ - Password, User, + User, create::{self, Create}, }; -use crate::{clock::DateTime, event::Broadcaster, name::Name}; +use crate::{clock::DateTime, event::Broadcaster, name::Name, password::Password}; pub struct Users<'a> { db: &'a SqlitePool, diff --git a/src/user/create.rs b/src/user/create.rs index da94685..0e7a118 100644 --- a/src/user/create.rs +++ b/src/user/create.rs @@ -1,10 +1,11 @@ use sqlx::{Transaction, sqlite::Sqlite}; -use super::{History, Password, password::StoredHash, repo::Provider as _, validate}; +use super::{History, repo::Provider as _, validate}; use crate::{ clock::DateTime, event::{Broadcaster, Event, repo::Provider as _}, name::Name, + password::{Password, StoredHash}, }; #[must_use = "dropping a user creation attempt is likely a mistake"] diff --git a/src/user/handlers/login/mod.rs b/src/user/handlers/login/mod.rs index e80377e..da88885 100644 --- a/src/user/handlers/login/mod.rs +++ b/src/user/handlers/login/mod.rs @@ -9,8 +9,9 @@ use crate::{ clock::RequestedAt, error::Internal, name::Name, + password::Password, token::{app, extract::IdentityCookie}, - user::{Password, User}, + user::User, }; #[cfg(test)] diff --git a/src/user/handlers/password/mod.rs b/src/user/handlers/password/mod.rs index 9158325..c327e87 100644 --- a/src/user/handlers/password/mod.rs +++ b/src/user/handlers/password/mod.rs @@ -8,11 +8,12 @@ use crate::{ app::App, clock::RequestedAt, error::Internal, + password::Password, token::{ app, extract::{Identity, IdentityCookie}, }, - user::{Password, User}, + user::User, }; #[cfg(test)] diff --git a/src/user/mod.rs b/src/user/mod.rs index 44e1633..60ec209 100644 --- a/src/user/mod.rs +++ b/src/user/mod.rs @@ -5,9 +5,8 @@ pub mod event; pub mod handlers; mod history; mod id; -pub mod password; pub mod repo; mod snapshot; mod validate; -pub use self::{event::Event, history::History, id::Id, password::Password, snapshot::User}; +pub use self::{event::Event, history::History, id::Id, snapshot::User}; diff --git a/src/user/password.rs b/src/user/password.rs deleted file mode 100644 index e1d164e..0000000 --- a/src/user/password.rs +++ /dev/null @@ -1,65 +0,0 @@ -use std::fmt; - -use argon2::Argon2; -use password_hash::{PasswordHash, PasswordHasher, PasswordVerifier, SaltString}; -use rand_core::OsRng; - -use crate::normalize::nfc; - -#[derive(sqlx::Type)] -#[sqlx(transparent)] -pub struct StoredHash(String); - -impl StoredHash { - pub fn verify(&self, password: &Password) -> Result<bool, password_hash::Error> { - let hash = PasswordHash::new(&self.0)?; - - match Argon2::default().verify_password(password.as_bytes(), &hash) { - // Successful authentication, not an error - Ok(()) => Ok(true), - // Unsuccessful authentication, also not an error - Err(password_hash::errors::Error::Password) => Ok(false), - // Password validation failed for some other reason, treat as an error - Err(err) => Err(err), - } - } -} - -impl fmt::Debug for StoredHash { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("StoredHash").field(&"********").finish() - } -} - -#[derive(Clone, serde::Deserialize)] -#[serde(transparent)] -pub struct Password(nfc::String); - -impl Password { - pub fn hash(&self) -> Result<StoredHash, password_hash::Error> { - let Self(password) = self; - let salt = SaltString::generate(&mut OsRng); - let argon2 = Argon2::default(); - let hash = argon2 - .hash_password(password.as_bytes(), &salt)? - .to_string(); - Ok(StoredHash(hash)) - } - - fn as_bytes(&self) -> &[u8] { - let Self(value) = self; - value.as_bytes() - } -} - -impl fmt::Debug for Password { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("Password").field(&"********").finish() - } -} - -impl From<String> for Password { - fn from(password: String) -> Self { - Password(password.into()) - } -} diff --git a/src/user/repo.rs b/src/user/repo.rs index 83a1471..0f67e9a 100644 --- a/src/user/repo.rs +++ b/src/user/repo.rs @@ -5,7 +5,8 @@ use crate::{ clock::DateTime, event::{Instant, Sequence}, name::{self, Name}, - user::{History, Id, User, password::StoredHash}, + password::StoredHash, + user::{History, Id, User}, }; pub trait Provider { |
