From d0e9cb57b25591166a20c81b5f2a4a8dd628a39c Mon Sep 17 00:00:00 2001 From: Ian Costanzo Date: Mon, 31 Jan 2022 14:38:48 -0800 Subject: [PATCH] Add support for DIDExchange connections Signed-off-by: Ian Costanzo --- .../api/endpoints/routes/connections.py | 72 +++++++++++++++---- 1 file changed, 60 insertions(+), 12 deletions(-) diff --git a/services/traction/api/endpoints/routes/connections.py b/services/traction/api/endpoints/routes/connections.py index 4c6c5cb9e..e554b3255 100644 --- a/services/traction/api/endpoints/routes/connections.py +++ b/services/traction/api/endpoints/routes/connections.py @@ -1,7 +1,7 @@ from enum import Enum from typing import Optional -from fastapi import APIRouter +from fastapi import APIRouter, HTTPException from pydantic import BaseModel from api import acapy_utils as au @@ -90,14 +90,48 @@ async def get_connections( return connections["results"] +async def get_connection_with_alias(alias: str): + params = { + "alias": alias, + } + connections = await au.acapy_GET("connections", params=params) + if 0 == len(connections["results"]): + return None + if 1 < len(connections["results"]): + raise HTTPException( + status_code=500, + detail=f"Error multiple connections found with alias {alias}", + ) + return connections["results"][0] + + @router.post("/create-invitation", response_model=Invitation) async def create_invitation( alias: str | None = None, + invitation_type: ConnectionProtocolType = ConnectionProtocolType.DIDExchange, ): - params = {"alias": alias} - invitation = await au.acapy_POST( - "connections/create-invitation", data={}, params=params - ) + existing_connection = await get_connection_with_alias(alias) + if existing_connection: + raise HTTPException( + status_code=500, detail=f"Error alias {alias} already in use" + ) + if invitation_type == ConnectionProtocolType.DIDExchange: + data = { + "alias": alias, + "handshake_protocols": [ + "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/didexchange/1.0", + ], + } + invitation = await au.acapy_POST( + "out-of-band/create-invitation", data=data, params=None + ) + connection = await get_connection_with_alias(alias) + invitation["connection_id"] = connection["connection_id"] + else: + params = {"alias": alias} + invitation = await au.acapy_POST( + "connections/create-invitation", data={}, params=params + ) return invitation @@ -106,10 +140,21 @@ async def receive_invitation( payload: dict, alias: str | None = None, ): - params = {"alias": alias} - connection = await au.acapy_POST( - "connections/receive-invitation", data=payload, params=params - ) + existing_connection = await get_connection_with_alias(alias) + if existing_connection: + raise HTTPException( + status_code=500, detail=f"Error alias {alias} already in use" + ) + if "/out-of-band/" in payload.get("@type", ""): + params = {"alias": alias} + connection = await au.acapy_POST( + "out-of-band/receive-invitation", data=payload, params=params + ) + else: + params = {"alias": alias} + connection = await au.acapy_POST( + "connections/receive-invitation", data=payload, params=params + ) return connection @@ -120,9 +165,12 @@ async def send_message( alias: str | None = None, ): if not connection_id: - lookup_params = {"alias": alias} - connections = await au.acapy_GET("connections", params=lookup_params) - connection_id = connections["results"][0]["connection_id"] + existing_connection = await get_connection_with_alias(alias) + if not existing_connection: + raise HTTPException( + status_code=404, detail=f"Error alias {alias} does not exist" + ) + connection_id = existing_connection["connection_id"] message = {"content": payload.content} response = await au.acapy_POST( f"connections/{connection_id}/send-message", data=message