Implement forgot password
This commit is contained in:
		
							parent
							
								
									3be567c8ac
								
							
						
					
					
						commit
						0b53bbaa70
					
				@ -32,3 +32,12 @@ def deliver_otp(data: OTPResend, db: Session = Depends(get_db)):
 | 
				
			|||||||
    update_otp(data=data, db=db)
 | 
					    update_otp(data=data, db=db)
 | 
				
			||||||
    response = resend_otp(data=data, db=db)
 | 
					    response = resend_otp(data=data, db=db)
 | 
				
			||||||
    return response
 | 
					    return response
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@router.post("/forgot_password", response_model=ForgotPasswordResponse)
 | 
				
			||||||
 | 
					def forgot_password(data: ForgotPassword, db: Session = Depends(get_db)):
 | 
				
			||||||
 | 
					    mark_password_reset(data=data, db=db)
 | 
				
			||||||
 | 
					    response = resend_otp(data=data, db=db)
 | 
				
			||||||
 | 
					    return response
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -122,6 +122,22 @@ class OTPResendResponse(UserCreateResponse):
 | 
				
			|||||||
        orm_mode = True
 | 
					        orm_mode = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ForgotPassword(BaseModel):
 | 
				
			||||||
 | 
					    email: EmailStr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class Config:
 | 
				
			||||||
 | 
					        orm_mode = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ForgotPasswordResponse(BaseModel):
 | 
				
			||||||
 | 
					    otp: int
 | 
				
			||||||
 | 
					    mobile: str = Query(None, min_length=8, max_length=13)
 | 
				
			||||||
 | 
					    message: str = "The OTP has been sent to you via SMS"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class Config:
 | 
				
			||||||
 | 
					        orm_mode = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    access_key: str
 | 
					    access_key: str
 | 
				
			||||||
    otp: int = Query(None, ge=6, le=6)
 | 
					    otp: int = Query(None, ge=6, le=6)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -113,6 +113,14 @@ def activate_account(user, db):
 | 
				
			|||||||
    db.refresh(user)
 | 
					    db.refresh(user)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def deactivate_account(user, db):
 | 
				
			||||||
 | 
					    db.query(Users).filter(Users.email == user.email).update(
 | 
				
			||||||
 | 
					        {Users.status: 0, Users.forgot_password: 1}
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    db.commit()
 | 
				
			||||||
 | 
					    db.refresh(user)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def verify_otp(data: OTPVerify, db):
 | 
					def verify_otp(data: OTPVerify, db):
 | 
				
			||||||
    user = fetch_user_by_key(data=data, db=db)
 | 
					    user = fetch_user_by_key(data=data, db=db)
 | 
				
			||||||
    matching_otp = user.otp == data.otp
 | 
					    matching_otp = user.otp == data.otp
 | 
				
			||||||
@ -123,3 +131,15 @@ def verify_otp(data: OTPVerify, db):
 | 
				
			|||||||
        return user
 | 
					        return user
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        raise HTTPException(status_code=400, detail="The OTP is not correct")
 | 
					        raise HTTPException(status_code=400, detail="The OTP is not correct")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def mark_password_reset(data, db):
 | 
				
			||||||
 | 
					    user = fetch_user_by_email(data=data, db=db)
 | 
				
			||||||
 | 
					    if user.social_id:
 | 
				
			||||||
 | 
					        raise HTTPException(
 | 
				
			||||||
 | 
					            status_code=400,
 | 
				
			||||||
 | 
					            detail="You logged in with Facebook/Google. You can't reset the password",
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    deactivate_account(user=user, db=db)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,5 @@
 | 
				
			|||||||
from sqlalchemy import Column, DateTime, Enum, ForeignKey, Integer, String, Text, text
 | 
					from sqlalchemy import Column, ForeignKey, text
 | 
				
			||||||
 | 
					from sqlalchemy.types import *
 | 
				
			||||||
from sqlalchemy.sql import func
 | 
					from sqlalchemy.sql import func
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from database import Base
 | 
					from database import Base
 | 
				
			||||||
@ -27,6 +28,7 @@ class Users(Base):
 | 
				
			|||||||
    admin_status = Column(Integer, server_default=text("0"))
 | 
					    admin_status = Column(Integer, server_default=text("0"))
 | 
				
			||||||
    device_id = Column(Text)
 | 
					    device_id = Column(Text)
 | 
				
			||||||
    device_type = Column(Integer)
 | 
					    device_type = Column(Integer)
 | 
				
			||||||
 | 
					    forgot_password = Column(Integer, server_default=text("0"))
 | 
				
			||||||
    created = Column(DateTime, nullable=False, server_default=func.now())
 | 
					    created = Column(DateTime, nullable=False, server_default=func.now())
 | 
				
			||||||
    updated = Column(DateTime, nullable=True, onupdate=func.now())
 | 
					    updated = Column(DateTime, nullable=True, onupdate=func.now())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					"""add forgot_password field
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Revision ID: f8ef6bad794a
 | 
				
			||||||
 | 
					Revises: d994081ed483
 | 
				
			||||||
 | 
					Create Date: 2020-10-08 18:04:08.204841
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					from alembic import op
 | 
				
			||||||
 | 
					import sqlalchemy as sa
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# revision identifiers, used by Alembic.
 | 
				
			||||||
 | 
					revision = "f8ef6bad794a"
 | 
				
			||||||
 | 
					down_revision = "d994081ed483"
 | 
				
			||||||
 | 
					branch_labels = None
 | 
				
			||||||
 | 
					depends_on = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def upgrade():
 | 
				
			||||||
 | 
					    with op.batch_alter_table("users") as batch_op:
 | 
				
			||||||
 | 
					        batch_op.add_column(
 | 
				
			||||||
 | 
					            sa.Column("forgot_password", sa.Integer, server_default=sa.text("0")),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def downgrade():
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
@ -25,10 +25,7 @@ def test_registration():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
def test_otp_verification(get_test_db):
 | 
					def test_otp_verification(get_test_db):
 | 
				
			||||||
    user = get_test_db.query(Users).filter(Users.email == "oyvey@hotmail.com").first()
 | 
					    user = get_test_db.query(Users).filter(Users.email == "oyvey@hotmail.com").first()
 | 
				
			||||||
    data = {
 | 
					    data = {"access_key": user.access_key, "otp": user.otp}
 | 
				
			||||||
        "access_key": user.access_key,
 | 
					 | 
				
			||||||
        "otp": user.otp,
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    response = client.post("/otpVerification", json=data)
 | 
					    response = client.post("/otpVerification", json=data)
 | 
				
			||||||
    assert response.status_code == 200
 | 
					    assert response.status_code == 200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -46,8 +43,14 @@ def test_login():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_resend_otp():
 | 
					def test_resend_otp():
 | 
				
			||||||
    data = {
 | 
					    data = {"email": "testorganizer@odyfo.com"}
 | 
				
			||||||
        "email": "testorganizer@odyfo.com",
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    response = client.post("/resendOTP", json=data)
 | 
					    response = client.post("/resendOTP", json=data)
 | 
				
			||||||
    assert response.status_code == 200
 | 
					    assert response.status_code == 200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_forgot_password():
 | 
				
			||||||
 | 
					    data = {"email": "oyvey@hotmail.com"}
 | 
				
			||||||
 | 
					    response = client.post("/forgot_password", json=data)
 | 
				
			||||||
 | 
					    assert response.status_code == 200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user