hotspot / App /Users /UserRoutes.py
Mbonea's picture
testing deployment
9e798a1
raw
history blame
3.7 kB
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.")