Skip to content

Commit 3181166

Browse files
rev: metadata endpoint
- use federation `entity_configuration_exp` instead mapping in credential_configurations - rev mapping for get_credential_configurations_supported (view: 444#discussion_r2152251070)
1 parent e41dc0f commit 3181166

7 files changed

Lines changed: 57 additions & 20 deletions

File tree

example/satosa/openid4vci_frontend.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,6 @@ config:
476476
# this is the custom configuration for credential management.
477477
credential_configurations:
478478
lookup_source: openid4vci #this key is the same one found in `internal_attributes.yaml`, used for lookup filter for attributes
479-
entity_configuration_exp: 800
480479
entity_default_sig_alg: *default_sig_alg
481480
credential_specification:
482481
mso_mdoc_mDL:

pyeudiw/openid4vci/endpoints/metadata_endpoint.py

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,7 @@ def __init__(self, config: dict, internal_attributes: dict[str, dict[str, str |
2222
"""
2323
super().__init__(config, internal_attributes, base_url, name)
2424
self.metadata_jwks = config.get("metadata_jwks", [])
25-
26-
@property
27-
def authority_hints(self):
28-
return (
29-
self.config.get("trust", {})
30-
.get("federation", {})
31-
.get("config", {})
32-
.get("authority_hints", [])
33-
)
25+
self.federation_config = self.config.get("trust", {}).get("federation", {}).get("config", {})
3426

3527
def _ensure_credential_issuer(self, metadata: dict, metadata_key: str, issuer_key:str):
3628
metadata_val = metadata.get(metadata_key)
@@ -52,13 +44,13 @@ def metadata(self) -> dict:
5244
def entity_configuration_as_dict(self) -> dict:
5345
"""Returns the entity configuration as a dictionary."""
5446
ec_payload = {
55-
"exp": exp_from_now(minutes=self.credential_configuration.entity_configuration_exp),
47+
"exp": exp_from_now(minutes=self.federation_config.get("entity_configuration_exp")),
5648
"iat": iat_now(),
5749
"iss": self.entity_id,
5850
"sub": self.entity_id,
5951
"jwks": {"keys": self.metadata_jwks},
6052
"metadata": self.metadata,
61-
"authority_hints": self.authority_hints,
53+
"authority_hints": self.federation_config.get("authority_hints", []),
6254
}
6355
return ec_payload
6456

@@ -105,7 +97,6 @@ def _validate_configs(self):
10597
])
10698
self._validate_required_configs([
10799
("credential_configurations.entity_default_sig_alg", credential_configuration.entity_default_sig_alg),
108-
("credential_configurations.entity_configuration_exp", credential_configuration.entity_configuration_exp),
109100
])
110101

111102
self.credential_configuration = credential_configuration

pyeudiw/openid4vci/tools/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def get_credential_configurations_supported(self) -> Dict[str, CredentialConfigu
4646
if not ccs:
4747
return None
4848
return {
49-
k: CredentialConfiguration(id=k, format=v["format"], scope=v["scope"])
49+
k: CredentialConfiguration.map(k, v)
5050
for k, v in ccs.items()
5151
}
5252

pyeudiw/satosa/schemas/metadata.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@ class CredentialConfiguration(BaseModel):
1818
id: str
1919
format: str
2020
scope: str
21+
doctype: Optional[str] = None
22+
23+
@staticmethod
24+
def map(id: str, config_dict: dict):
25+
return CredentialConfiguration(
26+
id=id,
27+
format=config_dict["format"],
28+
scope=config_dict["scope"],
29+
doctype=config_dict.get("doctype"),
30+
)
2131

2232
class OpenidCredentialIssuerMetadata(BaseModel):
2333
credential_configurations_supported: Optional[dict] = None

pyeudiw/tests/openid4vci/endpoints/test_metadata_endpoint.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,6 @@ def _mock_configurations(field: list[str] | str):
6767
@pytest.mark.parametrize("config, missing_fields", [
6868
(_mock_configurations("credential_configurations"), ["credential_configurations"]),
6969
(_mock_configurations("entity_default_sig_alg"), ["credential_configurations.entity_default_sig_alg"]),
70-
(_mock_configurations("entity_configuration_exp"), ["credential_configurations.entity_configuration_exp"]),
71-
(_mock_configurations(["entity_configuration_exp", "entity_default_sig_alg"]), ["credential_configurations.entity_default_sig_alg", "credential_configurations.entity_configuration_exp"])
7270
])
7371
def test_missing_configurations(config, missing_fields):
7472
do_test_missing_configurations_raises(MetadataHandler, config, missing_fields)

pyeudiw/tests/openid4vci/mock_openid4vci.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@
9393

9494
MOCK_CREDENTIAL_CONFIGURATIONS = {
9595
"lookup_source": "openid4vci",
96-
"entity_configuration_exp": 800,
9796
"entity_default_sig_alg": "ES256",
9897
"credential_specification": {
9998
"dc_sd_jwt_mDL": {
@@ -115,6 +114,26 @@
115114
!sd tax_id_code: "TINIT-{{fiscal_code}}"
116115
!sd unique_id: "{{unique_id}}"
117116
"""
117+
},
118+
"mso_mdoc_mDL": {
119+
"template": """
120+
holder_disclosed_claims:
121+
!sd given_name: "{{name}}"
122+
!sd family_name: "{{surname}}"
123+
!sd place_of_birth:
124+
country: "{{countyOfBirth}}"
125+
locality: "{{placeOfBirth}}"
126+
key_binding: true
127+
user_claims:
128+
!sd birthdate: "{{dateOfBirth}}"
129+
!sd family_name: "{{surname}}"
130+
!sd given_name: "{{name}}"
131+
!sd place_of_birth:
132+
country: "{{countyOfBirth}}"
133+
locality: "{{placeOfBirth}}"
134+
!sd tax_id_code: "TINIT-{{fiscal_code}}"
135+
!sd unique_id: "{{unique_id}}"
136+
"""
118137
}
119138
}
120139
}
@@ -131,6 +150,14 @@
131150
"cryptographic_binding_methods_supported": [
132151
"jwk"
133152
]
153+
},
154+
"mso_mdoc_mDL": {
155+
"doctype": "org.iso.18013.5.1.mDL",
156+
"format": "mso_mdoc",
157+
"scope": "mDL",
158+
"cryptographic_binding_methods_supported": [
159+
"cose_key"
160+
]
134161
}
135162
},
136163
"authorization_servers": [],
@@ -190,7 +217,14 @@
190217
},
191218
"user_storage": MOCK_USER_STORAGE_CONFIG,
192219
"metadata_jwks": MOCK_METADATA_JWKS_CONFIG,
193-
"credential_configurations": MOCK_CREDENTIAL_CONFIGURATIONS
220+
"credential_configurations": MOCK_CREDENTIAL_CONFIGURATIONS,
221+
"trust": {
222+
"federation": {
223+
"config":{
224+
"entity_configuration_exp":600
225+
}
226+
}
227+
}
194228
}
195229

196230
MOCK_INTERNAL_ATTRIBUTES = {

pyeudiw/tests/openid4vci/tools/test_config.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,19 +50,24 @@ def test_get_openid_credential_issuer(config_utils):
5050
"cryptographic_binding_methods_supported": [
5151
"jwk"
5252
]
53-
}
53+
},
54+
'mso_mdoc_mDL': {
55+
'cryptographic_binding_methods_supported': ['cose_key'],
56+
'format': 'mso_mdoc',
57+
'scope': 'mDL'}
5458
}
5559

5660

5761
def test_get_credential_configurations_supported(config_utils):
5862
result = config_utils.get_credential_configurations_supported()
5963
assert isinstance(result, dict)
60-
assert set(result.keys()) == {"dc_sd_jwt_EuropeanDisabilityCard", "dc_sd_jwt_mDL"}
64+
assert set(result.keys()) == {'dc_sd_jwt_mDL', 'mso_mdoc_mDL', 'dc_sd_jwt_EuropeanDisabilityCard'}
6165
for k, v in result.items():
6266
assert isinstance(v, CredentialConfiguration)
6367
assert v.id == k
6468
assert v.scope is not None
6569
assert v.format is not None
70+
assert v.doctype == ("org.iso.18013.5.1.mDL" if v.id == 'mso_mdoc_mDL' else None)
6671

6772

6873
def test_get_credential_configurations(config_utils):

0 commit comments

Comments
 (0)