odapi/database/crud.py

135 lines
3.6 KiB
Python
Raw Normal View History

2020-09-28 18:19:59 +02:00
from datetime import datetime
from fastapi import HTTPException
from hashlib import sha1
2020-09-30 11:27:48 +02:00
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"])
2020-09-30 11:27:48 +02:00
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
def instantiate_model(model, data):
table = eval(model)
instance = table(**data.dict())
return instance
def insert_data(model, data, db):
item = instantiate_model(model=model, data=data)
db.add(item)
db.commit()
db.refresh(item)
return item
# FIXME db.id has to be replaced with the table's UID
def delete_data(model, data, db):
item = instantiate_model(model=model, data=data)
result = db.query(item).filter(item.email == data.email).delete()
return result
2020-09-28 18:19:59 +02:00
def fetch_user_by_key(data, db):
return db.query(Users).filter(Users.access_key == data.access_key).first()
2020-09-28 18:19:59 +02:00
def fetch_user_by_email(data, db):
return db.query(Users).filter(Users.email == data.email).first()
2020-04-19 21:30:41 +02:00
def create_user(data, db):
2020-09-30 11:27:48 +02:00
data.password = pwd_context.hash(data.password)
user = insert_data(model="Users", data=data, db=db)
return user
def update_otp(data: OTPResend, db):
db.query(Users).filter(Users.email == data.email).update(
{Users.otp: data.otp, Users.otp_valid_time: data.otp_valid_time}
)
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")
2020-09-28 18:19:59 +02:00
return user
2020-04-19 21:30:41 +02:00
def activate_account(user, db):
db.query(Users).filter(Users.access_key == user.access_key).update(
{Users.status: 1}
)
db.commit()
db.refresh(user)
def verify_otp(data: OTPVerify, db):
2020-09-28 18:19:59 +02:00
user = fetch_user_by_key(data=data, db=db)
matching_otp = user.otp == data.otp
valid_time = datetime.now() < user.otp_valid_time
valid_otp = matching_otp and valid_time
if valid_otp:
activate_account(user=user, db=db)
return user
2020-09-28 18:19:59 +02:00
else:
raise HTTPException(status_code=400, detail="The OTP is not correct")