auth-service / app /controllers /merchant_controller.py
Prabha-AIMLOPS's picture
updated get otp to support login and register, implemented protected apis and other improvements
1a3a466
import logging
from typing import Optional
from datetime import datetime, timedelta
from fastapi import APIRouter, HTTPException, Query, Depends, status, Body
from app.models.merchant import MerchantRegister, GetOtpRequest
from app.services.merchant_services import generate_and_send_otp, get_otp_from_cache, verify_otp_and_save_merchant, validate_merchant
# Initialize router and logger
router = APIRouter(prefix="/merchant")
logger = logging.getLogger(__name__)
@router.post("/register")
async def register_customer(user: MerchantRegister = Body(...)):
"""
API endpoint to register a new Merchant.
Args:
user (MerchantRegister): The details of the Merchant to register.
Returns:
dict: Confirmation message indicating email and SMS verification pending.
"""
try:
logger.info("Registering a new Merchant with Merchant name : %s, email: %s and mobile: %s", user.merchant_name, user.email, user.mobile)
# Validate email and mobile format
validation_result = await validate_merchant(user)
if validation_result["status"] == "error":
logger.error("Validation failed: %s", validation_result["errors"])
raise HTTPException(status_code=400, detail=validation_result["errors"])
return user.dict()
except HTTPException as e:
logger.error("Failed to register merchant: %s", e.detail)
raise e
except Exception as e:
logger.error("Unexpected error while registering merchant: %s", e)
raise HTTPException(status_code=500, detail="Failed to register Merchant") from e
@router.post("/otp/verify")
async def customer_otp_verification(user: MerchantRegister = Body(...)):
"""
API endpoint to validate OTPs and save the complete Merchant object.
Args:
user (MerchantRegister): The complete Merchant object including email, mobile, and OTPs.
Returns:
dict: Confirmation message indicating success or failure.
"""
try:
logger.info("Verifying OTPs and registering merchant with email: %s and mobile: %s", user.email, user.mobile)
# Verify OTPs and save customer
result = await verify_otp_and_save_merchant(user)
if result["status"] == "error":
raise HTTPException(status_code=400, detail=result["errors"])
return {"message": "Merchant successfully registered and verified."}
except HTTPException as e:
logger.error("Failed to verify and register merchant: %s", e.detail)
raise e
except Exception as e:
logger.error("Unexpected error while verifying and registering merchant: %s", e)
raise HTTPException(status_code=500, detail="Failed to verify and register merchant") from e
@router.post("/otp/get")
async def get_otps(payload: GetOtpRequest):
"""
API endpoint to retrieve the email or SMS OTP from Redis cache.
Args:
payload (GetOtpRequest): The request payload containing the identifier and type.
Returns:
dict: The OTP data if found, or an error message if not found.
"""
try:
logger.info("Retrieving OTP for identifier: %s, type: %s", payload.identifier, payload.type)
# Construct the Redis key based on the type
redis_key = f"otp:{payload.type}:{payload.identifier}"
# Retrieve OTP from Redis
otp_data = await get_otp_from_cache(redis_key)
if not otp_data:
raise HTTPException(status_code=404, detail="OTP not found or expired")
return {"identifier": payload.identifier, "type": payload.type, "otp_data": otp_data}
except HTTPException as e:
logger.error("Failed to retrieve OTP for identifier %s, type %s: %s", payload.identifier, payload.type, e.detail)
raise e
except Exception as e:
logger.error("Unexpected error while retrieving OTP for identifier %s, type %s: %s", payload.identifier, payload.type, e)
raise HTTPException(status_code=500, detail="Failed to retrieve OTP") from e
@router.post("/otp/regenerate")
async def regenerate_otp(user: MerchantRegister = Body(...)):
"""
API endpoint to regenerate an OTP for a given email, mobile number, or both.
Args:
user (MerchantRegister): The Merchant object containing email and mobile details.
Returns:
dict: Confirmation message indicating the OTP has been regenerated.
"""
try:
logger.info("Regenerating OTP for Merchant with email: %s and mobile: %s", user.email, user.mobile)
# Regenerate OTP for email & mobile
if user.email and user.mobile:
await generate_and_send_otp(user.email, user.mobile)
return {"message": "OTP successfully regenerated for email and/or mobile.", "email": user.email, "mobile": user.mobile}
except Exception as e:
logger.error("Failed to regenerate OTP for Merchant with email: %s and mobile: %s. Error: %s", user.email, user.mobile, e)
raise HTTPException(status_code=500, detail="Failed to regenerate OTP") from e