Skip to content

Commit

Permalink
move IssuerCredRevRecord creation to issue-credential manager
Browse files Browse the repository at this point in the history
Signed-off-by: Andrew Whitehead <[email protected]>
  • Loading branch information
andrewwhitehead committed Jun 23, 2022
1 parent 1aa623f commit 6d65a25
Show file tree
Hide file tree
Showing 13 changed files with 228 additions and 234 deletions.
18 changes: 0 additions & 18 deletions aries_cloudagent/indy/credx/issuer.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@
DEFAULT_CRED_DEF_TAG,
DEFAULT_SIGNATURE_TYPE,
)
from ...revocation.models.issuer_cred_rev_record import IssuerCredRevRecord


LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -225,7 +223,6 @@ async def create_credential(
credential_offer: dict,
credential_request: dict,
credential_values: dict,
cred_ex_id: str,
revoc_reg_id: str = None,
tails_file_path: str = None,
) -> Tuple[str, str]:
Expand All @@ -237,7 +234,6 @@ async def create_credential(
credential_offer: Credential Offer to create credential for
credential_request: Credential request to create credential for
credential_values: Values to go in credential
cred_ex_id: credential exchange identifier to use in issuer cred rev rec
revoc_reg_id: ID of the revocation registry
tails_file_path: The location of the tails file
Expand Down Expand Up @@ -324,20 +320,6 @@ async def create_credential(
await txn.handle.replace(
CATEGORY_REV_REG_INFO, revoc_reg_id, value_json=rev_info
)

issuer_cr_rec = IssuerCredRevRecord(
state=IssuerCredRevRecord.STATE_ISSUED,
cred_ex_id=cred_ex_id,
rev_reg_id=revoc_reg_id,
cred_rev_id=str(rev_reg_index),
)
await issuer_cr_rec.save(
txn,
reason=(
"Created issuer cred rev record for "
f"rev reg id {revoc_reg_id}, {rev_reg_index}"
),
)
await txn.commit()
except AskarError as err:
raise IndyIssuerError(
Expand Down
2 changes: 0 additions & 2 deletions aries_cloudagent/indy/credx/tests/test_cred_issuance.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ async def test_issue_store_non_rev(self):
cred_offer,
cred_req,
{"name": "NAME", "moniker": "MONIKER"},
cred_ex_id="cred_ex_id",
revoc_reg_id=None,
tails_file_path=None,
)
Expand Down Expand Up @@ -255,7 +254,6 @@ async def test_issue_store_rev(self):
cred_offer,
cred_req,
{"name": "NAME", "moniker": "MONIKER"},
cred_ex_id="cred_ex_id",
revoc_reg_id=reg_id,
tails_file_path=tails_path,
)
Expand Down
2 changes: 0 additions & 2 deletions aries_cloudagent/indy/issuer.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ async def create_credential(
credential_offer: dict,
credential_request: dict,
credential_values: dict,
cred_ex_id: str,
revoc_reg_id: str = None,
tails_file_path: str = None,
) -> Tuple[str, str]:
Expand All @@ -134,7 +133,6 @@ async def create_credential(
credential_offer: Credential Offer to create credential for
credential_request: Credential request to create credential for
credential_values: Values to go in credential
cred_ex_id: credential exchange identifier to use in issuer cred rev rec
revoc_reg_id: ID of the revocation registry
tails_file_path: The location of the tails file
Expand Down
19 changes: 0 additions & 19 deletions aries_cloudagent/indy/sdk/issuer.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

from ...indy.sdk.profile import IndySdkProfile
from ...messaging.util import encode
from ...revocation.models.issuer_cred_rev_record import IssuerCredRevRecord
from ...storage.error import StorageError

from ..issuer import (
Expand Down Expand Up @@ -162,7 +161,6 @@ async def create_credential(
credential_offer: dict,
credential_request: dict,
credential_values: dict,
cred_ex_id: str,
rev_reg_id: str = None,
tails_file_path: str = None,
) -> Tuple[str, str]:
Expand All @@ -174,7 +172,6 @@ async def create_credential(
credential_offer: Credential Offer to create credential for
credential_request: Credential request to create credential for
credential_values: Values to go in credential
cred_ex_id: credential exchange identifier to use in issuer cred rev rec
rev_reg_id: ID of the revocation registry
tails_file_path: Path to the local tails file
Expand Down Expand Up @@ -219,22 +216,6 @@ async def create_credential(
rev_reg_id,
tails_reader_handle,
)

if cred_rev_id:
issuer_cr_rec = IssuerCredRevRecord(
state=IssuerCredRevRecord.STATE_ISSUED,
cred_ex_id=cred_ex_id,
rev_reg_id=rev_reg_id,
cred_rev_id=cred_rev_id,
)
async with self.profile.session() as session:
await issuer_cr_rec.save(
session,
reason=(
"Created issuer cred rev record for "
f"rev reg id {rev_reg_id}, {cred_rev_id}"
),
)
except AnoncredsRevocationRegistryFullError:
LOGGER.warning(
"Revocation registry %s is full: cannot create credential",
Expand Down
234 changes: 90 additions & 144 deletions aries_cloudagent/indy/sdk/tests/test_issuer.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,58 +166,46 @@ async def test_create_revoke_credentials(
for cr_id in test_cred_rev_ids
]

with async_mock.patch.object(
test_module, "IssuerCredRevRecord", async_mock.MagicMock()
) as mock_issuer_cr_rec:
mock_issuer_cr_rec.return_value.save = async_mock.CoroutineMock()
mock_issuer_cr_rec.retrieve_by_ids = async_mock.CoroutineMock(
return_value=async_mock.MagicMock(
set_state=async_mock.CoroutineMock(),
)
)

with self.assertRaises(test_module.IndyIssuerError): # missing attribute
cred_json, revoc_id = await self.issuer.create_credential(
test_schema,
test_offer,
test_request,
{},
"dummy-cxid",
)

(cred_json, cred_rev_id) = await self.issuer.create_credential( # main line
with self.assertRaises(test_module.IndyIssuerError): # missing attribute
cred_json, revoc_id = await self.issuer.create_credential(
test_schema,
test_offer,
test_request,
test_values,
"dummy-cxid",
REV_REG_ID,
"/tmp/tails/path/dummy",
)
mock_indy_create_credential.assert_called_once()
(
call_wallet,
call_offer,
call_request,
call_values,
call_etc1,
call_etc2,
) = mock_indy_create_credential.call_args[0]
assert call_wallet is self.wallet.handle
assert json.loads(call_offer) == test_offer
assert json.loads(call_request) == test_request
values = json.loads(call_values)
assert "attr1" in values

mock_indy_revoke_credential.return_value = json.dumps(TEST_RR_DELTA)
mock_indy_merge_rr_deltas.return_value = json.dumps(TEST_RR_DELTA)
(result, failed) = await self.issuer.revoke_credentials(
REV_REG_ID, tails_file_path="dummy", cred_rev_ids=test_cred_rev_ids
{},
)
assert json.loads(result) == TEST_RR_DELTA
assert not failed
assert mock_indy_revoke_credential.call_count == 2
mock_indy_merge_rr_deltas.assert_called_once()

(cred_json, cred_rev_id) = await self.issuer.create_credential( # main line
test_schema,
test_offer,
test_request,
test_values,
REV_REG_ID,
"/tmp/tails/path/dummy",
)
mock_indy_create_credential.assert_called_once()
(
call_wallet,
call_offer,
call_request,
call_values,
call_etc1,
call_etc2,
) = mock_indy_create_credential.call_args[0]
assert call_wallet is self.wallet.handle
assert json.loads(call_offer) == test_offer
assert json.loads(call_request) == test_request
values = json.loads(call_values)
assert "attr1" in values

mock_indy_revoke_credential.return_value = json.dumps(TEST_RR_DELTA)
mock_indy_merge_rr_deltas.return_value = json.dumps(TEST_RR_DELTA)
(result, failed) = await self.issuer.revoke_credentials(
REV_REG_ID, tails_file_path="dummy", cred_rev_ids=test_cred_rev_ids
)
assert json.loads(result) == TEST_RR_DELTA
assert not failed
assert mock_indy_revoke_credential.call_count == 2
mock_indy_merge_rr_deltas.assert_called_once()

@async_mock.patch("indy.anoncreds.issuer_create_credential")
@async_mock.patch.object(test_module, "create_tails_reader", autospec=True)
Expand Down Expand Up @@ -266,73 +254,53 @@ async def test_create_revoke_credentials_x(
test_offer,
test_request,
{},
"dummy-cxid",
)

with async_mock.patch.object(
test_module, "IssuerCredRevRecord", async_mock.MagicMock()
) as mock_issuer_cr_rec:
mock_issuer_cr_rec.return_value.save = async_mock.CoroutineMock(
side_effect=test_module.StorageError(
"could not store" # not fatal; maximize coverage
)
)
mock_issuer_cr_rec.retrieve_by_ids = async_mock.CoroutineMock(
return_value=async_mock.MagicMock(
set_state=async_mock.CoroutineMock(
side_effect=test_module.StorageError(
"could not store" # not fatal; maximize coverage
)
),
)
)

(cred_json, cred_rev_id) = await self.issuer.create_credential( # main line
test_schema,
test_offer,
test_request,
test_values,
"dummy-cxid",
REV_REG_ID,
"/tmp/tails/path/dummy",
)
mock_indy_create_credential.assert_called_once()
(
call_wallet,
call_offer,
call_request,
call_values,
call_etc1,
call_etc2,
) = mock_indy_create_credential.call_args[0]
assert call_wallet is self.wallet.handle
assert json.loads(call_offer) == test_offer
assert json.loads(call_request) == test_request
values = json.loads(call_values)
assert "attr1" in values

def mock_revoke(_h, _t, _r, cred_rev_id):
if cred_rev_id == "42":
return json.dumps(TEST_RR_DELTA)
if cred_rev_id == "54":
raise IndyError(
error_code=ErrorCode.AnoncredsInvalidUserRevocId,
error_details={"message": "already revoked"},
)
(cred_json, cred_rev_id) = await self.issuer.create_credential( # main line
test_schema,
test_offer,
test_request,
test_values,
REV_REG_ID,
"/tmp/tails/path/dummy",
)
mock_indy_create_credential.assert_called_once()
(
call_wallet,
call_offer,
call_request,
call_values,
call_etc1,
call_etc2,
) = mock_indy_create_credential.call_args[0]
assert call_wallet is self.wallet.handle
assert json.loads(call_offer) == test_offer
assert json.loads(call_request) == test_request
values = json.loads(call_values)
assert "attr1" in values

def mock_revoke(_h, _t, _r, cred_rev_id):
if cred_rev_id == "42":
return json.dumps(TEST_RR_DELTA)
if cred_rev_id == "54":
raise IndyError(
error_code=ErrorCode.UnknownCryptoTypeError,
error_details={"message": "truly an outlier"},
error_code=ErrorCode.AnoncredsInvalidUserRevocId,
error_details={"message": "already revoked"},
)

mock_indy_revoke_credential.side_effect = mock_revoke
mock_indy_merge_rr_deltas.return_value = json.dumps(TEST_RR_DELTA)
(result, failed) = await self.issuer.revoke_credentials(
REV_REG_ID, tails_file_path="dummy", cred_rev_ids=test_cred_rev_ids
raise IndyError(
error_code=ErrorCode.UnknownCryptoTypeError,
error_details={"message": "truly an outlier"},
)
assert json.loads(result) == TEST_RR_DELTA
assert failed == ["54", "103"]
assert mock_indy_revoke_credential.call_count == 3
mock_indy_merge_rr_deltas.assert_not_called()

mock_indy_revoke_credential.side_effect = mock_revoke
mock_indy_merge_rr_deltas.return_value = json.dumps(TEST_RR_DELTA)
(result, failed) = await self.issuer.revoke_credentials(
REV_REG_ID, tails_file_path="dummy", cred_rev_ids=test_cred_rev_ids
)
assert json.loads(result) == TEST_RR_DELTA
assert failed == ["54", "103"]
assert mock_indy_revoke_credential.call_count == 3
mock_indy_merge_rr_deltas.assert_not_called()

@async_mock.patch("indy.anoncreds.issuer_create_credential")
@async_mock.patch.object(test_module, "create_tails_reader", autospec=True)
Expand All @@ -357,25 +325,14 @@ async def test_create_credential_rr_full(
error_code=ErrorCode.AnoncredsRevocationRegistryFullError
)

with async_mock.patch.object(
test_module, "IssuerCredRevRecord", async_mock.MagicMock()
) as mock_issuer_cr_rec:
mock_issuer_cr_rec.return_value.save = async_mock.CoroutineMock()
mock_issuer_cr_rec.retrieve_by_ids = async_mock.CoroutineMock(
return_value=async_mock.MagicMock(
set_state=async_mock.CoroutineMock(),
)
with self.assertRaises(IndyIssuerRevocationRegistryFullError):
await self.issuer.create_credential(
test_schema,
test_offer,
test_request,
test_values,
)

with self.assertRaises(IndyIssuerRevocationRegistryFullError):
await self.issuer.create_credential(
test_schema,
test_offer,
test_request,
test_values,
"dummy-cxid",
)

@async_mock.patch("indy.anoncreds.issuer_create_credential")
@async_mock.patch.object(test_module, "create_tails_reader", autospec=True)
async def test_create_credential_x_indy(
Expand All @@ -400,25 +357,14 @@ async def test_create_credential_x_indy(
error_code=ErrorCode.WalletInvalidHandle
)

with async_mock.patch.object(
test_module, "IssuerCredRevRecord", async_mock.MagicMock()
) as mock_issuer_cr_rec:
mock_issuer_cr_rec.return_value.save = async_mock.CoroutineMock()
mock_issuer_cr_rec.retrieve_by_ids = async_mock.CoroutineMock(
return_value=async_mock.MagicMock(
set_state=async_mock.CoroutineMock(),
)
with self.assertRaises(test_module.IndyIssuerError):
await self.issuer.create_credential(
test_schema,
test_offer,
test_request,
test_values,
)

with self.assertRaises(test_module.IndyIssuerError):
await self.issuer.create_credential(
test_schema,
test_offer,
test_request,
test_values,
"dummy-cxid",
)

@async_mock.patch("indy.anoncreds.issuer_create_and_store_revoc_reg")
@async_mock.patch.object(test_module, "create_tails_writer", autospec=True)
async def test_create_and_store_revocation_registry(
Expand Down
Loading

0 comments on commit 6d65a25

Please sign in to comment.