diff --git a/api/blueprints/finstitutions/payments/auth.py b/api/blueprints/finstitutions/payments/auth.py index 7bc4ffc..974af86 100644 --- a/api/blueprints/finstitutions/payments/auth.py +++ b/api/blueprints/finstitutions/payments/auth.py @@ -66,7 +66,7 @@ from shared import constants from bson.objectid import ObjectId # Data Models: -from models.api.software.auth import SoftwareAuthRequestHeaders, SoftwareAuthRequestData +from models.api.finstitutions.payments.auth import PGAuthRequestHeaders, PGAuthRequestData from models.core.auth_token import CoreAuthTokenModel # For asynchronous activities: @@ -81,7 +81,7 @@ import asyncio # Related to Quart: -fi_auth_bp = Blueprint("fi_auth", __name__) +pg_auth_bp = Blueprint("pg_auth", __name__) # ***************************************************************************************************************** @@ -101,7 +101,7 @@ fi_auth_bp = Blueprint("fi_auth", __name__) # ***************************************************************************************************************** -@fi_auth_bp.record_once +@pg_auth_bp.record_once def init(blueprint_setup_state): # This gets called when the blueprint is registered. @@ -112,7 +112,7 @@ def init(blueprint_setup_state): # --------------------------------------------------------------------------------------------------------------------- -@fi_auth_bp.route("/auth", methods = ["POST"]) +@pg_auth_bp.route("/auth", methods = ["POST"]) @set_api_version(api_version = "1.0.0") @read_input(sanitize_headers = False, sanitize_data = False) @get_session_info(key = "X-Session-Token", session_coro = "get_session") @@ -120,7 +120,7 @@ def init(blueprint_setup_state): attr_name = "logs_mongo", project = constants.PROJECT_NAME, log_type = constants.MODULE_NAME, - operation = "smsAuthApi", + operation = "pgAuthApi", log_input = True, log_output = True, sensitive_keys = ["sessionToken", "X-Session-Token"] @@ -128,19 +128,19 @@ def init(blueprint_setup_state): @log_chain_to_mongo(attr_name = "logs_mongo") @should_not_be_under_maintenance(attr_name = "is_under_maintenance") @validate_input( - header_validator = lambda x: SoftwareAuthRequestHeaders(**x).model_dump(), - data_validator = lambda x: SoftwareAuthRequestData(**x) + header_validator = lambda x: PGAuthRequestHeaders(**x).model_dump(), + data_validator = lambda x: PGAuthRequestData(**x) ) @handle_cancelled_request() -async def authorize_software_client( - inbound_headers: dict | SoftwareAuthRequestHeaders = None, - inbound_data: dict | SoftwareAuthRequestData = None, +async def authorize_payment_gateway( + inbound_headers: dict | PGAuthRequestHeaders = None, + inbound_data: dict | PGAuthRequestData = None, inbound_files: dict = None, **kwargs ): """ - God knows. Don't ask. + To accept the authorization details of payment gateways. :param inbound_headers: auto-extracted by the decorators. :param inbound_data: auto-extracted by the decorators. :param inbound_files: auto-extracted by the decorators. @@ -163,19 +163,22 @@ async def authorize_software_client( # Start by assuming failure: success = False - # ┏┳┓┓ ┏┓┏┓ ┏┓┏┏• ┏┓┳ - # ┃ ┣┓┏┓ ┃ ┣┫ ┃┃╋╋┓┏┏┓ ┣┫┃ - # ┻ ┛┗┗ ┗┛┛┗ ┗┛┛┛┗┗┗ ┛┗┻ + # ┏┓ ┏ • ┳┳┓ ┏┓ ┏┓ + # ┗┓┏┓╋┏┓┏┓┓┏┏┓┏┳┓ ┃┃┃━━┃┃┏┓┏┏┓ ┣ ┓┏┏┓┏┓┏┓┏┏ + # ┗┛┗┻┛┗┻┛ ┗┗┗┛┛┗┗ ┛ ┗ ┣┛┗ ┛┗┻ ┗┛┛┗┣┛┛ ┗ ┛┛ + # ┛ - if inbound_data.softwareClient == "theCaOfficeAi": + if inbound_data.client == "safaricomMPesaExpress": auth_token = CoreAuthTokenModel( - serviceType = "software", - client = inbound_data.softwareClient, + serviceType = "paymentGateway", + client = inbound_data.client, authType = "auth", auth = inbound_data.auth.model_dump(), user = kwargs.get("session_info"), - clientUserId = {}, + clientUserId = { + "businessShortCode": inbound_data.auth.businessShortCode + }, status = "active", syncFreq = 60 ) @@ -207,7 +210,7 @@ async def authorize_software_client( status_code = StatusCodes.OK if success else StatusCodes.FAILED, http_code = HttpCodes.SUCCESS if success else HttpCodes.INTERNAL_SERVER_ERROR, data = { - "client": inbound_data.softwareClient, + "client": inbound_data.client, "authorized": success } ) diff --git a/api/main.py b/api/main.py index 65ca6e9..bb59a3c 100644 --- a/api/main.py +++ b/api/main.py @@ -96,6 +96,7 @@ from api.blueprints.sms.send import sms_send_bp # from api.blueprints.chat.auth import chat_auth_bp # from api.blueprints.chat.webhook import chat_webhook_bp from api.blueprints.software.auth import sw_auth_bp +from api.blueprints.finstitutions.payments.auth import pg_auth_bp from api.blueprints.tech.chat_alerts import tech_chat_alert_bp from api.blueprints.test.callback import test_callback_bp from api.blueprints.ai.llm.invoke import llm_invoke_bp @@ -137,6 +138,7 @@ app.register_blueprint(sms_send_bp, url_prefix = f"/{MODULE_BASE}/sms") # app.register_blueprint(chat_auth_bp, url_prefix = f"/{MODULE_BASE}/chat") # app.register_blueprint(chat_webhook_bp, url_prefix = f"/{MODULE_BASE}/chat") app.register_blueprint(sw_auth_bp, url_prefix = f"/{MODULE_BASE}/software") +app.register_blueprint(pg_auth_bp, url_prefix = f"/{MODULE_BASE}/finstitutions/payments") app.register_blueprint(tech_chat_alert_bp, url_prefix = f"/{MODULE_BASE}/tech/alert") app.register_blueprint(test_callback_bp, url_prefix = f"/{MODULE_BASE}/test") app.register_blueprint(llm_invoke_bp, url_prefix = f"/{MODULE_BASE}/ai") diff --git a/models/api/finstitutions/payments/auth.py b/models/api/finstitutions/payments/auth.py index 0f1966f..bd6c515 100644 --- a/models/api/finstitutions/payments/auth.py +++ b/models/api/finstitutions/payments/auth.py @@ -75,25 +75,25 @@ REGEX_SESSION_TOKEN = r"^[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9] # ***************************************************************************************************************** -class TheCAOfficeAIAuth(BaseModel): +class SafaricomMPesaExpressAuth(BaseModel): - authorizeSoftware: bool = Field( - description = "god knows; don't ask", + consumerKey: str = Field( + description = "the app's consumer key given by safaricom; found in 'my apps'", frozen = True ) - authorizeMailMessaging: bool = Field( - description = "god knows; don't ask", + consumerSecret: str = Field( + description = "the app's consumer secret given by safaricom; found in 'my apps'", frozen = True ) - authorizeCompliancePortal: bool = Field( - description = "god knows; don't ask", + businessShortCode: str = Field( + description = "your app's business short code; found in 'my apps'", frozen = True ) - authorizeFinancialInstitution: bool = Field( - description = "god knows; don't ask", + appPasskey: str = Field( + description = "your app's passkey; taken from human representative", frozen = True ) @@ -109,7 +109,7 @@ class TheCAOfficeAIAuth(BaseModel): # --------------------------------------------------------------------------------------------------------------------- -class SoftwareAuthRequestHeaders(BaseModel): +class PGAuthRequestHeaders(BaseModel): sessionToken: str = Field( description = "the session token of the user who is requesting the service", @@ -133,10 +133,10 @@ class SoftwareAuthRequestHeaders(BaseModel): # --------------------------------------------------------------------------------------------------------------------- -class SoftwareAuthRequestData(BaseModel): +class PGAuthRequestData(BaseModel): - softwareClient: Literal["theCaOfficeAi"] = Field(alias = "client") - auth: Union[TheCAOfficeAIAuth] + client: Literal["safaricomMPesaExpress"] = Field(alias = "client") + auth: Union[SafaricomMPesaExpressAuth] # ┏┓ ┏• # ┃ ┏┓┏┓╋┓┏┓ diff --git a/models/core/auth_token.py b/models/core/auth_token.py index 7541d49..b5abc62 100644 --- a/models/core/auth_token.py +++ b/models/core/auth_token.py @@ -89,7 +89,7 @@ class CoreAuthTokenModel(BaseModel): alias = "_id" ) - serviceType: Literal["software", "email", "sms", "chat"] = Field( + serviceType: Literal["software", "email", "sms", "chat", "paymentGateway"] = Field( description = "the kind of service this message was sent/received from", frozen = True ) @@ -99,7 +99,7 @@ class CoreAuthTokenModel(BaseModel): "telegram", "whatsapp", # .................. Chat Clients "nimbusSmsIndia", "savvyBulkSmsKenya", # ... SMS Clients "razorpay", "safaricomMPesaExpress", # ..... Payment Gateways - "theCaOfficeAi" # .......................... God knows, don't ask. + "theCaOfficeAi" # .......................... Software ] = Field( description = "the third-part client that was used", frozen = True