-
Notifications
You must be signed in to change notification settings - Fork 534
fixed duplicate present-proof v2 webhook #3998
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
8f6584b
3c62222
8eb07c4
6e6e89d
acf7edc
ddf5dd0
7354432
42d8570
2b53895
33a7849
15d3346
eb8d2ba
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -206,6 +206,10 @@ async def emit_event(self, session: ProfileSession, payload: Optional[Any] = Non | |
| if not session.profile.settings.get("debug.webhooks"): | ||
| payload = V20PresExRecordWebhook(**payload) | ||
| payload = payload.__dict__ | ||
| # BUG #3802: remove legacy fields when by_format is present | ||
| elif payload.get("by_format"): | ||
| for key in ("pres_proposal", "pres_request", "pres"): | ||
| payload.pop(key, None) | ||
|
Comment on lines
+209
to
+212
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if not session.profile.settings.get("debug.webhooks"):
...
# BUG #3802: remove legacy fields when by_format is present
elif payload.get("by_format"):
for key in ("pres_proposal", "pres_request", "pres"):
payload.pop(key, None)-> if not session.profile.settings.get("debug.webhooks"):
...
elif by_format := payload.get("by_format"):
# Issue #3802: remove legacy fields when by_format is present
for key in ("pres_proposal", "pres_request", "pres"):
if key in by_format:
payload.pop(key, None)^ Move/reword comment; assign by_format; and check key in by_format before removing. It's probably good to explicitly check that they key being removed does in fact exist in by_format already. |
||
|
|
||
| await session.emit_event(topic, payload) | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,9 +4,11 @@ | |
| from ......messaging.models.base_record import BaseExchangeRecord, BaseExchangeSchema | ||
| from ......tests import mock | ||
| from ......utils.testing import create_test_profile | ||
| from ...message_types import ATTACHMENT_FORMAT, PRES_20_PROPOSAL | ||
| from ...message_types import ATTACHMENT_FORMAT, PRES_20, PRES_20_PROPOSAL, PRES_20_REQUEST | ||
| from ...messages.pres import V20Pres | ||
| from ...messages.pres_format import V20PresFormat | ||
| from ...messages.pres_proposal import V20PresProposal | ||
| from ...messages.pres_request import V20PresRequest | ||
| from .. import pres_exchange as test_module | ||
| from ..pres_exchange import V20PresExRecord | ||
|
|
||
|
|
@@ -52,6 +54,16 @@ | |
| } | ||
| }, | ||
| } | ||
| INDY_PROOF = { | ||
| "proof": {"proofs": []}, | ||
| "requested_proof": { | ||
| "revealed_attrs": {}, | ||
| "self_attested_attrs": {}, | ||
| "unrevealed_attrs": {}, | ||
| "predicates": {}, | ||
| }, | ||
| "identifiers": [], | ||
| } | ||
|
|
||
|
|
||
| class BasexRecordImpl(BaseExchangeRecord): | ||
|
|
@@ -134,3 +146,58 @@ async def test_save_error_state(self): | |
| mock_save.side_effect = test_module.StorageError() | ||
| await record.save_error_state(session, reason="testing") | ||
| mock_log_exc.assert_called_once() | ||
|
|
||
| # BUG #3802: ensure webhook payloads omit legacy pres_* fields when by_format exists | ||
| async def test_emit_event_strips_legacy_pres_fields(self): | ||
| settings = { | ||
| "wallet.type": "askar", | ||
| "auto_provision": True, | ||
| "wallet.key": "5BngFuBpS4wjFfVFCtPqoix3ZXG2XR8XJ7qosUzMak7R", | ||
| "wallet.key_derivation_method": "RAW", | ||
| "debug.webhooks": True, | ||
| } | ||
| self.profile = await create_test_profile(settings=settings) | ||
| pres_request = V20PresRequest( | ||
| formats=[ | ||
| V20PresFormat( | ||
| attach_id="indy", | ||
| format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ | ||
| V20PresFormat.Format.INDY.api | ||
| ], | ||
| ) | ||
| ], | ||
| request_presentations_attach=[ | ||
| AttachDecorator.data_base64(mapping=INDY_PROOF_REQ, ident="indy") | ||
| ], | ||
| ) | ||
| pres = V20Pres( | ||
| formats=[ | ||
| V20PresFormat( | ||
| attach_id="indy", | ||
| format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], | ||
| ) | ||
| ], | ||
| presentations_attach=[ | ||
| AttachDecorator.data_base64(mapping=INDY_PROOF, ident="indy") | ||
| ], | ||
| ) | ||
| record = V20PresExRecord( | ||
| pres_ex_id="pxid", | ||
| thread_id="thid", | ||
| connection_id="conn_id", | ||
| initiator="init", | ||
| role="role", | ||
| state=V20PresExRecord.STATE_PRESENTATION_RECEIVED, | ||
| pres_request=pres_request, | ||
| pres=pres, | ||
| ) | ||
|
|
||
| async with self.profile.session() as session: | ||
| session.emit_event = mock.CoroutineMock() | ||
| await record.emit_event(session) | ||
|
|
||
| payload = session.emit_event.call_args.args[1] | ||
| assert "by_format" in payload | ||
| assert "pres_request" not in payload | ||
| assert "pres" not in payload | ||
| assert "pres_proposal" not in payload | ||
|
Comment on lines
+199
to
+203
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would just add an assertion that those 3 keys do exist in for key in ("pres", "pres_proposal", "pres_request"):
assert key not in payload and key in payload["by_format"] |
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -18,23 +18,36 @@ | |||||||||||||||||||||||||||||||||||||||||||
| didexchange, | ||||||||||||||||||||||||||||||||||||||||||||
| indy_anoncred_credential_artifacts, | ||||||||||||||||||||||||||||||||||||||||||||
| indy_issue_credential_v2, | ||||||||||||||||||||||||||||||||||||||||||||
| indy_present_proof_v2, | ||||||||||||||||||||||||||||||||||||||||||||
| params, | ||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||
| from aiohttp import ClientSession | ||||||||||||||||||||||||||||||||||||||||||||
| from examples.util import indy_present_proof_v2 | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| ALICE = getenv("ALICE", "http://alice:3001") | ||||||||||||||||||||||||||||||||||||||||||||
| BOB = getenv("BOB", "http://bob:3001") | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| def _presentation_request_payload(presentation: V20PresExRecord): | ||||||||||||||||||||||||||||||||||||||||||||
| if presentation.by_format and presentation.by_format.pres_request: | ||||||||||||||||||||||||||||||||||||||||||||
| return presentation.by_format.pres_request | ||||||||||||||||||||||||||||||||||||||||||||
| request = presentation.pres_request | ||||||||||||||||||||||||||||||||||||||||||||
| if not request: | ||||||||||||||||||||||||||||||||||||||||||||
| return None | ||||||||||||||||||||||||||||||||||||||||||||
| if isinstance(request, dict): | ||||||||||||||||||||||||||||||||||||||||||||
| return request | ||||||||||||||||||||||||||||||||||||||||||||
| if hasattr(request, "model_dump"): | ||||||||||||||||||||||||||||||||||||||||||||
| return request.model_dump(by_alias=True) | ||||||||||||||||||||||||||||||||||||||||||||
| return request.dict(by_alias=True) | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+24
to
+42
|
||||||||||||||||||||||||||||||||||||||||||||
| from examples.util import indy_present_proof_v2 | |
| ALICE = getenv("ALICE", "http://alice:3001") | |
| BOB = getenv("BOB", "http://bob:3001") | |
| def _presentation_request_payload(presentation: V20PresExRecord): | |
| if presentation.by_format and presentation.by_format.pres_request: | |
| return presentation.by_format.pres_request | |
| request = presentation.pres_request | |
| if not request: | |
| return None | |
| if isinstance(request, dict): | |
| return request | |
| if hasattr(request, "model_dump"): | |
| return request.model_dump(by_alias=True) | |
| return request.dict(by_alias=True) | |
| from examples.util import indy_present_proof_v2, _presentation_request_payload | |
| ALICE = getenv("ALICE", "http://alice:3001") | |
| BOB = getenv("BOB", "http://bob:3001") |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,14 +29,27 @@ | |
| BOB = getenv("BOB", "http://bob:3001") | ||
|
|
||
|
|
||
| def _presentation_request_payload(presentation: V20PresExRecord): | ||
| if presentation.by_format and presentation.by_format.pres_request: | ||
| return presentation.by_format.pres_request | ||
| request = presentation.pres_request | ||
| if not request: | ||
| return None | ||
| if isinstance(request, dict): | ||
| return request | ||
| if hasattr(request, "model_dump"): | ||
| return request.model_dump(by_alias=True) | ||
| return request.dict(by_alias=True) | ||
|
Comment on lines
+32
to
+42
|
||
|
|
||
|
|
||
| def summary(presentation: V20PresExRecord) -> str: | ||
| """Summarize a presentation exchange record.""" | ||
| request = presentation.pres_request | ||
| request = _presentation_request_payload(presentation) | ||
| return "Summary: " + json.dumps( | ||
| { | ||
| "state": presentation.state, | ||
| "verified": presentation.verified, | ||
| "presentation_request": request.dict(by_alias=True) if request else None, | ||
| "presentation_request": request, | ||
| }, | ||
| indent=2, | ||
| sort_keys=True, | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -18,23 +18,36 @@ | |||||||||||||||||||||||||||||||||||||||||||
| didexchange, | ||||||||||||||||||||||||||||||||||||||||||||
| indy_anoncred_credential_artifacts, | ||||||||||||||||||||||||||||||||||||||||||||
| indy_issue_credential_v2, | ||||||||||||||||||||||||||||||||||||||||||||
| indy_present_proof_v2, | ||||||||||||||||||||||||||||||||||||||||||||
| params, | ||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||
| from aiohttp import ClientSession | ||||||||||||||||||||||||||||||||||||||||||||
| from examples.util import indy_present_proof_v2 | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| ALICE = getenv("ALICE", "http://alice:3001") | ||||||||||||||||||||||||||||||||||||||||||||
| BOB = getenv("BOB", "http://bob:3001") | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| def _presentation_request_payload(presentation: V20PresExRecord): | ||||||||||||||||||||||||||||||||||||||||||||
| if presentation.by_format and presentation.by_format.pres_request: | ||||||||||||||||||||||||||||||||||||||||||||
| return presentation.by_format.pres_request | ||||||||||||||||||||||||||||||||||||||||||||
| request = presentation.pres_request | ||||||||||||||||||||||||||||||||||||||||||||
| if not request: | ||||||||||||||||||||||||||||||||||||||||||||
| return None | ||||||||||||||||||||||||||||||||||||||||||||
| if isinstance(request, dict): | ||||||||||||||||||||||||||||||||||||||||||||
| return request | ||||||||||||||||||||||||||||||||||||||||||||
| if hasattr(request, "model_dump"): | ||||||||||||||||||||||||||||||||||||||||||||
| return request.model_dump(by_alias=True) | ||||||||||||||||||||||||||||||||||||||||||||
| return request.dict(by_alias=True) | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+24
to
+42
|
||||||||||||||||||||||||||||||||||||||||||||
| from examples.util import indy_present_proof_v2 | |
| ALICE = getenv("ALICE", "http://alice:3001") | |
| BOB = getenv("BOB", "http://bob:3001") | |
| def _presentation_request_payload(presentation: V20PresExRecord): | |
| if presentation.by_format and presentation.by_format.pres_request: | |
| return presentation.by_format.pres_request | |
| request = presentation.pres_request | |
| if not request: | |
| return None | |
| if isinstance(request, dict): | |
| return request | |
| if hasattr(request, "model_dump"): | |
| return request.model_dump(by_alias=True) | |
| return request.dict(by_alias=True) | |
| from examples.util import indy_present_proof_v2, _presentation_request_payload | |
| ALICE = getenv("ALICE", "http://alice:3001") | |
| BOB = getenv("BOB", "http://bob:3001") |
Uh oh!
There was an error while loading. Please reload this page.