Skip to content
This repository was archived by the owner on Sep 22, 2023. It is now read-only.

Commit

Permalink
Merge pull request #123 from Indicio-tech/feature/oob-didex-admin
Browse files Browse the repository at this point in the history
Feature/oob didex admin
  • Loading branch information
dbluhm authored Mar 7, 2022
2 parents 0f6a4bd + 4a14456 commit 418af4b
Show file tree
Hide file tree
Showing 9 changed files with 709 additions and 450 deletions.
51 changes: 49 additions & 2 deletions acapy_plugin_toolbox/connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,13 @@
RequestContext,
)
from aries_cloudagent.protocols.connections.v1_0.manager import ConnectionManager
from aries_cloudagent.protocols.out_of_band.v1_0.manager import OutOfBandManager
from aries_cloudagent.protocols.connections.v1_0.messages.connection_invitation import (
ConnectionInvitation,
)
from aries_cloudagent.protocols.out_of_band.v1_0.messages.invitation import (
InvitationMessage,
)
from aries_cloudagent.protocols.problem_report.v1_0.message import ProblemReport
from aries_cloudagent.storage.error import StorageNotFoundError
from marshmallow import Schema, fields, validate
Expand All @@ -38,17 +42,19 @@
DELETE = "{}/delete".format(PROTOCOL)
DELETED = "{}/deleted".format(PROTOCOL)
RECEIVE_INVITATION = "{}/receive-invitation".format(PROTOCOL)
RECEIVE_OOB_INVITATION = "{}/receive-oob-invitation".format(PROTOCOL)
CONNECTED = "{}/connected".format(PROTOCOL)

# Message Type string to Message Class map
MESSAGE_TYPES = {
GET_LIST: "acapy_plugin_toolbox.connections.GetList",
LIST: "acapy_plugin_toolbox.connections.List",
UPDATE: "acapy_plugin_toolbox.connections.Update",
CONNECTION: "acapy_plugin_toolbox.connections.Connnection",
CONNECTION: "acapy_plugin_toolbox.connections.Connection",
DELETE: "acapy_plugin_toolbox.connections.Delete",
DELETED: "acapy_plugin_toolbox.connections.Deleted",
RECEIVE_INVITATION: "acapy_plugin_toolbox.connections." "ReceiveInvitation",
RECEIVE_OOB_INVITATION: "acapy_plugin_toolbox.connections." "ReceiveOOBInvitation",
CONNECTED: "acapy_plugin_toolbox.connections.Connected",
}

Expand All @@ -71,7 +77,18 @@ async def connections_event_handler(profile: Profile, event: Event):
Send connected message to admins when connections reach active state.
"""
record: ConnRecord = ConnRecord.deserialize(event.payload)
if record.state == ConnRecord.State.RESPONSE:
if (
record.connection_protocol == ConnRecord.Protocol.RFC_0160.value
and record.state == ConnRecord.State.RESPONSE
):
responder = profile.inject(BaseResponder)
await send_to_admins(
profile, Connected(**conn_record_to_message_repr(record)), responder
)
if (
record.connection_protocol == ConnRecord.Protocol.RFC_0023.value
and record.state == ConnRecord.State.COMPLETED
):
responder = profile.inject(BaseResponder)
await send_to_admins(
profile, Connected(**conn_record_to_message_repr(record)), responder
Expand Down Expand Up @@ -281,6 +298,17 @@ async def handle(self, context: RequestContext, responder: BaseResponder):
},
)

ReceiveOOBInvitation, ReceiveOOBInvitationSchema = generate_model_schema(
name="ReceiveOOBInvitation",
handler="acapy_plugin_toolbox.connections.ReceiveOOBInvitationHandler",
msg_type=RECEIVE_OOB_INVITATION,
schema={
"invitation": fields.Str(required=True),
"auto_accept": fields.Bool(missing=False),
"mediation_id": fields.Str(required=False),
},
)


class ReceiveInvitationHandler(BaseHandler):
"""Handler for receive invitation request."""
Expand All @@ -299,3 +327,22 @@ async def handle(self, context: RequestContext, responder: BaseResponder):
connection_resp = Connection(**conn_record_to_message_repr(connection))
connection_resp.assign_thread_from(context.message)
await responder.send_reply(connection_resp)


class ReceiveOOBInvitationHandler(BaseHandler):
"""Handler for receive oob invitation request."""

@admin_only
async def handle(self, context: RequestContext, responder: BaseResponder):
"""Handle recieve oob invitation request."""
profile = context.profile
oob_mgr = OutOfBandManager(profile)
invitation = InvitationMessage.from_url(context.message.invitation)
connection = await oob_mgr.receive_invitation(
invitation,
auto_accept=context.message.auto_accept,
mediation_id=context.message.mediation_id,
)
connection_resp = Connection(**conn_record_to_message_repr(connection))
connection_resp.assign_thread_from(context.message)
await responder.send_reply(connection_resp)
96 changes: 85 additions & 11 deletions acapy_plugin_toolbox/invitations.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@
)
from aries_cloudagent.protocols.connections.v1_0.manager import ConnectionManager
from aries_cloudagent.connections.models.conn_record import ConnRecord
from aries_cloudagent.protocols.out_of_band.v1_0.manager import OutOfBandManager
from aries_cloudagent.protocols.out_of_band.v1_0.messages.invitation import HSProto

from aries_cloudagent.protocols.out_of_band.v1_0.messages.invitation import (
InvitationMessage,
)
from aries_cloudagent.protocols.connections.v1_0.messages.connection_invitation import (
ConnectionInvitation,
)

# ProblemReport will probably be needed when a delete message is implemented
# from aries_cloudagent.protocols.problem_report.v1_0.message import ProblemReport
Expand All @@ -32,14 +41,19 @@
INVITATION_LIST = "{}/list".format(PROTOCOL)
CREATE_INVITATION = "{}/create".format(PROTOCOL)
INVITATION = "{}/invitation".format(PROTOCOL)
OOB_CREATE = "{}/oob-create".format(PROTOCOL)

# Message Type string to Message Class map
MESSAGE_TYPES = {
CREATE_INVITATION: "acapy_plugin_toolbox.invitations" ".CreateInvitation",
INVITATION_GET_LIST: "acapy_plugin_toolbox.invitations" ".InvitationGetList",
INVITATION: "acapy_plugin_toolbox.invitations" ".Invitation",
OOB_CREATE: "acapy_plugin_toolbox.invitations" ".OOBCreateInvitation",
}

OOB_INVITE_TYPE = "https://didcomm.org/out-of-band/1.0/invitation"
CONN_INVITE_TYPE = "https://didcomm.org/connections/1.0/invitation"


async def setup(session: ProfileSession, protocol_registry: ProtocolRegistry = None):
"""Setup the connections plugin."""
Expand Down Expand Up @@ -70,10 +84,25 @@ async def setup(session: ProfileSession, protocol_registry: ProtocolRegistry = N
},
)

OOBCreateInvitation, OOBCreateInvitationSchema = generate_model_schema(
name="OOBCreateInvitation",
handler="acapy_plugin_toolbox.invitations.OOBCreateInvitationHandler",
msg_type=OOB_CREATE,
schema={
"label": fields.Str(required=False),
"alias": fields.Str(required=False), # default?
"group": fields.Str(required=False),
"auto_accept": fields.Boolean(missing=False),
"multi_use": fields.Boolean(missing=False),
"mediation_id": fields.Str(required=False),
},
)

BaseInvitationSchema = Schema.from_dict(
{
"id": fields.Str(required=True),
"label": fields.Str(required=False),
"invitation_type": fields.Str(required=True),
"alias": fields.Str(required=False), # default?
"group": fields.Str(required=False),
"auto_accept": fields.Boolean(missing=False),
Expand Down Expand Up @@ -126,6 +155,7 @@ async def handle(self, context: RequestContext, responder: BaseResponder):
invite_response = Invitation(
id=connection.connection_id,
label=invitation.label,
invitation_type=CONN_INVITE_TYPE,
alias=connection.alias,
group=context.message.group,
auto_accept=connection.accept == ConnRecord.ACCEPT_AUTO,
Expand All @@ -142,26 +172,61 @@ async def handle(self, context: RequestContext, responder: BaseResponder):
await responder.send_reply(invite_response)


class OOBCreateInvitationHandler(BaseHandler):
"""Handler for OOB create invitation request."""

@admin_only
async def handle(self, context: RequestContext, responder: BaseResponder):
"""Handle OOB create invitation request."""
session = await context.session()
profile = context.profile
connection_mgr = OutOfBandManager(profile)
invitation_record = await connection_mgr.create_invitation(
my_label=context.message.label,
auto_accept=context.message.auto_accept,
multi_use=bool(context.message.multi_use),
public=False,
alias=context.message.alias,
mediation_id=context.message.mediation_id,
hs_protos=[HSProto.RFC23, HSProto.RFC160],
)
connection = await ConnRecord.retrieve_by_invitation_msg_id(
session, invitation_record.invi_msg_id
)
if context.message.group:
await connection.metadata_set(session, "group", context.message.group)
invite_response = Invitation(
id=connection.connection_id,
label=invitation_record.invitation.label,
invitation_type=OOB_INVITE_TYPE,
alias=connection.alias,
group=context.message.group,
auto_accept=connection.accept == ConnRecord.ACCEPT_AUTO,
multi_use=(connection.invitation_mode == ConnRecord.INVITATION_MODE_MULTI),
mediation_id=context.message.mediation_id,
invitation_url=invitation_record.invitation_url,
created_date=connection.created_at,
raw_repr={
"connection": connection.serialize(),
"invitation": invitation_record.serialize(),
},
)
invite_response.assign_thread_from(context.message)
await responder.send_reply(invite_response)


class InvitationGetListHandler(BaseHandler):
"""Handler for get invitation list request."""

@admin_only
async def handle(self, context: RequestContext, responder: BaseResponder):
"""Handle get invitation list request."""

tag_filter = dict(filter(lambda item: item[1] is not None, {}.items()))
post_filter_positive = dict(
filter(
lambda item: item[1] is not None,
{
"state": "invitation",
# 'initiator': context.message.initiator,
}.items(),
)
)
post_filter_positive = {"state": "invitation"}

session = await context.session()
records = await ConnRecord.query(
session, tag_filter, post_filter_positive=post_filter_positive
session, post_filter_positive=post_filter_positive
)
results = []
for connection in records:
Expand All @@ -171,11 +236,20 @@ async def handle(self, context: RequestContext, responder: BaseResponder):
continue
group = await connection.metadata_get(session, "group")

invitation_type = (
CONN_INVITE_TYPE
if isinstance(invitation, ConnectionInvitation)
else OOB_INVITE_TYPE
if isinstance(invitation, InvitationMessage)
else None
)

invite = {
"id": connection.connection_id,
"label": invitation.label,
"alias": connection.alias,
"group": group,
"invitation_type": invitation_type,
"auto_accept": (connection.accept == ConnRecord.ACCEPT_AUTO),
"multi_use": (
connection.invitation_mode == ConnRecord.INVITATION_MODE_MULTI
Expand Down
Loading

0 comments on commit 418af4b

Please sign in to comment.