From c20ee4712d24acbe25d4a69066d4160acd5ee606 Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Mon, 16 Dec 2024 18:24:36 +0100 Subject: [PATCH] fix tests and data structure for callback --- src/edutap/wallet_google/handlers/fastapi.py | 7 ++++--- src/edutap/wallet_google/handlers/validate.py | 19 ++++++++++--------- src/edutap/wallet_google/models/callback.py | 4 +++- src/edutap/wallet_google/settings.py | 1 + .../test_wallet_google_plugins/plugins.py | 3 ++- tests/test_handler_validate.py | 2 ++ 6 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/edutap/wallet_google/handlers/fastapi.py b/src/edutap/wallet_google/handlers/fastapi.py index 91ab114..181bf23 100644 --- a/src/edutap/wallet_google/handlers/fastapi.py +++ b/src/edutap/wallet_google/handlers/fastapi.py @@ -23,9 +23,6 @@ async def handle_callback(request: Request, callback_data: CallbackData): It is called by Google Wallet API when a user interacts with a pass. The callback is triggered on save and delete of a pass in the wallet. """ - callback_message = verified_signed_message(callback_data) - logger.debug(f"Got message {callback_message}") - # get the registered callback handlers handlers = get_callback_handlers() if len(handlers) == 0: @@ -34,6 +31,10 @@ async def handle_callback(request: Request, callback_data: CallbackData): status_code=500, detail="No callback handlers were registered." ) + # extract and verify message (given verification is not disabled) + callback_message = verified_signed_message(callback_data) + logger.debug(f"Got message {callback_message}") + # call each handler asynchronously try: await asyncio.gather( diff --git a/src/edutap/wallet_google/handlers/validate.py b/src/edutap/wallet_google/handlers/validate.py index 693e033..5995ac6 100644 --- a/src/edutap/wallet_google/handlers/validate.py +++ b/src/edutap/wallet_google/handlers/validate.py @@ -1,7 +1,7 @@ from .._vendor.google_pay_token_decryption import GooglePayTokenDecryptor from ..models.callback import CallbackData from ..models.callback import SignedMessage -from ..settings import Settings +from ..session import session_manager def _raw_private_key(in_key: str) -> str: @@ -23,11 +23,12 @@ def verified_signed_message(data: CallbackData) -> SignedMessage: Verifies the signature of the callback data. and returns the parsed SignedMessage """ - settings = Settings() - decryptor = GooglePayTokenDecryptor( - settings.google_root_signing_public_keys.dict()["keys"], - settings.issuer_id, - _raw_private_key(settings.credentials_info["private_key"]), - ) - decryptor.verify_signature(data.model_dump(mode="json")) - return SignedMessage.model_validate(data.signedMessage) + settings = session_manager.settings + if settings.callback_verify_signature: + decryptor = GooglePayTokenDecryptor( + settings.google_root_signing_public_keys.dict()["keys"], + settings.issuer_id, + _raw_private_key(settings.credentials_info["private_key"]), + ) + decryptor.verify_signature(data.model_dump(mode="json")) + return SignedMessage.model_validate_json(data.signedMessage) diff --git a/src/edutap/wallet_google/models/callback.py b/src/edutap/wallet_google/models/callback.py index 39219a2..f5b202a 100644 --- a/src/edutap/wallet_google/models/callback.py +++ b/src/edutap/wallet_google/models/callback.py @@ -24,8 +24,10 @@ class IntermediateSigningKey(Model): class SignedMessage(Model): classId: str objectId: str - expTimeMillis: int eventType: EventType + expTimeMillis: int + count: int + nonce: str class CallbackData(Model): diff --git a/src/edutap/wallet_google/settings.py b/src/edutap/wallet_google/settings.py index d756902..f02fc15 100644 --- a/src/edutap/wallet_google/settings.py +++ b/src/edutap/wallet_google/settings.py @@ -46,6 +46,7 @@ class Settings(BaseSettings): save_url: HttpUrl = HttpUrl(SAVE_URL) callback_url: HttpUrl | None = None callback_prefix: str = "/googlewallet" + callback_verify_signature: bool = True scopes: list[str] = [SCOPE] diff --git a/tests/data/test_wallet_google_plugins/plugins.py b/tests/data/test_wallet_google_plugins/plugins.py index b30129d..34bcbce 100644 --- a/tests/data/test_wallet_google_plugins/plugins.py +++ b/tests/data/test_wallet_google_plugins/plugins.py @@ -1,3 +1,4 @@ +from edutap.wallet_google.models.callback import CallbackData from edutap.wallet_google.models.handlers import ImageData @@ -15,4 +16,4 @@ class TestCallbackHandler: Implementation of edutap.wallet_google.protocols.CallbackHandler """ - async def handle(self, pass_id: str) -> None: ... + async def handle(self, pass_id: CallbackData) -> None: ... diff --git a/tests/test_handler_validate.py b/tests/test_handler_validate.py index eac06bb..69ffc72 100644 --- a/tests/test_handler_validate.py +++ b/tests/test_handler_validate.py @@ -16,6 +16,8 @@ "objectId": "2", "expTimeMillis": 0, "eventType": "SAVE", + "count": 0, + "nonce": "3", }, }