From 6c4d6919d7ef893e62a91ba2cbb9f17e7a8f5291 Mon Sep 17 00:00:00 2001 From: coolneng Date: Thu, 8 Oct 2020 21:23:19 +0200 Subject: [PATCH] Implement password reset --- app/routes.py | 5 +++++ app/schemas.py | 30 ++++++++++++++++++++++++++---- database/crud.py | 19 ++++++++++++++++++- tests/requests_test.py | 6 ++++++ 4 files changed, 55 insertions(+), 5 deletions(-) diff --git a/app/routes.py b/app/routes.py index 824198d..768967f 100644 --- a/app/routes.py +++ b/app/routes.py @@ -37,7 +37,12 @@ def deliver_otp(data: OTPResend, db: Session = Depends(get_db)): @router.post("/forgot_password", response_model=ForgotPasswordResponse) def forgot_password(data: ForgotPassword, db: Session = Depends(get_db)): mark_password_reset(data=data, db=db) + update_otp(data=data, db=db) response = resend_otp(data=data, db=db) return response +@router.post("/reset_password", response_model=ResetPasswordResponse) +def reset_password(data: ResetPassword, db: Session = Depends(get_db)): + response = verify_password_reset(data=data, db=db) + return response diff --git a/app/schemas.py b/app/schemas.py index 3e374ae..c8db08a 100644 --- a/app/schemas.py +++ b/app/schemas.py @@ -122,8 +122,15 @@ class OTPResendResponse(UserCreateResponse): orm_mode = True -class ForgotPassword(BaseModel): - email: EmailStr +class ForgotPassword(OTPResend): + pass + + class Config: + orm_mode = True + + +class ResetPassword(ForgotPassword): + password: str class Config: orm_mode = True @@ -138,8 +145,23 @@ class ForgotPasswordResponse(BaseModel): orm_mode = True - access_key: str - otp: int = Query(None, ge=6, le=6) +class ResetPasswordResponse(BaseModel): + message: str = "The password has been updated" class Config: orm_mode = True + + +class MatchesList(BaseModel): + access_key: str + city_id: int + latitude: str + longitude: str + type: Optional[int] = Query(0, ge=0, le=2) + + class Config: + orm_mode = True + + +class MatchesResponse(BaseModel): + pass diff --git a/database/crud.py b/database/crud.py index ae02ff9..8d17724 100644 --- a/database/crud.py +++ b/database/crud.py @@ -54,7 +54,7 @@ def create_user(data, db): return user -def update_otp(data: OTPResend, db): +def update_otp(data, db): db.query(Users).filter(Users.email == data.email).update( {Users.otp: data.otp, Users.otp_valid_time: data.otp_valid_time} ) @@ -121,6 +121,12 @@ def deactivate_account(user, db): db.refresh(user) +def unset_forgot_password(user, db): + db.query(Users).filter(Users.email == user.email).update({Users.forgot_password: 0}) + db.commit() + db.refresh(user) + + def verify_otp(data: OTPVerify, db): user = fetch_user_by_key(data=data, db=db) matching_otp = user.otp == data.otp @@ -143,3 +149,14 @@ def mark_password_reset(data, db): deactivate_account(user=user, db=db) +def verify_password_reset(data, db): + user = fetch_user_by_email(data=data, db=db) + valid_account = user.status + password_reset_request = user.forgot_password + valid_request = valid_account and password_reset_request + if valid_request: + update_password_hash(user=user, password=data.password, db=db) + unset_forgot_password(user=user, db=db) + return user + else: + raise HTTPException(status_code=400, detail="The OTP is not correct") diff --git a/tests/requests_test.py b/tests/requests_test.py index 07c4dff..adcacff 100644 --- a/tests/requests_test.py +++ b/tests/requests_test.py @@ -1,4 +1,5 @@ from secrets import token_hex +from pytest import main from app.schemas import * from database.models import * @@ -54,3 +55,8 @@ def test_forgot_password(): assert response.status_code == 200 +def test_reset_password(): + main(["-k" "test_otp_verification"]) + data = {"email": "oyvey@hotmail.com", "password": "vivashviva"} + response = client.post("/reset_password", json=data) + assert response.status_code == 200