Source code for pyeudiw.tests.trust.handler.test_direct_trust_jar

import json
from dataclasses import dataclass

import pytest
from satosa.context import Context

from pyeudiw.jwk import JWK
from pyeudiw.trust.handler.direct_trust_jar import DirectTrustJar


[docs] @pytest.fixture def signing_private_key() -> list[dict]: return [ { "crv": "P-256", "d": "r8UhwdbIvxKLvObVE-yixibCtu-0nzBZ3QGQ_-i1owc", "kid": "MmjIDEhSnyIha4n462iIzrmdwMnJWlRZnsOJ3LWBEC4", "kty": "EC", "use": "sig", "x": "xEmx9ruaf1qycPoYQ5lIfMSXAz2qLib6n0Ar_WDEiHM", "y": "ZkSlQyYxuVTEKNRdrnONTisTepQ-3VcCza2O2yejawQ", } ]
[docs] @pytest.fixture def rsa_signing_private_key() -> list[dict]: return [{ "kty": "RSA", "use": "sig", "alg": "RS256", "kid": "123114cf-ebef-48d9-9602-3be85e6e12dd", "d": "b41VkvQv083zdtsqX9Q4RqW6DOH7LcSMSSK-KaUi-jtR4SdPkans1vY9QwfZ1gL-iQm0UP50Txow1Xawnh_-O45efpTOJ0sEXno5gXregQQNXxum-ATh7npYTv3Zjfl1lw4GX9UvXwtko3zHA01OtvOdXxtDHtatvoojFEwTisBT5j9f_q7Dmmgmtml17U_M1heANv9O9PqOey2U7_wZRji2lLGpeP7DxeBpTVztyKdnBZCjBnwfyrES3eAPlO5GI3zWAxHuaSsms3F8WQKJqHQs8xDxHpC1MCPMqmnCZnrBxZXxeeg6gMuEJ72RtzziOwH2gr3alND6gpARwwgEYQ", "n": "oV1dBQQpxKhVpJzouceEvuJQ_0nIvK3GVF4FEKRunCWK1amBupkegZgIXq98WsvfNHLwKPhhFXO1unONb44Q51VeFet7ThWyJSB9dhXmr21wvqFA4HVQj4vGPLiGUmacKL-9W4vd_ElLyf1TEtcolUafEI83zfg6bsVkJrwdSRDkxYU5Kh28ayCgoaqXUwLsuR-xT5EiksJESHtqW5_8sqrp5v95UOxxK8NdbEQ54Fr2pfeKQ6Id5VyUlwOnfnV6zgJJ7qBM1NxcyQ7OkQHrh03LfoPF2Hl7-EuZ0ET8p9RVC7eC2NH033O9rSiWljwwsvmRG7nyVN7bkB5wbInp0Q", "e": "AQAB", "p": "0RHnCQZiI6VomMmRcfDyRgqZjUEHLPF17u4TAxqFys3-lgxuRCn8cjXkzJ7t9C0FmGNQy2zrwhQZRUlKotPwB9t0qTRwshqmG40O4EHfdgqu_sqNe8toCJ9xGqkDJFdYvmPy-SkqMYyszRf1GEwMjgj1Ncyx4WciaEbHZUllQo0", "q": "xZYanwkJJGOD4b7Z2PwCA_ubEYU8O2C3UoeINv2P5fXicXRK278o4WelaQBhyvDcPyS3lJyyusB_ro3Fax1fm4IDV1buITar671NzooWKOUQgG0MoVHS8k7qFmGXGDhFBrO_khsvc3FNAjdqkNpH5slo8AwvN2SrbHO3GX6aVVU", "dp": "tk7iJCCI24SVXQYH6k-tNB5yH5ag5zP3Hs5DjeVG3b4bTkSwsofaNs2AIl5EKTRJOMUB4yGrw6U7FAwBJVOib3eSlym_S8-pIUUzv6IxdgGC73M5RMXuhfZi7liLANmZ7QvDCDo5LNP6qy1E8FcAa6qsCKniQydn_X4aydvijNE", "dq": "Ml9mQg1Hq2NDiBXj7BGzYdiPXBQfmvO5SO0MqRhTy0i4hjwjqYo-ndiSrwZN6DMns2Fk_BpG5p2U76dtITXH3hlzSJz88LLDecI1R-akZ6CeaF9kzOvTX7sGqtYOczpFPsQsns8XddL40wvVu0Aq_Id0nV49211q5qdJktJX_lE", "qi": "rQ5SbqNeVrGOZ1rJXWbiAxux_-E1HBunOKWN6HQpoStLpRzJ6zz8aEXhSXMAnbeQOi1ZBS1escmlSupkgz4TEnrhionAJ2orIJ1rOiZIii7stJVkB3fs2LBoxs17Msj9AVrBA-tHhWpoBj63t-ahhEuxhgReq_0DjzQgcP7xUA" }]
[docs] @pytest.fixture def all_private_keys(signing_private_key: list[dict]) -> list[dict]: rsa_pkey = { "d": "l2vENvwM3YVZ7C36mDKGJIjaadzhc_3JSuUrj5PUj1DMRfDf5jElrseIg8hyWhi5n6FqN8uV_2hfw-xUarwx_glFtbe0StqVqHLAYpGg7Id8fe5CKUPsjweNBq9zx9EMKNZl5q_tBW4ZnhyLhbmv-tO0NUz2ht2moOOPsqycNymblxs3bIZKTLxwEfx9rBhXkOUJ8MWciRjvaA1kOTY5pT__AnhmEdqCGaqgSxfmf4tyudatREt7mhnOQqIPtyVPFFCHZHsHv5Akp9U7bA2cbke8NarfBlLbZufzj2sSaVErAn-po1KIB3fuA9HBs4YeDGcRv3hipUJrACMqYm5zhODdSr-P6X-3-FR5EWnSDUDwYeWZ7q1jzGzgKAXEbnn-CXY_JlXaYGfRUqIXui883rr9IjqI-c1TVcSPaSVpnxut9rwfkxuQo7MEbiExODGfXNvbR9S8DWJXWjKmFZklResqK6wWFe7GXkDLDeWRtbtRxEYirIkxPgNt3EXcm3sp", "e": "AQAB", "kid": "KwJFzr11BxhSmAW8D2ZGBDQRdiQXZo1YWGaxHGW5Md8", "kty": "RSA", "n": "wDBeA9a1xgOEb_zwm05cZnblBJANfWBA7oaZRYLp1sl0030pK6jHyEJ4wrXlMMQcxvwOx80uRFJG3o9BLTQ5lPnBu-VMAxF9LTkLZRD_gAJsrHz_myCgfcCMouX9AwDtUC01p5IIZ8YgfrbYPn694RxhCmH09oGs_OwOr7f3aW2qwf7uha7LRy8UPDYULnST7eqqWgrxjSIeHnmeO9BmEfcvqZJD2EfFHwFVXkjwMk1nWnQZYRV7Yncoz3qV0rhIQ86FQ2i4BoMW54OnRrgRHGqVUBHZP2y_Z3xo6foYOXJMgkHcEasiLbiATvHHN1cVsaM0PvQjO15qZu2IvVK224MgY6YbWU88pssG0ydTSOo0bY5gDhY6ml133MKXzfES0dzLNoOALrkyFxiHrPgQiFMKBuPXZ6qk1RomEWZYR54Brd7gDyK66MkdmpHvgBJf_V1YO42U1yxUTg63shdRp4O8FNZoTmhjMT9A_ZCD5mqGo00IewLHiQzVyWDqNrPv", "p": "0P7Vjj2Rc8tGdxqXvg77FsUaJIpoffgHSv59zrctOF7odKRYOSKW9FvlOi01NZE8dkcdYxlnriy3jyQVdGTxbRKJKKHrJbIJpqMDj6wUrk0k-67PbBuAJhzhmU_2wlyd04U7lt8gcn55kyV5XxQta6WTHz11MgO1GKePfCIlTRyS1T26_5wq5a_Q_VcdmiKuBHm0HtkBCkSYTWxWqfQjehs8eR5xOBAasgZHNit1KCMiONeUNyFtVFWgSSjDzhfL", "q": "62ngt1zghnj8pguWq1Xx6hRtE-eFS5K0rn6hSCgkLnUQeZWpO7cB4EEHFbN5FlWFIj9bjrRIoTQtHwprtM7dMqVaBH2HcKwSDiZy9ImmW2peKrP7Ko1t-Eg9Mhm8rycuzrwu3iQdd41JH-My5Fti-IuXyhZ3IVF_JvVNQKf4_RZQD4mbslEc6KFjLT-A3V6wfMhVFw7rnR6GcyQ0YUJTjzhRP3siG1A3GYGF1eN0pqT_3Lk2tvkd174BwcifiGft", "qi": "TFYkChfG3DRtgOiPRzl_yj_CDrYNsGWM-s0GmRHy_Zl1NvHK9u8Pc4hPoS9xx_qZiBnapX_Jmkaz39Q0GsjsJqjQQRxPMIofh1SZzH6O_tJ1-YQhJO4OfsQwi_FIAoDXHetkxnnhG1Axpvfqx5UyKM18uBz1vfWVrpfqaz9EBT04roVR_RFGzzV9jzDXFaZ17SWvovGtpHKqkVrCU0z6D8FV0lhuyBTmee6jXcxfzkwizGR6VexfaVwAHj7OdDGs", "use": "enc", } return signing_private_key + [rsa_pkey]
[docs] @pytest.fixture def direct_trust_jar(all_private_keys): return DirectTrustJar(jwks=all_private_keys)
[docs] def test_direct_trust_jar_build_metadata_path(direct_trust_jar): @dataclass class TestCase: backend_name: str expected_path: str explanation: str test_cases: list[TestCase] = [ TestCase( backend_name="", expected_path=".well-known/jar-issuer", explanation="empty backend name", ), TestCase( backend_name="openid4vp", expected_path="openid4vp/.well-known/jar-issuer", explanation="regular backend name", ), TestCase( backend_name="/openid4vp/", expected_path="openid4vp/.well-known/jar-issuer", explanation="backend name with usual slashes", ), ] for i, case in enumerate(test_cases): path_component = direct_trust_jar._build_metadata_path(case.backend_name) assert ( path_component == case.expected_path ), f"failed case {i+1}: test scenario: {case.explanation}"
[docs] def test_direct_trust_jat_custom_path(all_private_keys): @dataclass class TestCase: endpoint_component: str backend_name: str expected_path: str explanation: str test_cases: list[TestCase] = [ TestCase( endpoint_component="custom", backend_name="openid4vp", expected_path="openid4vp/custom", explanation="custom path", ), TestCase( endpoint_component="/custom-with-slashes/", backend_name="openid4vp", expected_path="openid4vp/custom-with-slashes", explanation="custom path with prepending and appending forward slash", ), ] for i, case in enumerate(test_cases): dtj = DirectTrustJar( jwks=all_private_keys, jwk_endpoint=case.endpoint_component ) path_component = dtj._build_metadata_path(case.backend_name) assert ( path_component == case.expected_path ), f"failed case {i+1}: test scenario: {case.explanation}"
[docs] def test_direct_trust_jar_metadata(direct_trust_jar): backend = "openid4vp" entity_id = f"https://rp.example/{backend}" metadata = direct_trust_jar._build_metadata_with_issuer_jwk(entity_id) assert metadata["issuer"] == entity_id assert len(metadata["jwks"]["keys"]) == 1 pub_key = metadata["jwks"]["keys"][0] assert "d" not in pub_key assert pub_key.get("use", "") != "enc"
[docs] def test_direct_trust_jar_metadata_no_private_key(all_private_keys, rsa_signing_private_key): dtj = DirectTrustJar(jwks=all_private_keys+rsa_signing_private_key) backend = "openid4vp" entity_id = f"https://rp.example/{backend}" metadata = dtj._build_metadata_with_issuer_jwk(entity_id) assert len(metadata["jwks"]["keys"]) == 2 assert "d" not in metadata["jwks"]["keys"][0] assert metadata["jwks"]["keys"][0].get("use", "") != "enc" assert "d" not in metadata["jwks"]["keys"][1] assert "p" not in metadata["jwks"]["keys"][1] assert "q" not in metadata["jwks"]["keys"][1] assert "dp" not in metadata["jwks"]["keys"][1] assert "dq" not in metadata["jwks"]["keys"][1] assert "qi" not in metadata["jwks"]["keys"][1] assert metadata["jwks"]["keys"][1].get("use", "") != "enc"
[docs] def test_direct_trust_metadata_handler(direct_trust_jar, signing_private_key): backend = "openid4vp" entity_id = f"https://rp.example/{backend}" registered_methods = direct_trust_jar.build_metadata_endpoints(backend, entity_id) assert len(registered_methods) == 1 endpoint_regexp = registered_methods[0][0] assert endpoint_regexp == "^openid4vp/.well-known/jar-issuer$" http_handler = registered_methods[0][1] empty_context = Context() response = http_handler(empty_context, "test") assert "200" in response.status assert response._content_type == "application/json" try: response.headers.index(("Content-Type", "application/json")) except Exception as e: assert True, f"unable to find application/json in response content type: {e}" response_data = json.loads(response.message) assert response_data["issuer"] == entity_id assert len(response_data["jwks"]["keys"]) == 1 pub_key = response_data["jwks"]["keys"][0] expected_pub_key = JWK(signing_private_key[0]).as_public_dict() assert pub_key == expected_pub_key