Skip to content

Commit 00d97b3

Browse files
authored
Merge pull request openwallet-foundation#1734 from Indicio-tech/feat/revocation-notification-v2
Feat/revocation notification v2
2 parents a4013f4 + ac4fe65 commit 00d97b3

22 files changed

Lines changed: 714 additions & 1 deletion

aries_cloudagent/protocols/revocation_notification/definition.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,11 @@
66
"minimum_minor_version": 0,
77
"current_minor_version": 0,
88
"path": "v1_0",
9-
}
9+
},
10+
{
11+
"major_version": 2,
12+
"minimum_minor_version": 0,
13+
"current_minor_version": 0,
14+
"path": "v2_0",
15+
},
1016
]

aries_cloudagent/protocols/revocation_notification/v1_0/models/rev_notification_record.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class Meta:
2727
"rev_reg_id",
2828
"cred_rev_id",
2929
"connection_id",
30+
"version",
3031
}
3132

3233
def __init__(
@@ -38,6 +39,7 @@ def __init__(
3839
connection_id: str = None,
3940
thread_id: str = None,
4041
comment: str = None,
42+
version: str = None,
4143
**kwargs,
4244
):
4345
"""Construct record."""
@@ -47,6 +49,7 @@ def __init__(
4749
self.connection_id = connection_id
4850
self.thread_id = thread_id
4951
self.comment = comment
52+
self.version = version
5053

5154
@property
5255
def revocation_notification_id(self) -> Optional[str]:
@@ -73,6 +76,7 @@ async def query_by_ids(
7376
rev_reg_id: the rev reg id by which to filter
7477
"""
7578
tag_filter = {
79+
**{"version": "v1_0"},
7680
**{"cred_rev_id": cred_rev_id for _ in [""] if cred_rev_id},
7781
**{"rev_reg_id": rev_reg_id for _ in [""] if rev_reg_id},
7882
}
@@ -101,6 +105,7 @@ async def query_by_rev_reg_id(
101105
rev_reg_id: the rev reg id by which to filter
102106
"""
103107
tag_filter = {
108+
**{"version": "v1_0"},
104109
**{"rev_reg_id": rev_reg_id for _ in [""] if rev_reg_id},
105110
}
106111

@@ -157,3 +162,7 @@ class Meta:
157162
description="Optional comment to include in revocation notification",
158163
required=False,
159164
)
165+
version = fields.Str(
166+
description="Version of Revocation Notification to send out",
167+
required=False,
168+
)

aries_cloudagent/protocols/revocation_notification/v1_0/models/tests/test_rev_notification_record.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ def rec():
2121
connection_id="mock_connection_id",
2222
thread_id="mock_thread_id",
2323
comment="mock_comment",
24+
version="v1_0",
2425
)
2526

2627

@@ -50,6 +51,7 @@ async def test_storage(profile, rec):
5051
another = RevNotificationRecord(
5152
rev_reg_id="mock_rev_reg_id",
5253
cred_rev_id="mock_cred_rev_id",
54+
version="v1_0",
5355
)
5456
await another.save(session)
5557
await RevNotificationRecord.query_by_ids(

aries_cloudagent/protocols/revocation_notification/v2_0/__init__.py

Whitespace-only changes.

aries_cloudagent/protocols/revocation_notification/v2_0/handlers/__init__.py

Whitespace-only changes.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
"""Handler for revoke message."""
2+
3+
from .....messaging.base_handler import BaseHandler
4+
from .....messaging.request_context import RequestContext
5+
from .....messaging.responder import BaseResponder
6+
7+
from ..messages.revoke import Revoke
8+
9+
10+
class RevokeHandler(BaseHandler):
11+
"""Handler for revoke message."""
12+
13+
RECIEVED_TOPIC = "acapy::revocation-notification-v2::received"
14+
WEBHOOK_TOPIC = "acapy::webhook::revocation-notification-v2"
15+
16+
async def handle(self, context: RequestContext, responder: BaseResponder):
17+
"""Handle revoke message."""
18+
assert isinstance(context.message, Revoke)
19+
self._logger.debug(
20+
"Received notification of revocation for %s cred %s with comment: %s",
21+
context.message.revocation_format,
22+
context.message.credential_id,
23+
context.message.comment,
24+
)
25+
# Emit a webhook
26+
if context.settings.get("revocation.monitor_notification"):
27+
await context.profile.notify(
28+
self.WEBHOOK_TOPIC,
29+
{
30+
"revocation_format": context.message.revocation_format,
31+
"credential_id": context.message.credential_id,
32+
"comment": context.message.comment,
33+
},
34+
)
35+
36+
# Emit an event
37+
await context.profile.notify(
38+
self.RECIEVED_TOPIC,
39+
{
40+
"revocation_format": context.message.revocation_format,
41+
"credential_id": context.message.credential_id,
42+
"comment": context.message.comment,
43+
},
44+
)

aries_cloudagent/protocols/revocation_notification/v2_0/handlers/tests/__init__.py

Whitespace-only changes.
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
"""Test RevokeHandler."""
2+
3+
import pytest
4+
5+
from ......config.settings import Settings
6+
from ......core.event_bus import EventBus, MockEventBus
7+
from ......core.in_memory import InMemoryProfile
8+
from ......core.profile import Profile
9+
from ......messaging.request_context import RequestContext
10+
from ......messaging.responder import MockResponder, BaseResponder
11+
from ...messages.revoke import Revoke
12+
from ..revoke_handler import RevokeHandler
13+
14+
15+
@pytest.fixture
16+
def event_bus():
17+
yield MockEventBus()
18+
19+
20+
@pytest.fixture
21+
def responder():
22+
yield MockResponder()
23+
24+
25+
@pytest.fixture
26+
def profile(event_bus):
27+
yield InMemoryProfile.test_profile(bind={EventBus: event_bus})
28+
29+
30+
@pytest.fixture
31+
def message():
32+
yield Revoke(
33+
revocation_format="indy-anoncreds",
34+
credential_id="mock_cred_revocation_id",
35+
comment="mock_comment",
36+
)
37+
38+
39+
@pytest.fixture
40+
def context(profile: Profile, message: Revoke):
41+
request_context = RequestContext(profile)
42+
request_context.message = message
43+
yield request_context
44+
45+
46+
@pytest.mark.asyncio
47+
async def test_handle(
48+
context: RequestContext, responder: BaseResponder, event_bus: MockEventBus
49+
):
50+
await RevokeHandler().handle(context, responder)
51+
assert event_bus.events
52+
[(_, received)] = event_bus.events
53+
assert received.topic == RevokeHandler.RECIEVED_TOPIC
54+
assert "revocation_format" in received.payload
55+
assert "credential_id" in received.payload
56+
assert "comment" in received.payload
57+
58+
59+
@pytest.mark.asyncio
60+
async def test_handle_monitor(
61+
context: RequestContext, responder: BaseResponder, event_bus: MockEventBus
62+
):
63+
context.settings["revocation.monitor_notification"] = True
64+
await RevokeHandler().handle(context, responder)
65+
[(_, webhook), (_, received)] = event_bus.events
66+
67+
assert webhook.topic == RevokeHandler.WEBHOOK_TOPIC
68+
assert "revocation_format" in received.payload
69+
assert "credential_id" in received.payload
70+
assert "comment" in webhook.payload
71+
72+
assert received.topic == RevokeHandler.RECIEVED_TOPIC
73+
assert "revocation_format" in received.payload
74+
assert "credential_id" in received.payload
75+
assert "comment" in received.payload
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
"""Message type identifiers for Revocation Notification protocol."""
2+
3+
from ...didcomm_prefix import DIDCommPrefix
4+
5+
6+
SPEC_URI = (
7+
"https://github.com/hyperledger/aries-rfcs/blob/main/features/"
8+
"0721-revocation-notification-v2/README.md"
9+
)
10+
PROTOCOL = "revocation_notification"
11+
VERSION = "2.0"
12+
BASE = f"{PROTOCOL}/{VERSION}"
13+
14+
# Message types
15+
REVOKE = f"{BASE}/revoke"
16+
17+
PROTOCOL_PACKAGE = "aries_cloudagent.protocols.revocation_notification.v2_0"
18+
MESSAGE_TYPES = DIDCommPrefix.qualify_all(
19+
{REVOKE: f"{PROTOCOL_PACKAGE}.messages.revoke.Revoke"}
20+
)

aries_cloudagent/protocols/revocation_notification/v2_0/messages/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)