Forbid password resets after 15 minutes.

This commit is contained in:
Sage Vaillancourt 2022-09-26 09:40:48 -04:00
parent ae1a743855
commit 7800c24f99
2 changed files with 16 additions and 10 deletions

View File

@ -1,7 +1,8 @@
from uuid import uuid4, UUID
import os import os
from dataclasses import dataclass from dataclasses import dataclass
from datetime import datetime, timedelta
from typing import Optional from typing import Optional
from uuid import uuid4, UUID
import bcrypt import bcrypt
import psycopg import psycopg
@ -134,17 +135,21 @@ def initiate_password_reset(email: str) -> Optional[UUID]:
return reset_id return reset_id
RESET_TIME = timedelta(minutes=-1 * 15)
def complete_reset(reset_id: str, new_password: str): def complete_reset(reset_id: str, new_password: str):
with connect() as con: with connect() as con:
cur = con.cursor() cur = con.cursor()
cur.execute("SELECT reset_time, user_id FROM resets WHERE id = %s", (reset_id,)) cur.execute("SELECT reset_time, user_id FROM resets WHERE id = %s", (reset_id,))
row = cur.fetchone() row = cur.fetchone()
if row: if not row or not row[0]:
reset_time, user_id = row return False
if reset_time: # TODO: And reset_time is not too far in the past reset_time, user_id = row
cur.execute("DELETE FROM resets WHERE id = %s", (reset_id,)) if reset_time > (datetime.utcnow() + RESET_TIME):
password_hash = __gen_pw_hash(new_password) cur.execute("DELETE FROM resets WHERE id = %s", (reset_id,))
cur.execute("UPDATE users SET password = %s WHERE id = %s", (password_hash, user_id)) password_hash = __gen_pw_hash(new_password)
con.commit() cur.execute("UPDATE users SET password = %s WHERE id = %s", (password_hash, user_id))
return True con.commit()
return True
return False return False

View File

@ -166,7 +166,8 @@ def reset_password():
elif existing_reset_id: elif existing_reset_id:
# TODO: Eventually remove db entry whether or not link is clicked # TODO: Eventually remove db entry whether or not link is clicked
new_password = request.form['password'] new_password = request.form['password']
db.complete_reset(existing_reset_id, new_password) if not db.complete_reset(existing_reset_id, new_password):
return render_index(error="Password reset failed. Your reset link may have expired.", status=500)
# TODO: Log in? # TODO: Log in?
return redirect('/') return redirect('/')