summaryrefslogtreecommitdiff
path: root/src/login/app.rs
diff options
context:
space:
mode:
authorOwen Jacobson <owen@grimoire.ca>2024-09-15 23:50:41 -0400
committerOwen Jacobson <owen@grimoire.ca>2024-09-16 11:03:22 -0400
commit491cb3eb34d20140aed80dbb9edc39c4db5335d2 (patch)
treee1e2e009f064dc6dfc8c98d2bf97d8d1f7b45615 /src/login/app.rs
parent99b33023332393e46f5a661901b980b78e6fb133 (diff)
Consolidate most repository types into a repo module.
Having them contained in the individual endpoint groups conveyed an unintended sense that their intended scope was _only_ that endpoint group. It also made most repo-related import paths _quite_ long. This splits up the repos as follows: * "General applicability" repos - those that are only loosely connected to a single task, and are likely to be shared between tasks - go in crate::repo. * Specialized repos - those tightly connected to a specific task - go in the module for that task, under crate::PATH::repo. In both cases, each repo goes in its own submodule, to make it easier to use the module name as a namespace. Which category a repo goes in is a judgment call. `crate::channel::repo::broadcast` (formerly `channel::repo::messages`) is used outside of `crate::channel`, for example, but its main purpose is to support channel message broadcasts. It could arguably live under `crate::event::repo::channel`, but the resulting namespace is less legible to me.
Diffstat (limited to 'src/login/app.rs')
-rw-r--r--src/login/app.rs46
1 files changed, 10 insertions, 36 deletions
diff --git a/src/login/app.rs b/src/login/app.rs
index cd65f35..c82da1a 100644
--- a/src/login/app.rs
+++ b/src/login/app.rs
@@ -1,13 +1,15 @@
-use argon2::Argon2;
-use password_hash::{PasswordHash, PasswordHasher, PasswordVerifier, SaltString};
-use rand_core::OsRng;
use sqlx::sqlite::SqlitePool;
-use super::repo::{
- logins::{Login, Provider as _},
- tokens::Provider as _,
+use super::repo::auth::Provider as _;
+use crate::{
+ clock::DateTime,
+ error::BoxedError,
+ password::StoredHash,
+ repo::{
+ login::{Login, Provider as _},
+ token::Provider as _,
+ },
};
-use crate::{clock::DateTime, error::BoxedError};
pub struct Logins<'a> {
db: &'a SqlitePool,
@@ -26,7 +28,7 @@ impl<'a> Logins<'a> {
) -> Result<Option<String>, BoxedError> {
let mut tx = self.db.begin().await?;
- let login = if let Some((login, stored_hash)) = tx.logins().for_login(name).await? {
+ let login = if let Some((login, stored_hash)) = tx.auth().for_name(name).await? {
if stored_hash.verify(password)? {
// Password verified; use the login.
Some(login)
@@ -75,31 +77,3 @@ impl<'a> Logins<'a> {
Ok(())
}
}
-
-#[derive(Debug, sqlx::Type)]
-#[sqlx(transparent)]
-pub struct StoredHash(String);
-
-impl StoredHash {
- fn new(password: &str) -> Result<Self, password_hash::Error> {
- let salt = SaltString::generate(&mut OsRng);
- let argon2 = Argon2::default();
- let hash = argon2
- .hash_password(password.as_bytes(), &salt)?
- .to_string();
- Ok(Self(hash))
- }
-
- fn verify(&self, password: &str) -> 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),
- }
- }
-}