Implement login with secure password rehashing
This commit is contained in:
@@ -1,13 +1,15 @@
|
||||
from datetime import datetime
|
||||
from fastapi import HTTPException
|
||||
from hashlib import sha1
|
||||
from passlib.context import CryptContext
|
||||
|
||||
from app.schemas import *
|
||||
from constants import SHA1_SALT
|
||||
from database import SessionLocal
|
||||
from database.models import *
|
||||
|
||||
|
||||
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
||||
pwd_context = CryptContext(schemes=["bcrypt"])
|
||||
|
||||
|
||||
def get_db():
|
||||
@@ -60,7 +62,55 @@ def update_otp(data: OTPResend, db):
|
||||
db.commit()
|
||||
|
||||
|
||||
)
|
||||
def rehash_password(password):
|
||||
return pwd_context.hash(secret=password)
|
||||
|
||||
|
||||
def update_password_hash(user, password, db):
|
||||
new_hash = rehash_password(password=password)
|
||||
db.query(Users).filter(Users.email == user.email).update({Users.password: new_hash})
|
||||
db.commit()
|
||||
db.refresh(user)
|
||||
|
||||
|
||||
def check_sha1_hash(db_hash):
|
||||
hash_length = len(db_hash)
|
||||
sha1_length = 40
|
||||
if hash_length == sha1_length:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def verify_legacy_password(user, password, db):
|
||||
hash = SHA1_SALT + password
|
||||
correct_password = user.password == sha1(hash.encode("utf-8")).hexdigest()
|
||||
if correct_password:
|
||||
update_password_hash(user=user, password=password, db=db)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def verify_updated_password(user, password):
|
||||
return pwd_context.verify(secret=password, hash=user.password)
|
||||
|
||||
|
||||
def verify_password(user, password, db):
|
||||
legacy_hash = check_sha1_hash(user.password)
|
||||
if legacy_hash:
|
||||
return verify_legacy_password(user=user, password=password, db=db)
|
||||
return verify_updated_password(user=user, password=password)
|
||||
|
||||
|
||||
def authenticate_user(data: UserLogin, db):
|
||||
user = fetch_user_by_email(data=data, db=db)
|
||||
if not user:
|
||||
raise HTTPException(status_code=400, detail="Incorrect username or password")
|
||||
correct_password = verify_password(user=user, password=data.password, db=db)
|
||||
if not correct_password:
|
||||
raise HTTPException(status_code=400, detail="Incorrect username or password")
|
||||
valid_account = user.status
|
||||
if not valid_account:
|
||||
raise HTTPException(status_code=400, detail="Your account is not active")
|
||||
return user
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user