Skip to content
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

Fix: Present Proof v2 - check_proof_vs_proposal update to support proof request with restrictions #1820

Merged
merged 6 commits into from
Jun 21, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,10 @@ def _check_proof_vs_proposal():
f"attr::{name}::value": proof_value,
}

if not any(r.items() <= criteria.items() for r in req_restrictions):
if (
not any(r.items() <= criteria.items() for r in req_restrictions)
and len(req_restrictions) != 0
):
raise V20PresFormatHandlerError(
f"Presented attribute {reft} does not satisfy proof request "
f"restrictions {req_restrictions}"
Expand Down Expand Up @@ -234,7 +237,10 @@ def _check_proof_vs_proposal():
},
}

if not any(r.items() <= criteria.items() for r in req_restrictions):
if (
not any(r.items() <= criteria.items() for r in req_restrictions)
and len(req_restrictions) != 0
):
raise V20PresFormatHandlerError(
f"Presented attr group {reft} does not satisfy proof request "
f"restrictions {req_restrictions}"
Expand Down Expand Up @@ -287,7 +293,10 @@ def _check_proof_vs_proposal():
"issuer_did": cred_def_id.split(":")[-5],
}

if not any(r.items() <= criteria.items() for r in req_restrictions):
if (
not any(r.items() <= criteria.items() for r in req_restrictions)
and len(req_restrictions) != 0
):
raise V20PresFormatHandlerError(
f"Presented predicate {reft} does not satisfy proof request "
f"restrictions {req_restrictions}"
Expand Down
158 changes: 158 additions & 0 deletions aries_cloudagent/protocols/present_proof/v2_0/tests/test_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -1400,6 +1400,164 @@ async def test_receive_pres_receive_pred_value_mismatch_punt_to_indy(self):
save_ex.assert_called_once()
assert px_rec_out.state == (V20PresExRecord.STATE_PRESENTATION_RECEIVED)

async def test_receive_pres_indy_no_predicate_restrictions(self):
connection_record = async_mock.MagicMock(connection_id=CONN_ID)
indy_proof_req = {
"name": PROOF_REQ_NAME,
"version": PROOF_REQ_VERSION,
"nonce": PROOF_REQ_NONCE,
"requested_attributes": {
"0_player_uuid": {
"name": "player",
"restrictions": [{"cred_def_id": CD_ID}],
"non_revoked": {"from": NOW, "to": NOW},
},
"0_screencapture_uuid": {
"name": "screenCapture",
"restrictions": [{"cred_def_id": CD_ID}],
"non_revoked": {"from": NOW, "to": NOW},
},
},
"requested_predicates": {
"0_highscore_GE_uuid": {
"name": "highScore",
"p_type": ">=",
"p_value": 1000000,
"restrictions": [],
"non_revoked": {"from": NOW, "to": NOW},
}
},
}
pres_request = V20PresRequest(
formats=[
V20PresFormat(
attach_id="indy",
format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][
V20PresFormat.Format.INDY.api
],
)
],
request_presentations_attach=[
AttachDecorator.data_base64(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(INDY_PROOF, ident="indy")
],
)
pres.assign_thread_id("thread-id")

px_rec_dummy = V20PresExRecord(
pres_request=pres_request.serialize(),
)

# cover by_format property
by_format = px_rec_dummy.by_format

assert by_format.get("pres_request").get("indy") == indy_proof_req

with async_mock.patch.object(
V20PresExRecord, "save", autospec=True
) as save_ex, async_mock.patch.object(
V20PresExRecord, "retrieve_by_tag_filter", autospec=True
) as retrieve_ex, async_mock.patch.object(
self.profile,
"session",
async_mock.MagicMock(return_value=self.profile.session()),
) as session:
retrieve_ex.side_effect = [px_rec_dummy]
px_rec_out = await self.manager.receive_pres(pres, connection_record, None)
retrieve_ex.assert_called_once_with(
session.return_value,
{"thread_id": "thread-id"},
{"role": V20PresExRecord.ROLE_VERIFIER, "connection_id": CONN_ID},
)
save_ex.assert_called_once()
assert px_rec_out.state == (V20PresExRecord.STATE_PRESENTATION_RECEIVED)

async def test_receive_pres_indy_no_attr_restrictions(self):
connection_record = async_mock.MagicMock(connection_id=CONN_ID)
indy_proof_req = {
"name": PROOF_REQ_NAME,
"version": PROOF_REQ_VERSION,
"nonce": PROOF_REQ_NONCE,
"requested_attributes": {
"0_player_uuid": {
"name": "player",
"restrictions": [],
"non_revoked": {"from": NOW, "to": NOW},
}
},
"requested_predicates": {},
}
proof = deepcopy(INDY_PROOF)
proof["requested_proof"]["revealed_attrs"] = {
"0_player_uuid": {
"sub_proof_index": 0,
"raw": "Richie Knucklez",
"encoded": "516439982",
}
}
proof["requested_proof"]["predicates"] = {}
pres_request = V20PresRequest(
formats=[
V20PresFormat(
attach_id="indy",
format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][
V20PresFormat.Format.INDY.api
],
)
],
request_presentations_attach=[
AttachDecorator.data_base64(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(proof, ident="indy")],
)
pres.assign_thread_id("thread-id")

px_rec_dummy = V20PresExRecord(
pres_request=pres_request.serialize(),
)

# cover by_format property
by_format = px_rec_dummy.by_format

assert by_format.get("pres_request").get("indy") == indy_proof_req

with async_mock.patch.object(
V20PresExRecord, "save", autospec=True
) as save_ex, async_mock.patch.object(
V20PresExRecord, "retrieve_by_tag_filter", autospec=True
) as retrieve_ex, async_mock.patch.object(
self.profile,
"session",
async_mock.MagicMock(return_value=self.profile.session()),
) as session:
retrieve_ex.side_effect = [px_rec_dummy]
px_rec_out = await self.manager.receive_pres(pres, connection_record, None)
retrieve_ex.assert_called_once_with(
session.return_value,
{"thread_id": "thread-id"},
{"role": V20PresExRecord.ROLE_VERIFIER, "connection_id": CONN_ID},
)
save_ex.assert_called_once()
assert px_rec_out.state == (V20PresExRecord.STATE_PRESENTATION_RECEIVED)

async def test_receive_pres_bait_and_switch_attr_name(self):
connection_record = async_mock.MagicMock(connection_id=CONN_ID)
indy_proof_req = deepcopy(INDY_PROOF_REQ_NAME)
Expand Down