Compute user digest on deserialization.

This commit is contained in:
Joe Ardent 2023-12-22 17:19:30 -08:00
parent 91a0ba05c4
commit e9e5436e02
3 changed files with 26 additions and 30 deletions

View file

@ -21,20 +21,6 @@ impl AuthStore {
}
}
impl std::ops::DerefMut for AuthStore {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl std::ops::Deref for AuthStore {
type Target = SqlitePool;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[derive(Default, Debug, Clone, PartialEq, Eq)]
pub struct Credentials {
pub username: String,
@ -57,7 +43,9 @@ impl AuthnBackend for AuthStore {
let username = creds.username.trim();
let password = creds.password.trim();
let user = User::try_get(username, self).await.map_err(|_| AuthError)?;
let user = User::try_get(username, &self.0)
.await
.map_err(|_| AuthError)?;
let verifier = Argon2::default();
let hash = PasswordHash::new(&user.pwhash).map_err(|_| AuthError)?;
Ok(
@ -70,12 +58,11 @@ impl AuthnBackend for AuthStore {
}
async fn get_user(&self, user_id: &UserId<Self>) -> Result<Option<Self::User>, Self::Error> {
let user = sqlx::query_as("select * from users where id = ?")
sqlx::query_as("select * from users where id = ?")
.bind(user_id)
.fetch_optional(&self.0)
.await
.map_err(|_| AuthError)?;
Ok(user)
.map_err(|_| AuthError)
}
}
@ -87,7 +74,7 @@ impl AuthUser for User {
}
fn session_auth_hash(&self) -> &[u8] {
self.pwhash.as_bytes()
self.digest.as_bytes()
}
}

View file

@ -7,10 +7,6 @@ use serde::{Deserialize, Serialize};
use crate::{auth::Credentials, AuthSession, LoginPage, LogoutPage, LogoutSuccessPage};
//-************************************************************************
// Constants
//-************************************************************************
//-************************************************************************
// Login error and success types
//-************************************************************************

View file

@ -7,14 +7,14 @@ use axum::{
};
use julid::Julid;
use serde::{Deserialize, Serialize};
use sqlx::SqlitePool;
use sqlx::{sqlite::SqliteRow, Row, SqlitePool};
use crate::AuthSession;
const USERNAME_QUERY: &str = "select * from users where username = $1";
const LAST_SEEN_QUERY: &str = "update users set last_seen = (select unixepoch()) where id = $1";
#[derive(Default, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
#[derive(Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct User {
pub id: Julid,
pub username: String,
@ -22,10 +22,25 @@ pub struct User {
pub email: Option<String>,
pub last_seen: Option<i64>,
pub pwhash: String,
#[sqlx(default)]
pub digest: String,
}
impl sqlx::FromRow<'_, SqliteRow> for User {
fn from_row(row: &SqliteRow) -> Result<Self, sqlx::Error> {
let pwhash = row.try_get("pwhash")?;
let digest = sha256::digest(&pwhash);
Ok(Self {
id: row.try_get("id")?,
username: row.try_get("username")?,
displayname: row.try_get("displayname")?,
email: row.try_get("email")?,
last_seen: row.try_get("last_seen")?,
pwhash,
digest,
})
}
}
impl Debug for User {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("User")
@ -54,12 +69,10 @@ impl Display for User {
impl User {
pub async fn try_get(username: &str, db: &SqlitePool) -> Result<Self, sqlx::Error> {
let mut user: Self = sqlx::query_as(USERNAME_QUERY)
sqlx::query_as(USERNAME_QUERY)
.bind(username)
.fetch_one(db)
.await?;
user.digest = sha256::digest(&user.pwhash);
Ok(user)
.await
}
pub async fn update_last_seen(&self, pool: &SqlitePool) {