Compute user digest on deserialization.
This commit is contained in:
parent
91a0ba05c4
commit
e9e5436e02
3 changed files with 26 additions and 30 deletions
25
src/auth.rs
25
src/auth.rs
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,10 +7,6 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use crate::{auth::Credentials, AuthSession, LoginPage, LogoutPage, LogoutSuccessPage};
|
||||
|
||||
//-************************************************************************
|
||||
// Constants
|
||||
//-************************************************************************
|
||||
|
||||
//-************************************************************************
|
||||
// Login error and success types
|
||||
//-************************************************************************
|
||||
|
|
27
src/users.rs
27
src/users.rs
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue