From d3a733d9bec4bb9fc341f8cf25a2003d1f9878bd Mon Sep 17 00:00:00 2001 From: Patrick Burke Date: Thu, 16 Jan 2025 11:26:20 -0500 Subject: [PATCH 1/3] Rename request_attributes method to build_request_attributes It was being masked in the constructor as the result of the method call was being assigned to a property also named request_attributes. --- tests/protocol_test_suite_helper.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/protocol_test_suite_helper.py b/tests/protocol_test_suite_helper.py index d986ba9..5710108 100644 --- a/tests/protocol_test_suite_helper.py +++ b/tests/protocol_test_suite_helper.py @@ -41,12 +41,12 @@ def cases(self): class ProtocolTestSuiteParser: def __init__(self, case_path): self.case_name = os.path.basename(case_path) - self.request_attributes = self.request_attributes(case_path) + self.request_attributes = self.build_request_attributes(case_path) self.sts = self.read_file_by_extension(case_path, "sts") self.sig = self.read_file_by_extension(case_path, "sig") self.auth_headers = self.read_json_by_extension(case_path, "authz") - def request_attributes(self, case_path): + def build_request_attributes(self, case_path): req = self.read_json_by_extension(case_path, "req") body_file_path = os.path.join(case_path, req["body_filepath"]) if "body_filepath" in req else "" body = self.read_file(body_file_path, "rb") if body_file_path else req.get("body") From d128dca94939cae7538b0a01e89066c984ff85d5 Mon Sep 17 00:00:00 2001 From: Patrick Burke Date: Thu, 16 Jan 2025 11:17:28 -0500 Subject: [PATCH 2/3] Ensure EPOCH_DATETIME is in UTC This fixes an issue with the time set by @freeze_time being different than the expected EPOCH value. --- tests/signer_test.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/signer_test.py b/tests/signer_test.py index 1131473..de546bc 100644 --- a/tests/signer_test.py +++ b/tests/signer_test.py @@ -1,5 +1,5 @@ import unittest -from datetime import datetime +from datetime import datetime, timezone import os from freezegun import freeze_time from mauth_client.signable import RequestSignable @@ -7,7 +7,7 @@ APP_UUID = "5ff4257e-9c16-11e0-b048-0026bbfffe5e" EPOCH = "1309891855" # 2011-07-05 18:50:00 UTC -EPOCH_DATETIME = datetime.fromtimestamp(float(EPOCH)) +EPOCH_DATETIME = datetime.fromtimestamp(float(EPOCH), timezone.utc) REQUEST_ATTRIBUTES = {"method": "GET", "url": "https://example.org/studies/123/users?k=v"} ADDITIONAL_ATTRIBUTES = {"app_uuid": APP_UUID, "time": EPOCH} @@ -40,7 +40,7 @@ def test_signed_headers(self): "MCC-Time": EPOCH, } - signed_headers = self.signer.signed_headers(self.signable, ADDITIONAL_ATTRIBUTES) + signed_headers = self.signer.signed_headers(self.signable) self.assertEqual(signed_headers.keys(), expected.keys()) self.assertRegex(signed_headers["X-MWS-Authentication"], expected["X-MWS-Authentication"]) self.assertRegex(signed_headers["MCC-Authentication"], expected["MCC-Authentication"]) @@ -51,7 +51,7 @@ def test_signed_headers(self): def test_signed_headers_v1_only(self): expected = {"X-MWS-Authentication": r"\AMWS {}:".format(APP_UUID), "X-MWS-Time": EPOCH} - signed_headers = self.signer_v1_only.signed_headers(self.signable, ADDITIONAL_ATTRIBUTES) + signed_headers = self.signer_v1_only.signed_headers(self.signable) self.assertEqual(signed_headers.keys(), expected.keys()) self.assertRegex(signed_headers["X-MWS-Authentication"], expected["X-MWS-Authentication"]) self.assertEqual(signed_headers["X-MWS-Time"], expected["X-MWS-Time"]) @@ -60,7 +60,7 @@ def test_signed_headers_v1_only(self): def test_signed_headers_v2_only(self): expected = {"MCC-Authentication": r"MWSV2 {}:[^;]*;".format(APP_UUID), "MCC-Time": EPOCH} - signed_headers = self.signer_v2_only.signed_headers(self.signable, ADDITIONAL_ATTRIBUTES) + signed_headers = self.signer_v2_only.signed_headers(self.signable) self.assertEqual(signed_headers.keys(), expected.keys()) self.assertRegex(signed_headers["MCC-Authentication"], expected["MCC-Authentication"]) self.assertEqual(signed_headers["MCC-Time"], expected["MCC-Time"]) From a3d91fe89c8c92fd3b5e9ca192db5c00bccf9a22 Mon Sep 17 00:00:00 2001 From: Patrick Burke Date: Thu, 16 Jan 2025 11:45:52 -0500 Subject: [PATCH 3/3] Ensure TEST_SUITE.request_time is in UTC This fixes an issue with the time set by @freeze_time being different than the original test case request time. --- tests/protocol_test_suite_helper.py | 6 +++--- tests/protocol_test_suite_test.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/protocol_test_suite_helper.py b/tests/protocol_test_suite_helper.py index 5710108..818fac7 100644 --- a/tests/protocol_test_suite_helper.py +++ b/tests/protocol_test_suite_helper.py @@ -1,7 +1,7 @@ # file to handle loading and parsing of mauth protocol test suite cases in order # to run them as unit tests -from datetime import datetime +from datetime import datetime, timezone import glob import os import json @@ -29,7 +29,7 @@ def __init__(self): with open(os.path.join(MAUTH_PROTOCOL_DIR, "signing-params/rsa-key-pub"), "r") as key_file: self.public_key = key_file.read() - self.request_time = datetime.fromtimestamp(float(config["request_time"])) + self.request_time = datetime.fromtimestamp(float(config["request_time"]), timezone.utc) self.app_uuid = config["app_uuid"] self.signer = Signer(config["app_uuid"], private_key, "v2") self.additional_attributes = {"app_uuid": config["app_uuid"], "time": config["request_time"]} @@ -44,7 +44,7 @@ def __init__(self, case_path): self.request_attributes = self.build_request_attributes(case_path) self.sts = self.read_file_by_extension(case_path, "sts") self.sig = self.read_file_by_extension(case_path, "sig") - self.auth_headers = self.read_json_by_extension(case_path, "authz") + self.auth_headers = {k: str(v) for k, v in self.read_json_by_extension(case_path, "authz").items()} def build_request_attributes(self, case_path): req = self.read_json_by_extension(case_path, "req") diff --git a/tests/protocol_test_suite_test.py b/tests/protocol_test_suite_test.py index c48a133..ed54fda 100644 --- a/tests/protocol_test_suite_test.py +++ b/tests/protocol_test_suite_test.py @@ -27,7 +27,7 @@ def test_protocol_test_suite(self): for case_path in TEST_SUITE.cases(): parser = ProtocolTestSuiteParser(case_path) request_signable = RequestSignable(**parser.request_attributes) - signed_headers_v2 = TEST_SUITE.signer.signed_headers_v2(request_signable, TEST_SUITE.additional_attributes) + signed_headers_v2 = TEST_SUITE.signer.signed_headers_v2(request_signable) if "authentication-only" not in case_path: with self.subTest(test="string_to_sign_v2", case_name=parser.case_name): string_to_sign = request_signable.string_to_sign_v2(TEST_SUITE.additional_attributes)