Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BREAKING: Allow multi-use public invites and public invites with metadata #2034

Merged
Merged
146 changes: 78 additions & 68 deletions aries_cloudagent/protocols/connections/v1_0/manager.py
Original file line number Diff line number Diff line change
@@ -127,10 +127,42 @@ async def create_invitation(
or_default=True,
)
image_url = self.profile.context.settings.get("image_url")
invitation = None
connection = None

invitation_mode = ConnRecord.INVITATION_MODE_ONCE
if multi_use:
invitation_mode = ConnRecord.INVITATION_MODE_MULTI

if not my_label:
my_label = self.profile.settings.get("default_label")

accept = (
ConnRecord.ACCEPT_AUTO
if (
auto_accept
or (
auto_accept is None
and self.profile.settings.get("debug.auto_accept_requests")
)
)
else ConnRecord.ACCEPT_MANUAL
)

if recipient_keys:
# TODO: register recipient keys for relay
# TODO: check that recipient keys are in wallet
invitation_key = recipient_keys[0] # TODO first key appropriate?
else:
# Create and store new invitation key
async with self.profile.session() as session:
wallet = session.inject(BaseWallet)
invitation_signing_key = await wallet.create_signing_key(
key_type=KeyType.ED25519
)
invitation_key = invitation_signing_key.verkey
recipient_keys = [invitation_key]

if public:
if not self.profile.settings.get("public_invites"):
raise ConnectionManagerError("Public invitations are not enabled")
@@ -143,89 +175,64 @@ async def create_invitation(
"Cannot create public invitation with no public DID"
)

if multi_use:
raise ConnectionManagerError(
"Cannot use public and multi_use at the same time"
)

if metadata:
raise ConnectionManagerError(
"Cannot use public and set metadata at the same time"
)

# FIXME - allow ledger instance to format public DID with prefix?
invitation = ConnectionInvitation(
label=my_label, did=f"did:sov:{public_did.did}", image_url=image_url
)

connection = ConnRecord( # create connection record
invitation_key=public_did.verkey,
invitation_msg_id=invitation._id,
invitation_mode=invitation_mode,
their_role=ConnRecord.Role.REQUESTER.rfc23,
state=ConnRecord.State.INVITATION.rfc23,
accept=accept,
alias=alias,
connection_protocol=CONN_PROTO,
)

async with self.profile.session() as session:
await connection.save(session, reason="Created new invitation")

# Add mapping for multitenant relaying.
# Mediation of public keys is not supported yet
await self._route_manager.route_public_did(self.profile, public_did.verkey)

return None, invitation

invitation_mode = ConnRecord.INVITATION_MODE_ONCE
if multi_use:
invitation_mode = ConnRecord.INVITATION_MODE_MULTI

if recipient_keys:
# TODO: register recipient keys for relay
# TODO: check that recipient keys are in wallet
invitation_key = recipient_keys[0] # TODO first key appropriate?
else:
# Create and store new invitation key
# Create connection record
connection = ConnRecord(
invitation_key=invitation_key, # TODO: determine correct key to use
their_role=ConnRecord.Role.REQUESTER.rfc160,
state=ConnRecord.State.INVITATION.rfc160,
accept=accept,
invitation_mode=invitation_mode,
alias=alias,
connection_protocol=CONN_PROTO,
)
async with self.profile.session() as session:
wallet = session.inject(BaseWallet)
invitation_signing_key = await wallet.create_signing_key(
key_type=KeyType.ED25519
)
invitation_key = invitation_signing_key.verkey
recipient_keys = [invitation_key]
await connection.save(session, reason="Created new invitation")

accept = (
ConnRecord.ACCEPT_AUTO
if (
auto_accept
or (
auto_accept is None
and self.profile.settings.get("debug.auto_accept_requests")
)
await self._route_manager.route_invitation(
self.profile, connection, mediation_record
)
routing_keys, my_endpoint = await self._route_manager.routing_info(
self.profile,
my_endpoint or cast(str, self.profile.settings.get("default_endpoint")),
mediation_record,
)
else ConnRecord.ACCEPT_MANUAL
)

# Create connection record
connection = ConnRecord(
invitation_key=invitation_key, # TODO: determine correct key to use
their_role=ConnRecord.Role.REQUESTER.rfc160,
state=ConnRecord.State.INVITATION.rfc160,
accept=accept,
invitation_mode=invitation_mode,
alias=alias,
connection_protocol=CONN_PROTO,
)
async with self.profile.session() as session:
await connection.save(session, reason="Created new invitation")

await self._route_manager.route_invitation(
self.profile, connection, mediation_record
)
routing_keys, my_endpoint = await self._route_manager.routing_info(
self.profile,
my_endpoint or cast(str, self.profile.settings.get("default_endpoint")),
mediation_record,
)
# Create connection invitation message
# Note: Need to split this into two stages
# to support inbound routing of invites
# Would want to reuse create_did_document and convert the result
invitation = ConnectionInvitation(
label=my_label,
recipient_keys=recipient_keys,
routing_keys=routing_keys,
endpoint=my_endpoint,
image_url=image_url,
)

# Create connection invitation message
# Note: Need to split this into two stages to support inbound routing of invites
# Would want to reuse create_did_document and convert the result
invitation = ConnectionInvitation(
label=my_label,
recipient_keys=recipient_keys,
routing_keys=routing_keys,
endpoint=my_endpoint,
image_url=image_url,
)
async with self.profile.session() as session:
await connection.attach_invitation(session, invitation)

@@ -531,6 +538,9 @@ async def receive_request(
their_role=ConnRecord.Role.REQUESTER.rfc160,
)
if not connection:
if not self.profile.settings.get("requests_through_public_did"):
raise ConnectionManagerError("Unsolicited connection requests to "
"public DID is not enabled")
connection = ConnRecord()
connection.invitation_key = connection_key
connection.my_did = my_info.did