68 logger.info(f
"POST /api/2fa/authorize/ - data: {request.data}")
73 if not serializer.is_valid():
74 logger.error(f
"Error de validación: {serializer.errors}")
75 return Response({
'error':
'Datos inválidos',
'detalles': serializer.errors}, status=400)
77 email = serializer.validated_data[
'email']
78 monto = serializer.validated_data[
'monto']
79 titular = serializer.validated_data[
'titular']
80 code = serializer.validated_data.get(
'code')
82 logger.info(f
"AuthorizePurchase: email={email}, monto={monto}, titular={titular}, code={code}")
85 user2fa, created = User2FA.objects.get_or_create(email=email)
87 logger.info(f
"Se creó un nuevo usuario 2FA: {email}")
88 user2fa.secret = pyotp.random_base32()
96 motivo.append(
'monto')
99 if titular.strip().lower()
not in email.strip().lower():
101 motivo.append(
'titular')
104 if not user2fa.enabled:
105 logger.info(f
"2FA requerido pero no configurado para {email}")
106 return Response({
'requiere_2fa':
True,
'motivo': motivo,
'configurado':
False}, status=200)
109 logger.info(f
"2FA requerido, esperando código para {email}")
110 return Response({
'requiere_2fa':
True,
'motivo': motivo,
'configurado':
True}, status=200)
112 totp = pyotp.TOTP(user2fa.secret)
113 if not totp.verify(code):
114 logger.warning(f
"Código 2FA inválido para {email}")
115 return Response({
'error':
'Código 2FA inválido'}, status=400)
117 logger.info(f
"Compra autorizada con 2FA para {email}")
118 return Response({
'autorizado':
True,
'motivo': motivo})
120 logger.info(f
"Compra autorizada sin 2FA para {email}")
121 return Response({
'autorizado':
True,
'motivo': motivo})
123 except Exception
as e:
124 logger.error(f
"Error inesperado: {str(e)}", exc_info=
True)
125 return Response({
'error':
'Error interno del servidor'}, status=500)