Skip to content
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
65 changes: 1 addition & 64 deletions acapy_agent/anoncreds/revocation/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,10 @@

import logging
from collections.abc import Mapping, Sequence
from typing import TYPE_CHECKING, Optional, Tuple, Type
from typing import TYPE_CHECKING, Optional, Tuple

from ...core.error import BaseError
from ...core.profile import Profile
from ...protocols.issue_credential.v1_0.models.credential_exchange import (
V10CredentialExchange,
)
from ...protocols.issue_credential.v2_0.models.cred_ex_record import V20CredExRecord
from ...protocols.revocation_notification.v1_0.models.rev_notification_record import (
RevNotificationRecord,
)
Expand Down Expand Up @@ -368,62 +364,3 @@ async def set_cred_revoked_state(
updated_cred_rev_ids.append(cred_rev_id)

await txn.commit()

# Check if any requested cred rev ids were not found
missing_cred_rev_ids = [
_id for _id in cred_rev_ids if _id not in updated_cred_rev_ids
]
if missing_cred_rev_ids:
self._logger.warning(
"IssuerCredRevRecord not found for cred_rev_id=%s. Could not revoke.",
missing_cred_rev_ids,
)

# Map cred_ex_version to the record type
_cred_ex_version_map: dict[str, Type[V10CredentialExchange | V20CredExRecord]] = {
IssuerCredRevRecord.VERSION_1: V10CredentialExchange,
IssuerCredRevRecord.VERSION_2: V20CredExRecord,
}

# Update CredEx records for each credential revocation record
for cred_rev_record in cred_rev_records:
async with self._profile.transaction() as txn:
cred_ex_id = cred_rev_record.cred_ex_id
cred_ex_version = cred_rev_record.cred_ex_version
known_record_type = _cred_ex_version_map.get(cred_ex_version)

# If we know the record type, use it, otherwise try both V1 and V2
record_type_to_use = (
[known_record_type]
if known_record_type
else [V10CredentialExchange, V20CredExRecord]
)

for record_type in record_type_to_use:
try:
cred_ex_record = await record_type.retrieve_by_id(
txn, cred_ex_id, for_update=True
)

# Update cred ex record state to indicate revoked
cred_ex_record.state = record_type.STATE_CREDENTIAL_REVOKED
await cred_ex_record.save(txn, reason="revoke credential")

self._logger.debug(
"Updated %s state to REVOKED for cred_ex_id=%s",
record_type.__name__,
cred_ex_id,
)
await txn.commit()
break # Record found, no need to check other record type
except StorageNotFoundError:
# Credential Exchange records may have been deleted, which is fine
self._logger.debug(
"%s not found for cred_ex_id=%s / cred_rev_id=%s.%s",
record_type.__name__,
cred_ex_id,
cred_rev_record.cred_rev_id,
" Checking next record type."
if not known_record_type
else "",
)
105 changes: 5 additions & 100 deletions acapy_agent/anoncreds/revocation/tests/test_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@

import pytest

from ....protocols.issue_credential.v1_0.models.credential_exchange import (
V10CredentialExchange,
)
from ....protocols.issue_credential.v2_0.models.cred_ex_record import V20CredExRecord
from ....revocation.models.issuer_cred_rev_record import IssuerCredRevRecord
from ....tests import mock
from ....utils.testing import create_test_profile
from ...issuer import AnonCredsIssuer
Expand Down Expand Up @@ -108,27 +104,6 @@ async def test_revoke_cred_by_cxid_not_found(self):
with self.assertRaises(RevocationManagerError):
await self.manager.revoke_credential_by_cred_ex_id(CRED_EX_ID)

@pytest.mark.skip(reason="AnonCreds-break")
async def test_revoke_credential_no_rev_reg_rec(self):
V10CredentialExchange(
credential_exchange_id="dummy-cxid",
credential_definition_id=CRED_DEF_ID,
role=V10CredentialExchange.ROLE_ISSUER,
revocation_id=CRED_REV_ID,
revoc_reg_id=REV_REG_ID,
)

with mock.patch.object(test_module, "IndyRevocation", autospec=True) as revoc:
revoc.return_value.get_issuer_rev_reg_record = mock.CoroutineMock(
return_value=None
)

issuer = mock.MagicMock(AnonCredsIssuer, autospec=True)
self.profile.context.injector.bind_instance(AnonCredsIssuer, issuer)

with self.assertRaises(RevocationManagerError):
await self.manager.revoke_credential(REV_REG_ID, CRED_REV_ID)

@pytest.mark.skip(reason="AnonCreds-break")
async def test_revoke_credential_pend(self):
mock_issuer_rev_reg_record = mock.MagicMock(mark_pending=mock.AsyncMock())
Expand Down Expand Up @@ -417,89 +392,19 @@ async def test_clear_pending_1_rev_reg_some(self):
async def test_retrieve_records(self):
session = await self.profile.session()
for index in range(2):
exchange_record = V10CredentialExchange(
exchange_record = V20CredExRecord(
connection_id=str(index),
thread_id=str(1000 + index),
initiator=V10CredentialExchange.INITIATOR_SELF,
role=V10CredentialExchange.ROLE_ISSUER,
initiator=V20CredExRecord.INITIATOR_SELF,
role=V20CredExRecord.ROLE_ISSUER,
state=V20CredExRecord.STATE_ISSUED,
)
await exchange_record.save(session)

for _ in range(2): # second pass gets from cache
for index in range(2):
ret_ex = await V10CredentialExchange.retrieve_by_connection_and_thread(
ret_ex = await V20CredExRecord.retrieve_by_conn_and_thread(
session, str(index), str(1000 + index)
)
assert ret_ex.connection_id == str(index)
assert ret_ex.thread_id == str(1000 + index)

async def test_set_revoked_state_v1(self):
async with self.profile.session() as session:
exchange_record = V10CredentialExchange(
connection_id="mark-revoked-cid",
thread_id="mark-revoked-tid",
initiator=V10CredentialExchange.INITIATOR_SELF,
revoc_reg_id=REV_REG_ID,
revocation_id=CRED_REV_ID,
role=V10CredentialExchange.ROLE_ISSUER,
state=V10CredentialExchange.STATE_ISSUED,
)
await exchange_record.save(session)

crev_record = IssuerCredRevRecord(
cred_ex_id=exchange_record.credential_exchange_id,
cred_def_id=CRED_DEF_ID,
rev_reg_id=REV_REG_ID,
cred_rev_id=CRED_REV_ID,
state=IssuerCredRevRecord.STATE_ISSUED,
)
await crev_record.save(session)

await self.manager.set_cred_revoked_state(REV_REG_ID, [CRED_REV_ID])

async with self.profile.session() as session:
check_exchange_record = await V10CredentialExchange.retrieve_by_id(
session, exchange_record.credential_exchange_id
)
assert (
check_exchange_record.state
== V10CredentialExchange.STATE_CREDENTIAL_REVOKED
)

check_crev_record = await IssuerCredRevRecord.retrieve_by_id(
session, crev_record.record_id
)
assert check_crev_record.state == IssuerCredRevRecord.STATE_REVOKED

async def test_set_revoked_state_v2(self):
async with self.profile.session() as session:
exchange_record = V20CredExRecord(
connection_id="mark-revoked-cid",
thread_id="mark-revoked-tid",
initiator=V20CredExRecord.INITIATOR_SELF,
role=V20CredExRecord.ROLE_ISSUER,
state=V20CredExRecord.STATE_ISSUED,
)
await exchange_record.save(session)

crev_record = IssuerCredRevRecord(
cred_ex_id=exchange_record.cred_ex_id,
cred_def_id=CRED_DEF_ID,
rev_reg_id=REV_REG_ID,
cred_rev_id=CRED_REV_ID,
state=IssuerCredRevRecord.STATE_ISSUED,
)
await crev_record.save(session)

await self.manager.set_cred_revoked_state(REV_REG_ID, [CRED_REV_ID])

async with self.profile.session() as session:
check_exchange_record = await V20CredExRecord.retrieve_by_id(
session, exchange_record.cred_ex_id
)
assert check_exchange_record.state == V20CredExRecord.STATE_CREDENTIAL_REVOKED

check_crev_record = await IssuerCredRevRecord.retrieve_by_id(
session, crev_record.record_id
)
assert check_crev_record.state == IssuerCredRevRecord.STATE_REVOKED
3 changes: 1 addition & 2 deletions acapy_agent/core/oob_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from ..messaging.decorators.service_decorator import ServiceDecorator
from ..messaging.request_context import RequestContext
from ..protocols.didcomm_prefix import DIDCommPrefix
from ..protocols.issue_credential.v1_0.message_types import CREDENTIAL_OFFER
from ..protocols.issue_credential.v2_0.message_types import CRED_20_OFFER
from ..protocols.out_of_band.v1_0.models.oob_record import OobRecord
from ..protocols.present_proof.v1_0.message_types import PRESENTATION_REQUEST
Expand Down Expand Up @@ -301,10 +300,10 @@ async def handle_message(
):
"""Message handler for inbound messages."""
supported_types = [
CREDENTIAL_OFFER,
CRED_20_OFFER,
PRESENTATION_REQUEST,
PRES_20_REQUEST,
"issue-credential/1.0/offer-credential",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be the only reference for issue-credential/1.0. I wasn't able to think of a way to inject it into this class without maybe an ugly monkey patch of the function in the plugin.

]

supported_messages = [
Expand Down
2 changes: 1 addition & 1 deletion acapy_agent/core/tests/test_goal_code_registry.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from unittest import IsolatedAsyncioTestCase

from ...protocols.issue_credential.v1_0.message_types import CONTROLLERS
from ...protocols.issue_credential.v2_0.message_types import CONTROLLERS
from ..goal_code_registry import GoalCodeRegistry


Expand Down
6 changes: 3 additions & 3 deletions acapy_agent/core/tests/test_oob_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ async def test_handle_message_connection(self):
self.profile,
[
{
"@type": "issue-credential/1.0/offer-credential",
"@type": "issue-credential/2.0/offer-credential",
"@id": "4a580490-a9d8-44f5-a3f6-14e0b8a219b0",
}
],
Expand All @@ -706,7 +706,7 @@ async def test_handle_message_connectionless(self):
self.profile,
[
{
"@type": "issue-credential/1.0/offer-credential",
"@type": "issue-credential/2.0/offer-credential",
"@id": "4a580490-a9d8-44f5-a3f6-14e0b8a219b0",
}
],
Expand Down Expand Up @@ -735,7 +735,7 @@ async def test_handle_message_unsupported_message_type(self):
self.profile, [{"@type": "unsupported"}], mock.MagicMock()
)
assert (
"None of the oob attached messages supported. Supported message types are issue-credential/1.0/offer-credential, issue-credential/2.0/offer-credential, present-proof/1.0/request-presentation, present-proof/2.0/request-presentation"
"None of the oob attached messages supported. Supported message types are issue-credential/2.0/offer-credential, present-proof/1.0/request-presentation, present-proof/2.0/request-presentation"
in err.exception.message
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,12 @@
from ......core.protocol_registry import ProtocolRegistry
from ......messaging.request_context import RequestContext
from ......messaging.responder import MockResponder
from ......protocols.issue_credential.v1_0.controller import (
from ......protocols.issue_credential.v2_0.controller import (
ISSUE_VC,
PARTICIPATE_VC_INTERACTION,
)
from ......protocols.issue_credential.v1_0.message_types import (
CONTROLLERS as issue_cred_v1_controller,
)
from ......protocols.present_proof.v1_0.message_types import (
CONTROLLERS as pres_proof_v1_controller,
from ......protocols.issue_credential.v2_0.message_types import (
CONTROLLERS as pres_proof_v2_controller,
)
from ......tests import mock
from ......utils.testing import create_test_profile
Expand All @@ -32,7 +29,7 @@ async def request_context():
protocol_registry = ProtocolRegistry()
goal_code_registry = GoalCodeRegistry()
protocol_registry.register_message_types({TEST_MESSAGE_TYPE: object()})
goal_code_registry.register_controllers(issue_cred_v1_controller)
goal_code_registry.register_controllers(pres_proof_v2_controller)
profile = ctx.profile
profile.context.injector.bind_instance(ProtocolRegistry, protocol_registry)
profile.context.injector.bind_instance(GoalCodeRegistry, goal_code_registry)
Expand Down Expand Up @@ -93,7 +90,7 @@ async def test_queries_protocol_goal_code_all_disclose_list_settings(
protocol_registry.register_message_types({"doc/proto-b/1.0/message": object()})
profile.context.injector.bind_instance(ProtocolRegistry, protocol_registry)
goal_code_registry = profile.inject(GoalCodeRegistry)
goal_code_registry.register_controllers(pres_proof_v1_controller)
goal_code_registry.register_controllers(pres_proof_v2_controller)
profile.context.injector.bind_instance(GoalCodeRegistry, goal_code_registry)
profile.settings["disclose_protocol_list"] = [TEST_MESSAGE_FAMILY]
profile.settings["disclose_goal_code_list"] = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from .....wallet.base import BaseWallet
from .....wallet.did_method import SOV, DIDMethods
from .....wallet.key_type import ED25519, KeyTypes
from ....issue_credential.v1_0.tests import REV_REG_ID
from ....issue_credential.v2_0.tests import REV_REG_ID
from ..manager import TransactionManager, TransactionManagerError
from ..models.transaction_record import TransactionRecord
from ..transaction_jobs import TransactionJob
Expand Down
6 changes: 0 additions & 6 deletions acapy_agent/protocols/issue_credential/definition.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
"""Version definitions for this protocol."""

versions = [
{
"major_version": 1,
"minimum_minor_version": 0,
"current_minor_version": 0,
"path": "v1_0",
},
{
"major_version": 2,
"minimum_minor_version": 0,
Expand Down
60 changes: 0 additions & 60 deletions acapy_agent/protocols/issue_credential/v1_0/__init__.py

This file was deleted.

Loading
Loading