Skip to content

Commit

Permalink
Merge pull request #1897 from ianco/master
Browse files Browse the repository at this point in the history
Fixes a few AATH failures
  • Loading branch information
ianco authored Aug 16, 2022
2 parents d407c48 + 331ff16 commit 5df3bc8
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 20 deletions.
8 changes: 6 additions & 2 deletions aries_cloudagent/ledger/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ def backend(self) -> str:
def read_only(self) -> bool:
"""Accessor for the ledger read-only flag."""

@abstractmethod
async def is_ledger_read_only(self) -> bool:
"""Check if ledger is read-only including TAA."""

@abstractmethod
async def get_key_for_did(self, did: str) -> str:
"""Fetch the verkey for a ledger DID.
Expand Down Expand Up @@ -266,7 +270,7 @@ async def create_and_send_schema(
LOGGER.warning("Schema already exists on ledger. Returning details.")
schema_id, schema_def = schema_info
else:
if self.read_only:
if await self.is_ledger_read_only():
raise LedgerError(
"Error cannot write schema when ledger is in read only mode"
)
Expand Down Expand Up @@ -461,7 +465,7 @@ async def create_and_send_credential_definition(
except IndyIssuerError as err:
raise LedgerError(err.message) from err

if self.read_only:
if await self.is_ledger_read_only():
raise LedgerError(
"Error cannot write cred def when ledger is in read only mode"
)
Expand Down
16 changes: 14 additions & 2 deletions aries_cloudagent/ledger/indy.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,18 @@ def read_only(self) -> bool:
"""Accessor for the ledger read-only flag."""
return self.pool.read_only

async def is_ledger_read_only(self) -> bool:
"""Check if ledger is read-only including TAA."""
if self.read_only:
return self.read_only
# if TAA is required and not accepted we should be in read-only mode
taa = await self.get_txn_author_agreement()
if taa["taa_required"]:
taa_acceptance = await self.get_latest_txn_author_acceptance()
if "mechanism" not in taa_acceptance:
return True
return self.read_only

async def __aenter__(self) -> "IndySdkLedger":
"""
Context manager entry.
Expand Down Expand Up @@ -758,7 +770,7 @@ async def update_endpoint_for_did(
)

if exist_endpoint_of_type != endpoint:
if self.pool.read_only:
if await self.is_ledger_read_only():
raise LedgerError(
"Error cannot update endpoint when ledger is in read only mode"
)
Expand Down Expand Up @@ -811,7 +823,7 @@ async def register_nym(
alias: Human-friendly alias to assign to the DID.
role: For permissioned ledgers, what role should the new DID have.
"""
if self.pool.read_only:
if await self.is_ledger_read_only():
raise LedgerError(
"Error cannot register nym when ledger is in read only mode"
)
Expand Down
12 changes: 12 additions & 0 deletions aries_cloudagent/ledger/indy_vdr.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,18 @@ def read_only(self) -> bool:
"""Accessor for the ledger read-only flag."""
return self.pool.read_only

async def is_ledger_read_only(self) -> bool:
"""Check if ledger is read-only including TAA."""
if self.read_only:
return self.read_only
# if TAA is required and not accepted we should be in read-only mode
taa = await self.get_txn_author_agreement()
if taa["taa_required"]:
taa_acceptance = await self.get_latest_txn_author_acceptance()
if "mechanism" not in taa_acceptance:
return True
return self.read_only

async def __aenter__(self) -> "IndyVdrLedger":
"""
Context manager entry.
Expand Down
68 changes: 64 additions & 4 deletions aries_cloudagent/ledger/tests/test_indy.py
Original file line number Diff line number Diff line change
Expand Up @@ -537,8 +537,10 @@ async def test_txn_endorse(
@async_mock.patch("aries_cloudagent.storage.indy.IndySdkStorage.add_record")
@async_mock.patch("indy.ledger.build_schema_request")
@async_mock.patch("indy.ledger.append_request_endorser")
@async_mock.patch("aries_cloudagent.ledger.indy.IndySdkLedger.is_ledger_read_only")
async def test_send_schema(
self,
mock_is_ledger_read_only,
mock_append_request_endorser,
mock_build_schema_req,
mock_add_record,
Expand All @@ -550,6 +552,7 @@ async def test_send_schema(
):
mock_wallet = async_mock.MagicMock()
self.session.context.injector.bind_provider(BaseWallet, mock_wallet)
mock_is_ledger_read_only.return_value = False

issuer = async_mock.MagicMock(IndyIssuer)
ledger = IndySdkLedger(IndySdkLedgerPool("name", checked=True), self.profile)
Expand Down Expand Up @@ -677,8 +680,10 @@ async def test_send_schema_already_exists(
)
@async_mock.patch("aries_cloudagent.storage.indy.IndySdkStorage.add_record")
@async_mock.patch("indy.ledger.build_schema_request")
@async_mock.patch("aries_cloudagent.ledger.indy.IndySdkLedger.is_ledger_read_only")
async def test_send_schema_ledger_transaction_error_already_exists(
self,
mock_is_ledger_read_only,
mock_build_schema_req,
mock_add_record,
mock_check_existing,
Expand All @@ -690,6 +695,7 @@ async def test_send_schema_ledger_transaction_error_already_exists(

mock_wallet = async_mock.MagicMock()
self.session.context.injector.bind_provider(BaseWallet, mock_wallet)
mock_is_ledger_read_only.return_value = False

issuer = async_mock.MagicMock(IndyIssuer)
issuer.create_schema.return_value = ("1", "{}")
Expand Down Expand Up @@ -764,8 +770,10 @@ async def test_send_schema_ledger_read_only(
@async_mock.patch(
"aries_cloudagent.ledger.indy.IndySdkLedger.check_existing_schema"
)
@async_mock.patch("aries_cloudagent.ledger.indy.IndySdkLedger.is_ledger_read_only")
async def test_send_schema_issuer_error(
self,
mock_is_ledger_read_only,
mock_check_existing,
mock_close_pool,
mock_open_ledger,
Expand All @@ -775,6 +783,7 @@ async def test_send_schema_issuer_error(

mock_wallet = async_mock.MagicMock()
self.session.context.injector.bind_provider(BaseWallet, mock_wallet)
mock_is_ledger_read_only.return_value = False

issuer = async_mock.MagicMock(IndyIssuer)
issuer.create_schema = async_mock.CoroutineMock(
Expand Down Expand Up @@ -850,8 +859,10 @@ async def test_send_schema_ledger_transaction_error(
)
@async_mock.patch("aries_cloudagent.storage.indy.IndySdkStorage.add_record")
@async_mock.patch("indy.ledger.build_schema_request")
@async_mock.patch("aries_cloudagent.ledger.indy.IndySdkLedger.is_ledger_read_only")
async def test_send_schema_no_seq_no(
self,
mock_is_ledger_read_only,
mock_build_schema_req,
mock_add_record,
mock_fetch_schema_by_seq_no,
Expand All @@ -863,6 +874,7 @@ async def test_send_schema_no_seq_no(
mock_wallet = async_mock.MagicMock()
self.session.context.injector.bind_provider(BaseWallet, mock_wallet)
issuer = async_mock.MagicMock(IndyIssuer)
mock_is_ledger_read_only.return_value = False
ledger = IndySdkLedger(IndySdkLedgerPool("name", checked=True), self.profile)
issuer.create_schema.return_value = ("schema_issuer_did:name:1.0", "{}")
mock_fetch_schema_by_id.return_value = None
Expand Down Expand Up @@ -1143,8 +1155,10 @@ async def test_get_schema_by_wrong_seq_no(
@async_mock.patch("aries_cloudagent.storage.indy.IndySdkStorage.find_all_records")
@async_mock.patch("aries_cloudagent.storage.indy.IndySdkStorage.add_record")
@async_mock.patch("indy.ledger.build_cred_def_request")
@async_mock.patch("aries_cloudagent.ledger.indy.IndySdkLedger.is_ledger_read_only")
async def test_send_credential_definition(
self,
mock_is_ledger_read_only,
mock_build_cred_def,
mock_add_record,
mock_find_all_records,
Expand All @@ -1157,6 +1171,7 @@ async def test_send_credential_definition(
mock_wallet = async_mock.MagicMock()
self.session.context.injector.bind_provider(BaseWallet, mock_wallet)
mock_find_all_records.return_value = []
mock_is_ledger_read_only.return_value = False

mock_get_schema.return_value = {"seqNo": 999}
cred_def_id = f"{self.test_did}:3:CL:999:default"
Expand Down Expand Up @@ -1231,8 +1246,10 @@ async def test_send_credential_definition(
@async_mock.patch("aries_cloudagent.storage.indy.IndySdkStorage.add_record")
@async_mock.patch("indy.ledger.build_cred_def_request")
@async_mock.patch("indy.ledger.append_request_endorser")
@async_mock.patch("aries_cloudagent.ledger.indy.IndySdkLedger.is_ledger_read_only")
async def test_send_credential_definition_endorse_only(
self,
mock_is_ledger_read_only,
mock_append_request_endorser,
mock_build_cred_def,
mock_add_record,
Expand All @@ -1246,6 +1263,7 @@ async def test_send_credential_definition_endorse_only(
mock_wallet = async_mock.MagicMock()
self.session.context.injector.bind_provider(BaseWallet, mock_wallet)
mock_find_all_records.return_value = []
mock_is_ledger_read_only.return_value = False

mock_get_schema.return_value = {"seqNo": 999}
cred_def_id = f"{self.test_did}:3:CL:999:default"
Expand Down Expand Up @@ -2229,8 +2247,10 @@ async def test_get_endpoint_for_did_no_endpoint(
@async_mock.patch("indy.ledger.build_get_attrib_request")
@async_mock.patch("indy.ledger.build_attrib_request")
@async_mock.patch("aries_cloudagent.ledger.indy.IndySdkLedger._submit")
@async_mock.patch("aries_cloudagent.ledger.indy.IndySdkLedger.is_ledger_read_only")
async def test_update_endpoint_for_did(
self,
mock_is_ledger_read_only,
mock_submit,
mock_build_attrib_req,
mock_build_get_attrib_req,
Expand All @@ -2240,6 +2260,7 @@ async def test_update_endpoint_for_did(
mock_wallet = async_mock.MagicMock()
self.session.context.injector.bind_provider(BaseWallet, mock_wallet)
endpoint = ["http://old.aries.ca", "http://new.aries.ca"]
mock_is_ledger_read_only.return_value = False
mock_submit.side_effect = [
json.dumps(
{
Expand Down Expand Up @@ -2283,8 +2304,10 @@ async def test_update_endpoint_for_did(
@async_mock.patch("indy.ledger.build_get_attrib_request")
@async_mock.patch("indy.ledger.build_attrib_request")
@async_mock.patch("aries_cloudagent.ledger.indy.IndySdkLedger._submit")
@async_mock.patch("aries_cloudagent.ledger.indy.IndySdkLedger.is_ledger_read_only")
async def test_update_endpoint_for_did_no_prior_endpoints(
self,
mock_is_ledger_read_only,
mock_submit,
mock_build_attrib_req,
mock_build_get_attrib_req,
Expand All @@ -2294,6 +2317,7 @@ async def test_update_endpoint_for_did_no_prior_endpoints(
mock_wallet = async_mock.MagicMock()
self.session.context.injector.bind_provider(BaseWallet, mock_wallet)
endpoint = "http://new.aries.ca"
mock_is_ledger_read_only.return_value = False
ledger = IndySdkLedger(IndySdkLedgerPool("name", checked=True), self.profile)
with async_mock.patch.object(
IndySdkWallet, "get_public_did"
Expand Down Expand Up @@ -2329,8 +2353,10 @@ async def test_update_endpoint_for_did_no_prior_endpoints(
@async_mock.patch("indy.ledger.build_get_attrib_request")
@async_mock.patch("indy.ledger.build_attrib_request")
@async_mock.patch("aries_cloudagent.ledger.indy.IndySdkLedger._submit")
@async_mock.patch("aries_cloudagent.ledger.indy.IndySdkLedger.is_ledger_read_only")
async def test_update_endpoint_of_type_profile_for_did(
self,
mock_is_ledger_read_only,
mock_submit,
mock_build_attrib_req,
mock_build_get_attrib_req,
Expand All @@ -2341,6 +2367,7 @@ async def test_update_endpoint_of_type_profile_for_did(
self.session.context.injector.bind_provider(BaseWallet, mock_wallet)
endpoint = ["http://company.com/oldProfile", "http://company.com/newProfile"]
endpoint_type = EndpointType.PROFILE
mock_is_ledger_read_only.return_value = False
mock_submit.side_effect = [
json.dumps(
{
Expand All @@ -2354,6 +2381,11 @@ async def test_update_endpoint_of_type_profile_for_did(
for i in range(len(endpoint))
]
ledger = IndySdkLedger(IndySdkLedgerPool("name", checked=True), self.profile)
# ledger = async_mock.patch.object(
# ledger,
# "is_ledger_read_only",
# async_mock.CoroutineMock(return_value=False),
# )
with async_mock.patch.object(
IndySdkWallet, "get_public_did"
) as mock_wallet_get_public_did:
Expand Down Expand Up @@ -2446,11 +2478,18 @@ async def test_update_endpoint_for_did_read_only(
@async_mock.patch("aries_cloudagent.ledger.indy.IndySdkLedgerPool.context_close")
@async_mock.patch("indy.ledger.build_nym_request")
@async_mock.patch("aries_cloudagent.ledger.indy.IndySdkLedger._submit")
@async_mock.patch("aries_cloudagent.ledger.indy.IndySdkLedger.is_ledger_read_only")
async def test_register_nym(
self, mock_submit, mock_build_nym_req, mock_close, mock_open
self,
mock_is_ledger_read_only,
mock_submit,
mock_build_nym_req,
mock_close,
mock_open,
):
mock_wallet = async_mock.MagicMock()
self.session.context.injector.bind_provider(BaseWallet, mock_wallet)
mock_is_ledger_read_only.return_value = False
with async_mock.patch.object(
IndySdkWallet, "get_public_did"
) as mock_wallet_get_public_did, async_mock.patch.object(
Expand Down Expand Up @@ -2518,12 +2557,19 @@ async def test_register_nym_read_only(self, mock_close, mock_open):

@async_mock.patch("aries_cloudagent.ledger.indy.IndySdkLedgerPool.context_open")
@async_mock.patch("aries_cloudagent.ledger.indy.IndySdkLedgerPool.context_close")
async def test_register_nym_no_public_did(self, mock_close, mock_open):
@async_mock.patch("aries_cloudagent.ledger.indy.IndySdkLedger.is_ledger_read_only")
async def test_register_nym_no_public_did(
self,
mock_is_ledger_read_only,
mock_close,
mock_open,
):
mock_wallet = async_mock.MagicMock(
type="indy",
get_local_did=async_mock.CoroutineMock(),
replace_local_did_metadata=async_mock.CoroutineMock(),
)
mock_is_ledger_read_only.return_value = False
self.session.context.injector.bind_provider(BaseWallet, mock_wallet)
ledger = IndySdkLedger(IndySdkLedgerPool("name", checked=True), self.profile)
with async_mock.patch.object(
Expand All @@ -2543,14 +2589,21 @@ async def test_register_nym_no_public_did(self, mock_close, mock_open):
@async_mock.patch("aries_cloudagent.ledger.indy.IndySdkLedgerPool.context_close")
@async_mock.patch("indy.ledger.build_nym_request")
@async_mock.patch("aries_cloudagent.ledger.indy.IndySdkLedger._submit")
@async_mock.patch("aries_cloudagent.ledger.indy.IndySdkLedger.is_ledger_read_only")
async def test_register_nym_ledger_x(
self, mock_submit, mock_build_nym_req, mock_close, mock_open
self,
mock_is_ledger_read_only,
mock_submit,
mock_build_nym_req,
mock_close,
mock_open,
):
mock_wallet = async_mock.MagicMock()
mock_build_nym_req.side_effect = IndyError(
error_code=ErrorCode.CommonInvalidParam1,
error_details={"message": "not today"},
)
mock_is_ledger_read_only.return_value = False
self.session.context.injector.bind_provider(BaseWallet, mock_wallet)
ledger = IndySdkLedger(IndySdkLedgerPool("name", checked=True), self.profile)
with async_mock.patch.object(
Expand All @@ -2570,11 +2623,18 @@ async def test_register_nym_ledger_x(
@async_mock.patch("aries_cloudagent.ledger.indy.IndySdkLedgerPool.context_close")
@async_mock.patch("indy.ledger.build_nym_request")
@async_mock.patch("aries_cloudagent.ledger.indy.IndySdkLedger._submit")
@async_mock.patch("aries_cloudagent.ledger.indy.IndySdkLedger.is_ledger_read_only")
async def test_register_nym_steward_register_others_did(
self, mock_submit, mock_build_nym_req, mock_close, mock_open
self,
mock_is_ledger_read_only,
mock_submit,
mock_build_nym_req,
mock_close,
mock_open,
):
mock_wallet = async_mock.MagicMock()
self.session.context.injector.bind_provider(BaseWallet, mock_wallet)
mock_is_ledger_read_only.return_value = False
ledger = IndySdkLedger(IndySdkLedgerPool("name", checked=True), self.profile)
with async_mock.patch.object(
IndySdkWallet, "get_public_did"
Expand Down
6 changes: 6 additions & 0 deletions aries_cloudagent/ledger/tests/test_indy_vdr.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ async def close():

with async_mock.patch.object(ledger.pool, "open", open), async_mock.patch.object(
ledger.pool, "close", close
), async_mock.patch.object(
ledger, "is_ledger_read_only", async_mock.CoroutineMock(return_value=False)
):
yield ledger

Expand Down Expand Up @@ -302,6 +304,10 @@ async def test_send_schema_ledger_read_only(
ledger,
"check_existing_schema",
async_mock.CoroutineMock(return_value=False),
), async_mock.patch.object(
ledger,
"is_ledger_read_only",
async_mock.CoroutineMock(return_value=True),
):
with pytest.raises(LedgerError):
schema_id, schema_def = await ledger.create_and_send_schema(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,14 @@ async def mediation_record_for_connection(
or_default: bool = False,
):
"""Return relevant mediator for connection."""
async with profile.session() as session:
mediation_metadata = await conn_record.metadata_get(
session, MediationManager.METADATA_KEY, {}
)
mediation_id = (
mediation_metadata.get(MediationManager.METADATA_ID) or mediation_id
)
if conn_record.connection_id:
async with profile.session() as session:
mediation_metadata = await conn_record.metadata_get(
session, MediationManager.METADATA_KEY, {}
)
mediation_id = (
mediation_metadata.get(MediationManager.METADATA_ID) or mediation_id
)

mediation_record = await self.mediation_record_if_id(
profile, mediation_id, or_default
Expand Down
Loading

0 comments on commit 5df3bc8

Please sign in to comment.