from fastapi import APIRouter, HTTPException, status from .Schema import ( RegisterUserRequest, LoginUserRequest, AccessTokenResponse, ForgotPasswordRequest, VerifyResetTokenRequest, ResetPasswordRequest, BaseResponse, UserResponse, ) from .Model import User from jose import jwt from typing import List from datetime import datetime, timedelta from App.Android.Android import AndroidClient from App.Android.Schema import RegisterUserRequest as AndroidRegister from App.Templates.Templates import MessageTemplate # JWT Configurations SECRET_KEY = "your_secret_key_here" ALGORITHM = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES = 30 user_router = APIRouter(tags=["User"]) client = AndroidClient() templates = MessageTemplate() 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) # The user registers # It sends userdetails to the router # It sends the user a message to welcome the user @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." ) new_user = await User.create_user(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.") @user_router.get( "/user/all", response_model=List[UserResponse], status_code=status.HTTP_200_OK ) async def get_all_users(): users = await User.all() return [UserResponse.from_orm(user) for user in users] @user_router.delete( "/user/{user_id}", response_model=BaseResponse, status_code=status.HTTP_200_OK ) async def delete_user(user_id: str): user = await User.filter(id=user_id).first() if not user: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="User not found." ) await user.delete() return BaseResponse(code=200, message="User deleted successfully.") @user_router.put( "/user/toggle_status/{user_id}", response_model=BaseResponse, status_code=status.HTTP_200_OK, ) async def toggle_user_status(user_id: str): user = await User.filter(id=user_id).first() if not user: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="User not found." ) user.account_locked = not user.account_locked await user.save() message = ( "User disabled successfully." if user.account_locked else "User enabled successfully." ) return BaseResponse(code=200, message=message)