File size: 3,701 Bytes
b856986 9e798a1 b856986 8450c71 b856986 9e798a1 8450c71 9e798a1 b856986 8450c71 9e798a1 b856986 9e798a1 b856986 9e798a1 b856986 9e798a1 b856986 9e798a1 b856986 9e798a1 b856986 9e798a1 b856986 9e798a1 b856986 9e798a1 b856986 9e798a1 b856986 9e798a1 b856986 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
from fastapi import APIRouter, HTTPException, status
from .Schema import (
RegisterUserRequest,
LoginUserRequest,
AccessTokenResponse,
ForgotPasswordRequest,
VerifyResetTokenRequest,
ResetPasswordRequest,
BaseResponse,
)
from .Model import User
from jose import jwt
from datetime import datetime, timedelta
# JWT Configurations
SECRET_KEY = "your_secret_key_here"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30
user_router = APIRouter(tags=["User"])
def create_access_token(data: dict, expires_delta: timedelta = None):
to_encode = data.copy()
expire = datetime.utcnow() + (
expires_delta or timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
)
to_encode.update({"exp": expire})
return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
@user_router.post(
"/user/register", response_model=BaseResponse, status_code=status.HTTP_201_CREATED
)
async def register_user(request: RegisterUserRequest):
existing_user = await User.filter(phoneNumber=request.phoneNumber).first()
if existing_user:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail="User already exists."
)
request.hash_password()
new_user = await User.create(**request.dict())
return BaseResponse(
code=200, message="User created successfully", payload={"user_id": new_user.id}
)
@user_router.post(
"/user/login", response_model=AccessTokenResponse, status_code=status.HTTP_200_OK
)
async def login_user(request: LoginUserRequest):
db_user = await User.filter(phoneNumber=request.phoneNumber).first()
if db_user and db_user.verify_password(request.password):
access_token = create_access_token(data={"sub": db_user.phoneNumber})
return AccessTokenResponse(access_token=access_token, token_type="bearer")
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid credentials"
)
@user_router.post(
"/user/forgot-password", response_model=BaseResponse, status_code=status.HTTP_200_OK
)
async def forgot_password(request: ForgotPasswordRequest):
user = await User.filter(phoneNumber=request.phoneNumber).first()
if not user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="User not found."
)
await user.initiate_password_reset()
return BaseResponse(code=200, message="Password reset token sent to your phone.")
@user_router.post(
"/user/verify-reset-token",
response_model=BaseResponse,
status_code=status.HTTP_200_OK,
)
async def verify_reset_token(request: VerifyResetTokenRequest):
user = await User.filter(
phoneNumber=request.phoneNumber, reset_token=request.reset_token
).first()
if not user or datetime.utcnow() > user.reset_token_expiration:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail="Invalid or expired token."
)
return BaseResponse(code=200, message="Token verified. Proceed to reset password.")
@user_router.post(
"/user/reset-password", response_model=BaseResponse, status_code=status.HTTP_200_OK
)
async def reset_password(request: ResetPasswordRequest):
user = await User.filter(phoneNumber=request.phoneNumber).first()
if not user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="User not found."
)
if not await user.reset_password(request.reset_token, request.new_password):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail="Invalid or expired token."
)
return BaseResponse(code=200, message="Password has been reset successfully.")
|