Handle passwords

This commit is contained in:
traxys 2023-08-30 00:04:58 +02:00
parent e6d4f81533
commit 87d99c4875
5 changed files with 102 additions and 1 deletions

View file

@ -5,6 +5,10 @@ use std::{
sync::Arc,
};
use argon2::{
password_hash::{rand_core::OsRng, SaltString},
Argon2, PasswordHasher,
};
use axum::{
async_trait,
extract::{FromRef, FromRequestParts, Path, Query, State},
@ -27,6 +31,7 @@ use openidconnect::{
AccessTokenHash, AuthorizationCode, ClientId, ClientSecret, CsrfToken, IssuerUrl, Nonce,
OAuth2TokenResponse, PkceCodeChallenge, PkceCodeVerifier, RedirectUrl, TokenResponse,
};
use secrecy::{ExposeSecret, SecretString};
use serde::{Deserialize, Deserializer};
use sqlx::{postgres::PgPoolOptions, PgPool};
use tera::Tera;
@ -331,6 +336,8 @@ enum Error {
Tera(#[from] tera::Error),
#[error("A JWT error occured")]
Jwt(#[from] jwt_simple::Error),
#[error("An argon2 error occured")]
Argon2(#[from] argon2::password_hash::Error),
#[error("An internal error occured")]
InternalError,
}
@ -369,6 +376,10 @@ impl IntoResponse for Error {
tracing::error!("JWT error: {e:?}");
InternalError.into_response()
}
Error::Argon2(e) => {
tracing::error!("Argon2 error: {e:?}");
InternalError.into_response()
}
}
}
}
@ -794,6 +805,35 @@ async fn delete_recipient(
Ok(Redirect::to("/"))
}
#[derive(Deserialize, Debug)]
struct Password {
password: SecretString,
}
#[tracing::instrument(skip(state))]
async fn set_password(
state: State<Arc<AppState>>,
User(user): User,
Form(password): Form<Password>,
) -> Result<Redirect, Error> {
let salt = SaltString::generate(&mut OsRng);
let argon2 = Argon2::default();
let password_hash = argon2
.hash_password(password.password.expose_secret().as_bytes(), &salt)?
.to_string();
sqlx::query!(
"UPDATE accounts SET password = $1 WHERE id = $2",
password_hash,
user
)
.execute(&state.db)
.await?;
Ok(Redirect::to("/"))
}
#[tokio::main]
async fn main() -> color_eyre::Result<()> {
color_eyre::install()?;
@ -830,6 +870,7 @@ async fn main() -> color_eyre::Result<()> {
.route("/alias/recipient/add", post(add_recipient))
.route("/alias/recipient/delete", post(delete_recipient))
.route("/alias/delete", post(delete_alias))
.route("/password", post(set_password))
.fallback(page_not_found)
.with_state(Arc::new(AppState {
db,