Added password reset token expiry check

This commit is contained in:
Keanu D?lle 2020-12-30 12:37:31 +01:00
parent 23595f6d3b
commit 7cafa57789
6 changed files with 18 additions and 6 deletions

View File

@ -14,6 +14,8 @@ upload_path = "uploads/"
max_login_attempts = 6
#Duration of email lock after max_login_attempts in seconds. Default is 30 minutes
login_lock_duration = 1800
#How long does it take until tokens expire?
reset_password_token_valid_duration = 3600
[mail]
from = "No Reply <noreply@localhost>"

View File

@ -12,7 +12,7 @@
</div>
</div>
<div class="row">
<div class="col">
<div class="col-10">
<form method="post">
{{#if alert}}
{{> alert}}

View File

@ -5,7 +5,7 @@ use crate::schema::password_resets::dsl::{password_resets};
use rand::{thread_rng, Rng};
use rand::distributions::Alphanumeric;
use diesel::{ExpressionMethods, RunQueryDsl};
use chrono::NaiveDateTime;
use chrono::{NaiveDateTime, Utc};
use diesel::query_dsl::filter_dsl::FilterDsl;
use diesel::query_dsl::select_dsl::SelectDsl;
use argon2::Config;
@ -47,8 +47,17 @@ pub fn remove_token(settings: &State<Settings>, token2: String) -> Result<(), di
pub fn validate_token(settings: &State<Settings>, token2: String) -> Result<uuid::Uuid, diesel::result::Error>{
let connection = establish_connection(settings);
match password_resets.select(crate::schema::password_resets::dsl::user_id).filter(crate::schema::password_resets::dsl::token.eq(token2)).get_result(&connection){
Ok(user_id) => Ok(user_id),
match password_resets.select((crate::schema::password_resets::dsl::user_id, crate::schema::password_resets::issued)).filter(crate::schema::password_resets::dsl::token.eq(token2.clone())).get_result::<(uuid::Uuid, NaiveDateTime)>(&connection){
Ok(data) => {
let issued = data.1;
let now = Utc::now().naive_local();
let duration = now.signed_duration_since(issued).num_seconds();
if duration > settings.application.reset_password_token_valid_duration{
remove_token(settings, token2);
return Err(diesel::result::Error::NotFound)
}
Ok(data.0)
},
Err(e) => match e{
diesel::result::Error::NotFound => {
return Err(e)

View File

@ -17,6 +17,7 @@ pub struct Application {
pub max_login_attempts: i32,
pub login_lock_duration: i32,
pub name: String,
pub reset_password_token_valid_duration: i64,
}
#[derive(Debug, Deserialize, Default)]

View File

@ -135,7 +135,7 @@ pub struct PasswordChangeForm{
pub(crate) password: String,
}
#[post("/password_reset?1<token>", data = "<password_change_form>")]
#[post("/password_reset?<token>", data = "<password_change_form>")]
pub fn password_change_post(
settings: State<Settings>,
password_change_form: Form<PasswordChangeForm>,

View File

@ -180,7 +180,7 @@ table! {
password_resets (token) {
token -> Text,
user_id -> Uuid,
valid_until -> Timestamp,
issued -> Timestamp,
}
}