diff --git a/backend-services/src/auth_service/operations/twilio_2fa.py b/backend-services/src/auth_service/operations/twilio_2fa.py index 35c9521fb..a64979321 100644 --- a/backend-services/src/auth_service/operations/twilio_2fa.py +++ b/backend-services/src/auth_service/operations/twilio_2fa.py @@ -1,4 +1,5 @@ import asyncio +from concurrent.futures import ThreadPoolExecutor from fastapi import HTTPException from twilio.rest import Client @@ -11,33 +12,55 @@ ) from common.settings import AppSettings +executor = ThreadPoolExecutor() + + +def send_sms(client: Client, params: dict) -> str | None: + # Perform Twilio API calls here + verification = client.verify.v2.services( + params["service_sid"] + ).verifications.create(to=params["phone_number"], channel="sms") + return verification.sid + + +def check_otp_verification(client: Client, params: dict) -> str | None: + # Perform Twilio API calls here + verification_check = client.verify.v2.services( + params["service_sid"] + ).verification_checks.create( + verification_sid=params["verification_sid"], code=params["otp"] + ) + return verification_check.status + async def send_otp_to_user( settings: AppSettings, client: Client, params: SendOtp ) -> SendOtpResponse: loop = asyncio.get_event_loop() - asyncio.set_event_loop(loop) # Set the Twilio client's event loop as the default - - verification = await client.verify.v2.services( - settings.twilio_service_sid - ).verifications.create_async(to=params.phone_number, channel="sms") - - asyncio.set_event_loop(None) # Reset the default event loop - - if verification.sid is None: + send_sms_params = { + "service_sid": settings.twilio_service_sid, + "phone_number": params.phone_number, + } + verification_sid = await loop.run_in_executor( + executor, send_sms, client, send_sms_params + ) + if verification_sid is None: raise HTTPException(500) - return SendOtpResponse(verification_sid=verification.sid) + return SendOtpResponse(verification_sid=verification_sid) async def check_otp_verification_status( settings: AppSettings, client: Client, params: CheckOtpStatus ) -> CheckOtpStatusResponse: - verification_check = await client.verify.v2.services( - settings.twilio_service_sid - ).verification_checks.create_async( - verification_sid=params.verification_sid, code=params.otp + loop = asyncio.get_event_loop() + check_otp_params = { + "service_sid": settings.twilio_service_sid, + "verification_sid": params.verification_sid, + "otp": params.otp, + } + status = await loop.run_in_executor( + executor, check_otp_verification, client, check_otp_params ) - - if verification_check.status is None: + if status is None: raise HTTPException(500) - return CheckOtpStatusResponse(status=verification_check.status) + return CheckOtpStatusResponse(status=status) diff --git a/backend-services/src/web_asgi/main.py b/backend-services/src/web_asgi/main.py index e1b3a0c20..ad7078c6c 100644 --- a/backend-services/src/web_asgi/main.py +++ b/backend-services/src/web_asgi/main.py @@ -6,7 +6,6 @@ from fastapi.middleware.cors import CORSMiddleware from motor.motor_asyncio import AsyncIOMotorClient from odmantic import AIOEngine -from twilio.http.async_http_client import AsyncTwilioHttpClient from twilio.rest import Client as TwilioClient from auth_service.schema.actions import ( @@ -60,11 +59,9 @@ database=app_settings.wallet_db_name, ) -twilio_http_client = AsyncTwilioHttpClient() twilio_client = TwilioClient( app_settings.twilio_account_sid, app_settings.twilio_auth_token, - http_client=twilio_http_client, ) origins = [str(app_settings.primary_origin)]