Skip to content

Commit 7061d20

Browse files
authored
🐛 Add credential_id on matching proofs (#1349)
* add models to support credential_id * update return models * update tests * remove import * 🎨 * update test to assert cred_id * diff on OpenApi spec
1 parent 41659f2 commit 7061d20

File tree

6 files changed

+408
-333
lines changed

6 files changed

+408
-333
lines changed

app/models/verifier.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
from enum import Enum
22
from typing import Optional, Union
33

4-
from aries_cloudcontroller import DIFPresSpec, DIFProofRequest, IndyPresSpec
4+
from aries_cloudcontroller import (
5+
DIFPresSpec,
6+
DIFProofRequest,
7+
IndyNonRevocationInterval,
8+
IndyPresSpec,
9+
)
510
from aries_cloudcontroller import IndyProofRequest as AcaPyIndyProofRequest
611
from pydantic import BaseModel, Field, ValidationInfo, field_validator, model_validator
712

@@ -120,3 +125,29 @@ def validate_problem_report(cls, value):
120125
if value == "":
121126
raise CloudApiValueError("problem_report cannot be an empty string")
122127
return value
128+
129+
130+
class CredInfo(BaseModel):
131+
attrs: dict = Field(default=None, description="Attribute names and value")
132+
cred_def_id: str = Field(
133+
default=None, description="Credential definition identifier"
134+
)
135+
referent: str = Field(default=None, description="Credential identifier")
136+
credential_id: str = Field(default=None, description="Credential identifier")
137+
cred_rev_id: Optional[str] = Field(
138+
default=None, description="Credential revocation identifier"
139+
)
140+
rev_reg_id: Optional[str] = Field(
141+
default=None, description="Revocation registry identifier"
142+
)
143+
schema_id: Optional[str] = Field(default=None, description="Schema identifier")
144+
145+
146+
class CredPrecis(BaseModel):
147+
cred_info: CredInfo = Field(description="Credential info")
148+
interval: Optional[IndyNonRevocationInterval] = Field(
149+
default=None, description="Non-revocation interval from presentation request"
150+
)
151+
presentation_referents: Optional[list] = Field(
152+
default=None, description="Presentation referents"
153+
)

app/routes/verifier.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from typing import List, Optional
22
from uuid import UUID
33

4-
from aries_cloudcontroller import IndyCredPrecis
54
from fastapi import APIRouter, Depends
65

76
from app.dependencies.acapy_clients import client_from_auth
@@ -10,6 +9,8 @@
109
from app.models.verifier import (
1110
AcceptProofRequest,
1211
CreateProofRequest,
12+
CredInfo,
13+
CredPrecis,
1314
RejectProofRequest,
1415
SendProofRequest,
1516
)
@@ -456,15 +457,15 @@ async def delete_proof(
456457
@router.get(
457458
"/proofs/{proof_id}/credentials",
458459
summary="Get Matching Credentials for a Proof",
459-
response_model=List[IndyCredPrecis],
460+
response_model=List[CredPrecis],
460461
)
461462
async def get_credentials_by_proof_id(
462463
proof_id: str,
463464
referent: Optional[str] = None,
464465
limit: Optional[int] = limit_query_parameter,
465466
offset: Optional[int] = offset_query_parameter,
466467
auth: AcaPyAuth = Depends(acapy_auth_from_header),
467-
) -> List[IndyCredPrecis]:
468+
) -> List[CredPrecis]:
468469
"""
469470
Get matching credentials for a presentation exchange
470471
---
@@ -486,8 +487,8 @@ async def get_credentials_by_proof_id(
486487
487488
Returns:
488489
---
489-
List[IndyCredPrecis]
490-
A list of applicable Indy credentials
490+
List[CredPrecis]
491+
A list of applicable credentials
491492
"""
492493
bound_logger = logger.bind(body={"proof_id": proof_id})
493494
bound_logger.debug("GET request received: Get credentials for a proof request")
@@ -507,4 +508,13 @@ async def get_credentials_by_proof_id(
507508
raise
508509

509510
bound_logger.debug("Successfully fetched credentials for proof request.")
510-
return result
511+
return [
512+
CredPrecis(
513+
cred_info=CredInfo(
514+
**cred.cred_info.model_dump(), credential_id=cred.cred_info.referent
515+
),
516+
interval=cred.interval,
517+
presentation_referents=cred.presentation_referents,
518+
)
519+
for cred in result
520+
]

app/tests/e2e/verifier/test_verifier.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,12 +445,14 @@ async def test_get_credentials_for_request(
445445

446446
result = response.json()[0]
447447
assert "cred_info" in result
448+
assert result["cred_info"]["referent"] == result["cred_info"]["credential_id"]
448449
assert [
449450
attr
450451
in [
451452
"attrs",
452453
"cred_def_info",
453454
"referent",
455+
"credential_id",
454456
"interval",
455457
"presentation_referents",
456458
]

app/tests/services/verifier/test_verifier.py

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from app.dependencies.auth import AcaPyAuth
1111
from app.exceptions.cloudapi_exception import CloudApiException
1212
from app.main import app
13+
from app.models.verifier import CredInfo, CredPrecis
1314
from app.routes.verifier import acapy_auth_from_header, get_credentials_by_proof_id
1415
from app.services.verifier.acapy_verifier_v2 import VerifierV2
1516
from app.tests.services.verifier.utils import indy_pres_spec, sample_indy_proof_request
@@ -300,9 +301,25 @@ async def test_get_credentials_by_proof_id(
300301
"client_from_auth",
301302
return_value=mock_context_managed_controller(mock_agent_controller),
302303
)
303-
cred_precis = IndyCredPrecis(
304-
cred_info=IndyCredInfo(cred_def_id="WgWxqztrNooG92RXvxSTWv:3:CL:20:tag")
305-
)
304+
cred_precis = [
305+
IndyCredPrecis(
306+
cred_info=IndyCredInfo(
307+
cred_def_id="WgWxqztrNooG92RXvxSTWv:3:CL:20:tag",
308+
referent="abcde",
309+
attrs={"attr1": "value1"},
310+
),
311+
)
312+
]
313+
returned_cred_precis = [
314+
CredPrecis(
315+
cred_info=CredInfo(
316+
**cred.cred_info.model_dump(), credential_id=cred.cred_info.referent
317+
),
318+
interval=cred.interval,
319+
presentation_referents=cred.presentation_referents,
320+
)
321+
for cred in cred_precis
322+
]
306323

307324
# V2
308325
when(VerifierV2).get_credentials_by_proof_id(
@@ -311,7 +328,7 @@ async def test_get_credentials_by_proof_id(
311328
referent=None,
312329
limit=100,
313330
offset=0,
314-
).thenReturn(to_async([cred_precis]))
331+
).thenReturn(to_async(cred_precis))
315332

316333
result = await test_module.get_credentials_by_proof_id(
317334
proof_id="v2-abcd",
@@ -321,7 +338,7 @@ async def test_get_credentials_by_proof_id(
321338
offset=0,
322339
)
323340

324-
assert result == [cred_precis]
341+
assert result == returned_cred_precis
325342
verify(VerifierV2).get_credentials_by_proof_id(
326343
controller=mock_agent_controller,
327344
proof_id="v2-abcd",

0 commit comments

Comments
 (0)