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

Revocation API using anoncreds-rs #2458

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .devcontainer/post-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ WORKSPACE_DIR=$(pwd)
# install all ACA-Py requirements
python -m pip install --upgrade pip
pip3 install -r requirements.txt -r requirements.askar.txt -r requirements.bbs.txt -r requirements.dev.txt -r requirements.indy.txt -r requirements.anoncreds.txt
pip3 install -r demo/requirements.behave.txt -r demo/requirements.txt

# install black for formatting
pip3 install black
29 changes: 23 additions & 6 deletions aries_cloudagent/anoncreds/default/legacy_indy/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -491,10 +491,7 @@ def _indexes_to_bit_array(self, indexes: List[int], size: int) -> List[int]:
"""Turn a sequence of indexes into a full state bit array."""
return [1 if index in indexes else 0 for index in range(1, size + 1)]

async def get_revocation_list(
self, profile: Profile, rev_reg_def_id: str, timestamp: int
) -> GetRevListResult:
"""Get a revocation list from the registry."""
async def _get_ledger(self, profile: Profile, rev_reg_def_id: str):
async with profile.session() as session:
multitenant_mgr = session.inject_or(BaseMultitenantManager)
if multitenant_mgr:
Expand All @@ -512,6 +509,14 @@ async def get_revocation_list(
reason += ": missing wallet-type?"
raise AnonCredsResolutionError(reason)

return ledger_id, ledger

async def get_revocation_registry_delta(
self, profile: Profile, rev_reg_def_id: str, timestamp: None
) -> Tuple[dict, int]:
"""Fetch the revocation registry delta."""
ledger_id, ledger = await self._get_ledger(profile, rev_reg_def_id)

async with ledger:
delta, timestamp = await ledger.get_revoc_reg_delta(
rev_reg_def_id, timestamp_to=timestamp
Expand All @@ -522,8 +527,20 @@ async def get_revocation_list(
f"Revocation list not found for rev reg def: {rev_reg_def_id}",
{"ledger_id": ledger_id},
)
LOGGER.debug("Retrieved delta: %s", delta)
return delta, timestamp

async def get_revocation_list(
self, profile: Profile, rev_reg_def_id: str, timestamp: int
) -> GetRevListResult:
"""Get the revocation registry list."""
_, ledger = await self._get_ledger(profile, rev_reg_def_id)

LOGGER.debug("Retrieved delta: %s", delta)
delta, timestamp = await self.get_revocation_registry_delta(
profile, rev_reg_def_id, timestamp
)

async with ledger:
max_cred_num = await self._get_or_fetch_rev_reg_def_max_cred_num(
profile, ledger, rev_reg_def_id
)
Expand Down Expand Up @@ -582,7 +599,7 @@ async def _revoc_reg_entry_with_fix(
profile,
rev_list,
True,
ledger.genesis_txns,
ledger.pool.genesis_txns,
)
rev_entry_res = {"result": res}
LOGGER.warn("Ledger update/fix applied")
Expand Down
24 changes: 24 additions & 0 deletions aries_cloudagent/anoncreds/revocation.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,22 @@ async def get_created_revocation_registry_definitions(
# entry.name was stored as the credential_definition's ID
return [entry.name for entry in rev_reg_defs]

async def get_created_revocation_registry_definition_state(
self,
rev_reg_def_id: str,
) -> Optional[str]:
"""Retrieve rev reg def by ID from rev reg defs previously created."""
async with self.profile.session() as session:
rev_reg_def_entry = await session.handle.fetch(
CATEGORY_REV_REG_DEF,
name=rev_reg_def_id,
)

if rev_reg_def_entry:
return rev_reg_def_entry.tags.get("state")

return None

async def get_created_revocation_registry_definition(
self,
rev_reg_def_id: str,
Expand Down Expand Up @@ -1140,3 +1156,11 @@ async def clear_pending_revocations(
value_json=value,
tags=tags,
)

async def set_tails_file_public_uri(self, rev_reg_id, tails_public_uri):
"""Update Revocation Registy tails file public uri."""
pass

async def set_rev_reg_state(self, rev_reg_id, state):
"""Update Revocation Registy state."""
pass
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from asynctest import TestCase as AsyncTestCase
from asynctest import mock as async_mock
import pytest

from ....admin.request_context import AdminRequestContext
from ....core.in_memory import InMemoryProfile
Expand Down Expand Up @@ -63,7 +64,8 @@ def setUp(self):
__getitem__=lambda _, k: self.request_dict[k],
)

async def anoncreds_break_test_send_credential_definition(self):
@pytest.mark.skip(reason="anoncreds-rs breaking change")
async def test_send_credential_definition(self):
self.request.json = async_mock.CoroutineMock(
return_value={
"schema_id": "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0",
Expand All @@ -75,8 +77,10 @@ async def anoncreds_break_test_send_credential_definition(self):
self.request.query = {"create_transaction_for_endorser": "false"}

with async_mock.patch.object(test_module.web, "json_response") as mock_response:
result = await test_module.anoncreds_break_credential_definitions_send_credential_definition(
self.request
result = (
await test_module.credential_definitions_send_credential_definition(
self.request
)
)
assert result == mock_response.return_value
mock_response.assert_called_once_with(
Expand All @@ -86,7 +90,8 @@ async def anoncreds_break_test_send_credential_definition(self):
}
)

async def anoncreds_break_test_send_credential_definition_create_transaction_for_endorser(
@pytest.mark.skip(reason="anoncreds-rs breaking change")
async def test_send_credential_definition_create_transaction_for_endorser(
self,
):
self.request.json = async_mock.CoroutineMock(
Expand Down Expand Up @@ -124,8 +129,10 @@ async def anoncreds_break_test_send_credential_definition_create_transaction_for
}
)
)
result = await test_module.anoncreds_break_credential_definitions_send_credential_definition(
self.request
result = (
await test_module.credential_definitions_send_credential_definition(
self.request
)
)
assert result == mock_response.return_value
mock_response.assert_called_once_with(
Expand All @@ -135,7 +142,8 @@ async def anoncreds_break_test_send_credential_definition_create_transaction_for
}
)

async def anoncreds_break_test_send_credential_definition_create_transaction_for_endorser_storage_x(
@pytest.mark.skip(reason="anoncreds-rs breaking change")
async def test_send_credential_definition_create_transaction_for_endorser_storage_x(
self,
):
self.request.json = async_mock.CoroutineMock(
Expand Down Expand Up @@ -171,11 +179,12 @@ async def anoncreds_break_test_send_credential_definition_create_transaction_for
)

with self.assertRaises(test_module.web.HTTPBadRequest):
await test_module.anoncreds_break_credential_definitions_send_credential_definition(
await test_module.credential_definitions_send_credential_definition(
self.request
)

async def anoncreds_break_test_send_credential_definition_create_transaction_for_endorser_not_found_x(
@pytest.mark.skip(reason="anoncreds-rs breaking change")
async def test_send_credential_definition_create_transaction_for_endorser_not_found_x(
self,
):
self.request.json = async_mock.CoroutineMock(
Expand All @@ -197,11 +206,12 @@ async def anoncreds_break_test_send_credential_definition_create_transaction_for
mock_conn_rec_retrieve.side_effect = test_module.StorageNotFoundError()

with self.assertRaises(test_module.web.HTTPNotFound):
await test_module.anoncreds_break_credential_definitions_send_credential_definition(
await test_module.credential_definitions_send_credential_definition(
self.request
)

async def anoncreds_break_test_send_credential_definition_create_transaction_for_endorser_base_model_x(
@pytest.mark.skip(reason="anoncreds-rs breaking change")
async def test_send_credential_definition_create_transaction_for_endorser_base_model_x(
self,
):
self.request.json = async_mock.CoroutineMock(
Expand All @@ -223,11 +233,12 @@ async def anoncreds_break_test_send_credential_definition_create_transaction_for
mock_conn_rec_retrieve.side_effect = test_module.BaseModelError()

with self.assertRaises(test_module.web.HTTPBadRequest):
await test_module.anoncreds_break_credential_definitions_send_credential_definition(
await test_module.credential_definitions_send_credential_definition(
self.request
)

async def anoncreds_break_test_send_credential_definition_create_transaction_for_endorser_no_endorser_info_x(
@pytest.mark.skip(reason="anoncreds-rs breaking change")
async def test_send_credential_definition_create_transaction_for_endorser_no_endorser_info_x(
self,
):
self.request.json = async_mock.CoroutineMock(
Expand All @@ -250,11 +261,12 @@ async def anoncreds_break_test_send_credential_definition_create_transaction_for
metadata_get=async_mock.CoroutineMock(return_value=None)
)
with self.assertRaises(test_module.web.HTTPForbidden):
await test_module.anoncreds_break_credential_definitions_send_credential_definition(
await test_module.credential_definitions_send_credential_definition(
self.request
)

async def anoncreds_break_test_send_credential_definition_create_transaction_for_endorser_no_endorser_did_x(
@pytest.mark.skip(reason="anoncreds-rs breaking change")
async def test_send_credential_definition_create_transaction_for_endorser_no_endorser_did_x(
self,
):
self.request.json = async_mock.CoroutineMock(
Expand All @@ -281,11 +293,12 @@ async def anoncreds_break_test_send_credential_definition_create_transaction_for
)
)
with self.assertRaises(test_module.web.HTTPForbidden):
await test_module.anoncreds_break_credential_definitions_send_credential_definition(
await test_module.credential_definitions_send_credential_definition(
self.request
)

async def anoncreds_break_test_send_credential_definition_no_ledger(self):
@pytest.mark.skip(reason="anoncreds-rs breaking change")
async def test_send_credential_definition_no_ledger(self):
self.request.json = async_mock.CoroutineMock(
return_value={
"schema_id": "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0",
Expand All @@ -297,11 +310,12 @@ async def anoncreds_break_test_send_credential_definition_no_ledger(self):
self.context.injector.clear_binding(BaseLedger)
self.profile_injector.clear_binding(BaseLedger)
with self.assertRaises(test_module.web.HTTPForbidden):
await test_module.anoncreds_break_credential_definitions_send_credential_definition(
await test_module.credential_definitions_send_credential_definition(
self.request
)

async def anoncreds_break_test_send_credential_definition_ledger_x(self):
@pytest.mark.skip(reason="anoncreds-rs breaking change")
async def test_send_credential_definition_ledger_x(self):
self.request.json = async_mock.CoroutineMock(
return_value={
"schema_id": "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0",
Expand All @@ -316,11 +330,12 @@ async def anoncreds_break_test_send_credential_definition_ledger_x(self):
side_effect=test_module.LedgerError("oops")
)
with self.assertRaises(test_module.web.HTTPBadRequest):
await test_module.anoncreds_break_credential_definitions_send_credential_definition(
await test_module.credential_definitions_send_credential_definition(
self.request
)

async def anoncreds_break_test_created(self):
@pytest.mark.skip(reason="anoncreds-rs breaking change")
async def test_created(self):
self.request.match_info = {"cred_def_id": CRED_DEF_ID}

with async_mock.patch.object(test_module.web, "json_response") as mock_response:
Expand All @@ -330,7 +345,8 @@ async def anoncreds_break_test_created(self):
{"credential_definition_ids": [CRED_DEF_ID]}
)

async def anoncreds_break_test_get_credential_definition(self):
@pytest.mark.skip(reason="anoncreds-rs breaking change")
async def test_get_credential_definition(self):
self.profile_injector.bind_instance(
IndyLedgerRequestsExecutor,
async_mock.MagicMock(
Expand All @@ -352,7 +368,8 @@ async def anoncreds_break_test_get_credential_definition(self):
}
)

async def anoncreds_break_test_get_credential_definition_multitenant(self):
@pytest.mark.skip(reason="anoncreds-rs breaking change")
async def test_get_credential_definition_multitenant(self):
self.profile_injector.bind_instance(
BaseMultitenantManager,
async_mock.MagicMock(MultitenantManager, autospec=True),
Expand All @@ -374,7 +391,8 @@ async def anoncreds_break_test_get_credential_definition_multitenant(self):
}
)

async def anoncreds_break_test_get_credential_definition_no_ledger(self):
@pytest.mark.skip(reason="anoncreds-rs breaking change")
async def test_get_credential_definition_no_ledger(self):
self.profile_injector.bind_instance(
IndyLedgerRequestsExecutor,
async_mock.MagicMock(
Expand Down
Loading
Loading