Skip to content

Commit

Permalink
fix + unit tests
Browse files Browse the repository at this point in the history
Signed-off-by: Shaanjot Gill <[email protected]>
  • Loading branch information
shaangill025 committed Oct 19, 2023
1 parent bf871f7 commit cdf5751
Show file tree
Hide file tree
Showing 4 changed files with 324 additions and 7 deletions.
26 changes: 25 additions & 1 deletion aries_cloudagent/revocation/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from ..protocols.revocation_notification.v1_0.models.rev_notification_record import (
RevNotificationRecord,
)
from ..connections.models.conn_record import ConnRecord
from ..core.error import BaseError
from ..core.profile import Profile
from ..indy.issuer import IndyIssuer
Expand Down Expand Up @@ -48,6 +49,7 @@ async def revoke_credential_by_cred_ex_id(
thread_id: str = None,
connection_id: str = None,
comment: str = None,
write_ledger: bool = True,
):
"""Revoke a credential by its credential exchange identifier at issue.
Expand Down Expand Up @@ -80,6 +82,7 @@ async def revoke_credential_by_cred_ex_id(
thread_id=thread_id,
connection_id=connection_id,
comment=comment,
write_ledger=write_ledger,
)

async def revoke_credential(
Expand All @@ -92,6 +95,7 @@ async def revoke_credential(
thread_id: str = None,
connection_id: str = None,
comment: str = None,
write_ledger: bool = True,
):
"""Revoke a credential.
Expand Down Expand Up @@ -147,7 +151,27 @@ async def revoke_credential(
await txn.commit()
await self.set_cred_revoked_state(rev_reg_id, crids)
if delta_json:
await issuer_rr_upd.send_entry(self._profile)
if write_ledger:
await issuer_rr_upd.send_entry(self._profile)
else:
async with self._profile.session() as session:
try:
connection_record = await ConnRecord.retrieve_by_id(
session, connection_id
)
except StorageNotFoundError:
raise RevocationManagerError(
f"No connection record found for id: {connection_id}"
)
endorser_info = await connection_record.metadata_get(
session, "endorser_info"
)
endorser_did = endorser_info["endorser_did"]
await issuer_rr_upd.send_entry(
self._profile,
write_ledger=write_ledger,
endorser_did=endorser_did,
)
await notify_revocation_published_event(
self._profile, rev_reg_id, [cred_rev_id]
)
Expand Down
36 changes: 30 additions & 6 deletions aries_cloudagent/revocation/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ async def revoke(request: web.BaseRequest):
body = await request.json()
cred_ex_id = body.get("cred_ex_id")
body["notify"] = body.get("notify", context.settings.get("revocation.notify"))
notify = body.get("notify")
notify = body.get("notify", False)
connection_id = body.get("connection_id")
body["notify_version"] = body.get("notify_version", "v1_0")
notify_version = body["notify_version"]
Expand All @@ -532,14 +532,38 @@ async def revoke(request: web.BaseRequest):
)

rev_manager = RevocationManager(context.profile)
profile = context.profile
write_ledger = True
if is_author_role(profile):
write_ledger = False
if not connection_id:
connection_id = await get_endorser_connection_id(profile)
if not connection_id:
raise web.HTTPBadRequest(reason="No endorser connection found")
try:
if cred_ex_id:
# rev_reg_id and cred_rev_id should not be present so we can
# safely splat the body
await rev_manager.revoke_credential_by_cred_ex_id(**body)
await rev_manager.revoke_credential_by_cred_ex_id(
cred_ex_id=cred_ex_id,
publish=body.get("publish", False),
notify=notify,
notify_version=notify_version,
thread_id=body.get("thread_id"),
connection_id=connection_id,
comment=body.get("comment"),
write_ledger=write_ledger,
)
else:
# no cred_ex_id so we can safely splat the body
await rev_manager.revoke_credential(**body)
await rev_manager.revoke_credential(
rev_reg_id=body.get("rev_reg_id"),
cred_rev_id=body.get("cred_rev_id"),
publish=body.get("publish", False),
notify=notify,
notify_version=notify_version,
thread_id=body.get("thread_id"),
connection_id=connection_id,
comment=body.get("comment"),
write_ledger=write_ledger,
)
except (
RevocationManagerError,
RevocationError,
Expand Down
144 changes: 144 additions & 0 deletions aries_cloudagent/revocation/tests/test_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
IssuerCredRevRecord,
)

from ...connections.models.conn_record import ConnRecord
from ...core.in_memory import InMemoryProfile
from ...indy.issuer import IndyIssuer
from ...protocols.issue_credential.v1_0.models.credential_exchange import (
Expand Down Expand Up @@ -96,6 +97,149 @@ async def test_revoke_credential_publish(self):
["2", "1"],
)

async def test_revoke_credential_publish_endorser(self):
conn_record = ConnRecord(
their_label="Hello",
their_role=ConnRecord.Role.RESPONDER.rfc160,
alias="Bob",
)
session = await self.profile.session()
await conn_record.save(session)
await conn_record.metadata_set(
session,
key="endorser_info",
value={
"endorser_did": "test_endorser_did",
"endorser_name": "test_endorser_name",
},
)
conn_id = conn_record.connection_id
assert conn_id is not None
manager = RevocationManager(self.profile)
CRED_EX_ID = "dummy-cxid"
CRED_REV_ID = "1"
mock_issuer_rev_reg_record = async_mock.MagicMock(
revoc_reg_id=REV_REG_ID,
tails_local_path=TAILS_LOCAL,
send_entry=async_mock.CoroutineMock(),
clear_pending=async_mock.CoroutineMock(),
pending_pub=["2"],
)
issuer = async_mock.MagicMock(IndyIssuer, autospec=True)
issuer.revoke_credentials = async_mock.CoroutineMock(
return_value=(
json.dumps(
{
"ver": "1.0",
"value": {
"prevAccum": "1 ...",
"accum": "21 ...",
"issued": [1],
},
}
),
[],
)
)
self.profile.context.injector.bind_instance(IndyIssuer, issuer)

with async_mock.patch.object(
test_module.IssuerCredRevRecord,
"retrieve_by_cred_ex_id",
async_mock.CoroutineMock(),
) as mock_retrieve, async_mock.patch.object(
test_module, "IndyRevocation", autospec=True
) as revoc, async_mock.patch.object(
test_module.IssuerRevRegRecord,
"retrieve_by_id",
async_mock.CoroutineMock(return_value=mock_issuer_rev_reg_record),
):
mock_retrieve.return_value = async_mock.MagicMock(
rev_reg_id="dummy-rr-id", cred_rev_id=CRED_REV_ID
)
mock_rev_reg = async_mock.MagicMock(
get_or_fetch_local_tails_path=async_mock.CoroutineMock()
)
revoc.return_value.get_issuer_rev_reg_record = async_mock.CoroutineMock(
return_value=mock_issuer_rev_reg_record
)
revoc.return_value.get_ledger_registry = async_mock.CoroutineMock(
return_value=mock_rev_reg
)

await self.manager.revoke_credential_by_cred_ex_id(
cred_ex_id=CRED_EX_ID,
publish=True,
connection_id=conn_id,
write_ledger=False,
)

issuer.revoke_credentials.assert_awaited_once_with(
mock_issuer_rev_reg_record.cred_def_id,
mock_issuer_rev_reg_record.revoc_reg_id,
mock_issuer_rev_reg_record.tails_local_path,
["2", "1"],
)

async def test_revoke_credential_publish_endorser_x(self):
CRED_EX_ID = "dummy-cxid"
CRED_REV_ID = "1"
mock_issuer_rev_reg_record = async_mock.MagicMock(
revoc_reg_id=REV_REG_ID,
tails_local_path=TAILS_LOCAL,
send_entry=async_mock.CoroutineMock(),
clear_pending=async_mock.CoroutineMock(),
pending_pub=["2"],
)
issuer = async_mock.MagicMock(IndyIssuer, autospec=True)
issuer.revoke_credentials = async_mock.CoroutineMock(
return_value=(
json.dumps(
{
"ver": "1.0",
"value": {
"prevAccum": "1 ...",
"accum": "21 ...",
"issued": [1],
},
}
),
[],
)
)
self.profile.context.injector.bind_instance(IndyIssuer, issuer)

with async_mock.patch.object(
test_module.IssuerCredRevRecord,
"retrieve_by_cred_ex_id",
async_mock.CoroutineMock(),
) as mock_retrieve, async_mock.patch.object(
test_module, "IndyRevocation", autospec=True
) as revoc, async_mock.patch.object(
test_module.IssuerRevRegRecord,
"retrieve_by_id",
async_mock.CoroutineMock(return_value=mock_issuer_rev_reg_record),
):
mock_retrieve.return_value = async_mock.MagicMock(
rev_reg_id="dummy-rr-id", cred_rev_id=CRED_REV_ID
)
mock_rev_reg = async_mock.MagicMock(
get_or_fetch_local_tails_path=async_mock.CoroutineMock()
)
revoc.return_value.get_issuer_rev_reg_record = async_mock.CoroutineMock(
return_value=mock_issuer_rev_reg_record
)
revoc.return_value.get_ledger_registry = async_mock.CoroutineMock(
return_value=mock_rev_reg
)
with self.assertRaises(RevocationManagerError):
await self.manager.revoke_credential_by_cred_ex_id(
cred_ex_id=CRED_EX_ID,
publish=True,
connection_id="invalid_conn_id",
write_ledger=False,
)

async def test_revoke_cred_by_cxid_not_found(self):
CRED_EX_ID = "dummy-cxid"

Expand Down
Loading

0 comments on commit cdf5751

Please sign in to comment.