(20250220)
This commit is contained in:
@@ -146,15 +146,18 @@ class TimedOTPController:
|
||||
self,
|
||||
redis_cache: AsyncRedisCache,
|
||||
inbound_data: GenerateTimedOTP
|
||||
) -> str | None:
|
||||
) -> FunctionCallResponse:
|
||||
|
||||
"""
|
||||
To generate one OTP and store it in cache.
|
||||
:param redis_cache: The instance of the cache client to use to hold the OTP.
|
||||
:param inbound_data: The
|
||||
:return:
|
||||
:param inbound_data: The data from which the OTP will be generated.
|
||||
:return: A structured response to describe what happened in the process.
|
||||
"""
|
||||
|
||||
# Start by assuming failure:
|
||||
response = FunctionCallResponse()
|
||||
|
||||
# Generate the OTP:
|
||||
otp_key = self.KEY_PREFIX + redis_cache.make_key(str(inbound_data.id))
|
||||
otp_client = HashedOTP(secret = HashedOTP.generate_secret())
|
||||
@@ -172,53 +175,12 @@ class TimedOTPController:
|
||||
expiry = inbound_data.seconds
|
||||
)
|
||||
|
||||
# Done here:
|
||||
return otp if otp_stored else None
|
||||
|
||||
async def generate_and_send_sms(
|
||||
self,
|
||||
mongo_data_conn: AsyncMongo,
|
||||
redis_cache: AsyncRedisCache,
|
||||
auth_token: CoreAuthTokenModel,
|
||||
sms_client: SMSController,
|
||||
sms_message: NimbusSMSIndiaMessage | SavvyBulkSMSKenyaMessage,
|
||||
inbound_data: GenerateTimedOTP,
|
||||
tags: List[str] = None
|
||||
) -> FunctionCallResponse:
|
||||
|
||||
"""
|
||||
Generate an OTP and send it via SMS.
|
||||
:param mongo_data_conn: The client to use to connect to the database.
|
||||
:param redis_cache: The client to use to connect to the cache.
|
||||
:param auth_token: The credentials
|
||||
:param sms_client:
|
||||
:param sms_message:
|
||||
:param inbound_data:
|
||||
:param tags:
|
||||
:return:
|
||||
"""
|
||||
|
||||
# Start by assuming failure:
|
||||
response = FunctionCallResponse()
|
||||
|
||||
# Generate the OTP:
|
||||
otp = await self.generate(redis_cache, inbound_data)
|
||||
if not otp:
|
||||
response.message = "Failed to generate OTP."
|
||||
return response
|
||||
|
||||
# Send the SMS:
|
||||
sms_response = await sms_client.send_many_sms(
|
||||
mongo_data_conn = mongo_data_conn,
|
||||
auth_token = auth_token,
|
||||
messages = [sms_message],
|
||||
tags = tags
|
||||
)
|
||||
|
||||
# Analyze the actions:
|
||||
success = True if sms_response.successCount == 1 else False
|
||||
response.success = success
|
||||
response.message = "OTP sent successfully." if success else "OTP could NOT be sent."
|
||||
# Analyze the response:
|
||||
if otp_stored:
|
||||
response.success = True
|
||||
response.message = "OTP generated successfully."
|
||||
response.data = otp
|
||||
else: response.message = "Failed to generate an OTP."
|
||||
|
||||
# Done here:
|
||||
return response
|
||||
@@ -235,9 +197,9 @@ class TimedOTPController:
|
||||
|
||||
"""
|
||||
To verify if an OTP is valid, or not.
|
||||
:param redis_cache:
|
||||
:param inbound_data:
|
||||
:return:
|
||||
:param redis_cache: The instance of the cache client to use to hold the OTP.
|
||||
:param inbound_data: The data from which the OTP will be verified.
|
||||
:return: A structured response to describe what happened in the process.
|
||||
"""
|
||||
|
||||
# Start by assuming failure:
|
||||
|
||||
@@ -630,6 +630,41 @@ class CoreAuthTokenController(CoreBaseModel):
|
||||
# Done here:
|
||||
return [CoreAuthTokenModel(**token) for token in tokens]
|
||||
|
||||
async def get_first_token(
|
||||
self,
|
||||
mongo_data_conn: AsyncMongo,
|
||||
must_be_active: bool = True,
|
||||
additional_filter: dict = None
|
||||
) -> CoreAuthTokenModel | None:
|
||||
|
||||
"""
|
||||
To fetch the first auth-token that matches the given conditions. Good when you have been asked to, say, send an
|
||||
SMS without being specific about which client to send it from. In such a case, tune your conditions such that
|
||||
you fetch the first auth token for an SMS client and use that for the next steps.
|
||||
:param mongo_data_conn: The database connection (MongoDB) to use to perform the action.
|
||||
:param must_be_active: Set this to False if you want to allow pending and disabled accounts to be retrieved.
|
||||
:param additional_filter: Any addition filters to use.
|
||||
:return: The retrieved record that has the token, and information about the service and client if found, else
|
||||
None when there is no matching record.
|
||||
"""
|
||||
|
||||
# Prepare the filter:
|
||||
filter_json = {}
|
||||
if self._base_filter:
|
||||
for k, v in self._base_filter.items(): filter_json[k] = v
|
||||
if additional_filter:
|
||||
for k, v in additional_filter.items(): filter_json[k] = v
|
||||
if must_be_active: filter_json["status"] = "active"
|
||||
|
||||
# If there is some filtering possible, we fetch the token:
|
||||
token = await mongo_data_conn.find_one(
|
||||
collection = self.AUTH_COLLECTION,
|
||||
filter = mongo_data_conn.dict_to_dot_notation(filter_json)
|
||||
)
|
||||
|
||||
# Done here:
|
||||
return None if token is None else CoreAuthTokenModel(**token)
|
||||
|
||||
async def get_batches_to_sync(
|
||||
self,
|
||||
mongo_data_conn: AsyncMongo,
|
||||
|
||||
Reference in New Issue
Block a user