Skip to content

Commit 0267a94

Browse files
nodleshjamshale
andauthored
DIF presentation debug logging (#4019)
* DIF presentation debug logging Signed-off-by: Sheldon Regular <sheldon.regular@gmail.com> * fixed ruff failures Signed-off-by: Sheldon Regular <sheldon.regular@gmail.com> * more ruff lint fixes Signed-off-by: Sheldon Regular <sheldon.regular@gmail.com> --------- Signed-off-by: Sheldon Regular <sheldon.regular@gmail.com> Co-authored-by: jamshale <31809382+jamshale@users.noreply.github.com>
1 parent 77f4c82 commit 0267a94

3 files changed

Lines changed: 161 additions & 0 deletions

File tree

acapy_agent/protocols/present_proof/dif/pres_exch_handler.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,6 +1067,12 @@ async def apply_requirements(
10671067
result = {}
10681068
# Get all input_descriptors attached to the PresentationDefinition
10691069
descriptor_list = req.input_descriptors or []
1070+
LOGGER.debug(
1071+
"DIF-PRES apply_requirements: descriptors=%s creds=%s records_filter=%s",
1072+
len(descriptor_list),
1073+
len(credentials),
1074+
list(records_filter.keys()) if records_filter else None,
1075+
)
10701076
for descriptor in descriptor_list:
10711077
# Filter credentials to apply filtering
10721078
# upon by matching each credentialSchema.id
@@ -1090,6 +1096,13 @@ async def apply_requirements(
10901096
constraints=descriptor.constraint,
10911097
credentials=filtered_by_schema,
10921098
)
1099+
LOGGER.debug(
1100+
"DIF-PRES apply_requirements: descriptor=%s schema_filtered=%s "
1101+
"constraints_filtered=%s",
1102+
descriptor.id,
1103+
len(filtered_by_schema),
1104+
len(filtered),
1105+
)
10931106
if len(filtered) != 0:
10941107
result[descriptor.id] = filtered
10951108

acapy_agent/protocols/present_proof/v2_0/formats/dif/handler.py

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
Ed25519Signature2018,
1818
Ed25519Signature2020,
1919
)
20+
from ......vc.ld_proofs.validation_result import DocumentVerificationResult
2021
from ......vc.vc_di.manager import VcDiManager
2122
from ......vc.vc_ld.manager import VcLdpManager
2223
from ......vc.vc_ld.models.options import LDProofVCOptions
@@ -167,6 +168,16 @@ async def create_pres(
167168
if not challenge:
168169
challenge = str(uuid4())
169170
input_descriptors = pres_definition.input_descriptors
171+
LOGGER.debug(
172+
"DIF-PRES create_pres: pres_ex_id=%s thread_id=%s pd_id=%s "
173+
"input_descriptors=%s issuer_id=%s record_ids=%s",
174+
pres_ex_record.pres_ex_id,
175+
pres_ex_record.thread_id,
176+
pres_definition.id if pres_definition else None,
177+
len(input_descriptors) if input_descriptors else 0,
178+
issuer_id,
179+
len(limit_record_ids) if limit_record_ids else 0,
180+
)
170181
claim_fmt = pres_definition.fmt
171182
dif_handler_proof_type = None
172183
try:
@@ -200,6 +211,15 @@ async def create_pres(
200211
uri_list = None
201212
if len(one_of_uri_groups) == 0:
202213
one_of_uri_groups = None
214+
LOGGER.debug(
215+
"DIF-PRES descriptor=%s oneof=%s uri_list=%s uri_groups=%s "
216+
"limit_disclosure=%s",
217+
input_descriptor.id,
218+
bool(one_of_uri_groups),
219+
uri_list,
220+
one_of_uri_groups,
221+
limit_disclosure,
222+
)
203223
if limit_disclosure:
204224
proof_type = [BbsBlsSignature2020.signature_type]
205225
dif_handler_proof_type = BbsBlsSignature2020.signature_type
@@ -321,6 +341,14 @@ async def create_pres(
321341
)
322342
max_results = 1000
323343
cred_group = await search.fetch(max_results)
344+
LOGGER.debug(
345+
"DIF-PRES search(oneof): descriptor=%s uris=%s "
346+
"proof_types=%s results=%s",
347+
input_descriptor.id,
348+
uri_group,
349+
proof_type,
350+
len(cred_group),
351+
)
324352
(
325353
cred_group_vcrecord_list,
326354
cred_group_vcrecord_ids_set,
@@ -337,6 +365,14 @@ async def create_pres(
337365
# For now, setting to 1000
338366
max_results = 1000
339367
records = await search.fetch(max_results)
368+
LOGGER.debug(
369+
"DIF-PRES search: descriptor=%s uris=%s proof_types=%s "
370+
"results=%s",
371+
input_descriptor.id,
372+
uri_list,
373+
proof_type,
374+
len(records),
375+
)
340376

341377
# Avoiding addition of duplicate records
342378
(
@@ -345,6 +381,12 @@ async def create_pres(
345381
) = await self.process_vcrecords_return_list(records, record_ids)
346382
record_ids = vcrecord_ids_set
347383
credentials_list = credentials_list + vcrecord_list
384+
LOGGER.debug(
385+
"DIF-PRES candidates: descriptor=%s added=%s total=%s",
386+
input_descriptor.id,
387+
len(vcrecord_list),
388+
len(credentials_list),
389+
)
348390

349391
except StorageNotFoundError as err:
350392
raise V20PresFormatHandlerError(err)
@@ -376,6 +418,15 @@ async def create_pres(
376418
reveal_doc=reveal_doc_frame,
377419
)
378420
try:
421+
LOGGER.debug(
422+
"DIF-PRES create_vp: pres_ex_id=%s thread_id=%s proof_type=%s "
423+
"creds=%s records_filter=%s",
424+
pres_ex_record.pres_ex_id,
425+
pres_ex_record.thread_id,
426+
dif_handler_proof_type,
427+
len(credentials_list),
428+
len(limit_record_ids) if limit_record_ids else 0,
429+
)
379430
pres = await dif_handler.create_vp(
380431
challenge=challenge,
381432
domain=domain,
@@ -469,30 +520,98 @@ async def verify_pres(self, pres_ex_record: V20PresExRecord) -> V20PresExRecord:
469520
dif_proof = pres_ex_record.pres.attachment(DIFPresFormatHandler.format)
470521
pres_request = pres_ex_record.pres_request.attachment(DIFPresFormatHandler.format)
471522
pres_ver_result = None
523+
log_details = self._profile.settings.get("debug.presentations")
524+
525+
LOGGER.debug(
526+
"DIF-PRES verify_pres: pres_ex_id=%s thread_id=%s proof_is_sequence=%s",
527+
pres_ex_record.pres_ex_id,
528+
pres_ex_record.thread_id,
529+
isinstance(dif_proof, Sequence),
530+
)
472531
if isinstance(dif_proof, Sequence):
473532
if len(dif_proof) == 0:
474533
raise V20PresFormatHandlerError(
475534
"Presentation exchange record has no presentations to verify"
476535
)
477536
for proof in dif_proof:
478537
manager, options = self._get_type_manager_options(proof, pres_request)
538+
proof_type = (proof.get("proof") or {}).get("type")
539+
LOGGER.debug(
540+
"DIF-PRES verify_pres: proof_type=%s manager=%s",
541+
proof_type,
542+
manager.__class__.__name__,
543+
)
479544
pres_ver_result = await manager.verify_presentation(
480545
vp=VerifiablePresentation.deserialize(proof),
481546
options=options,
482547
)
548+
LOGGER.debug(
549+
"DIF-PRES verify_pres result: verified=%s errors=%s",
550+
pres_ver_result.verified,
551+
pres_ver_result.errors,
552+
)
553+
if log_details:
554+
LOGGER.debug(
555+
"DIF-PRES verify_pres details: presentation_result=%s "
556+
"credential_results=%s",
557+
self._summarize_doc_result(pres_ver_result.presentation_result),
558+
[
559+
self._summarize_doc_result(r)
560+
for r in (pres_ver_result.credential_results or [])
561+
],
562+
)
483563
if not pres_ver_result.verified:
484564
break
485565
else:
486566
manager, options = self._get_type_manager_options(dif_proof, pres_request)
567+
proof_type = (dif_proof.get("proof") or {}).get("type")
568+
LOGGER.debug(
569+
"DIF-PRES verify_pres: proof_type=%s manager=%s",
570+
proof_type,
571+
manager.__class__.__name__,
572+
)
487573
pres_ver_result = await manager.verify_presentation(
488574
vp=VerifiablePresentation.deserialize(dif_proof),
489575
options=options,
490576
)
577+
LOGGER.debug(
578+
"DIF-PRES verify_pres result: verified=%s errors=%s",
579+
pres_ver_result.verified,
580+
pres_ver_result.errors,
581+
)
582+
if log_details:
583+
LOGGER.debug(
584+
"DIF-PRES verify_pres details: presentation_result=%s "
585+
"credential_results=%s",
586+
self._summarize_doc_result(pres_ver_result.presentation_result),
587+
[
588+
self._summarize_doc_result(r)
589+
for r in (pres_ver_result.credential_results or [])
590+
],
591+
)
491592

492593
assert pres_ver_result is not None
493594
pres_ex_record.verified = json.dumps(pres_ver_result.verified)
494595
return pres_ex_record
495596

597+
@staticmethod
598+
def _summarize_doc_result(doc_result: Optional[DocumentVerificationResult]):
599+
if not doc_result:
600+
return None
601+
proof_results = [
602+
{
603+
"verified": pr.verified,
604+
"error": pr.error,
605+
"purpose_error": getattr(pr.purpose_result, "error", None),
606+
}
607+
for pr in (doc_result.results or [])
608+
]
609+
return {
610+
"verified": doc_result.verified,
611+
"errors": doc_result.errors,
612+
"proof_results": proof_results,
613+
}
614+
496615
def _get_type_manager_options(self, dif_proof: dict, pres_request: dict):
497616
"""Get the type of manager and options based on the proof type."""
498617
if dif_proof.get("proof") and dif_proof["proof"]["type"] == "DataIntegrityProof":

acapy_agent/protocols/present_proof/v2_0/formats/dif/tests/test_handler.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
from .......tests import mock
1313
from .......utils.testing import create_test_profile, skip_on_jsonld_url_error
1414
from .......vc.ld_proofs import DocumentLoader
15+
from .......vc.ld_proofs.validation_result import (
16+
DocumentVerificationResult,
17+
ProofResult,
18+
PurposeResult,
19+
)
1520
from .......vc.vc_di.manager import VcDiManager
1621
from .......vc.vc_ld.manager import VcLdpManager
1722
from .......vc.vc_ld.validation_result import PresentationVerificationResult
@@ -2379,3 +2384,27 @@ async def test_get_type_manager_options(self):
23792384
manager, options = handler._get_type_manager_options(dif_proof, pres_request)
23802385
assert isinstance(manager, VcLdpManager)
23812386
assert options.challenge == "3fa85f64-5717-4562-b3fc-2c963f66afa7"
2387+
2388+
async def test_summarize_doc_result_redacts_sensitive_fields(self):
2389+
self.profile = await create_test_profile()
2390+
handler = DIFPresFormatHandler(self.profile)
2391+
doc_result = DocumentVerificationResult(
2392+
verified=False,
2393+
document={"id": "doc", "proof": {"proofValue": "secret"}},
2394+
results=[
2395+
ProofResult(
2396+
verified=False,
2397+
proof={"proofValue": "secret"},
2398+
error="bad proof",
2399+
purpose_result=PurposeResult(valid=False, error="purpose failed"),
2400+
)
2401+
],
2402+
errors=["verification failed"],
2403+
)
2404+
summary = handler._summarize_doc_result(doc_result)
2405+
assert summary["verified"] is False
2406+
assert summary["errors"] == ["verification failed"]
2407+
assert "document" not in summary
2408+
assert "proof" not in summary["proof_results"][0]
2409+
assert summary["proof_results"][0]["error"] == "bad proof"
2410+
assert summary["proof_results"][0]["purpose_error"] == "purpose failed"

0 commit comments

Comments
 (0)