Skip to content
Snippets Groups Projects
Commit f478c022 authored by Steffen Schulze's avatar Steffen Schulze
Browse files

docker compose files added, invitation accepetion, routing completion

parent cb05efc3
No related branches found
No related tags found
1 merge request!10Refactoring
Pipeline #41091 passed with warnings with stages
in 3 minutes and 58 seconds
......@@ -2,7 +2,7 @@ env: DEV # DEV, PROD
logLevel: "info" # info, debug, warning, error
label: My Mediator
port: 9090
url: "http://localhost:9090"
url: "http://localhost:8080"
tokenExpiration: 500000
didcomm:
resolverUrl: "http://localhost:8081"
......
package main
import (
"encoding/base64"
"encoding/json"
"errors"
"io"
"net/http"
"net/url"
"github.com/gin-gonic/gin"
"gitlab.eclipse.org/eclipse/xfsc/common-services/didcomm-connector/didcomm"
"gitlab.eclipse.org/eclipse/xfsc/common-services/didcomm-connector/internal/config"
"gitlab.eclipse.org/eclipse/xfsc/common-services/didcomm-connector/mediator"
"gitlab.eclipse.org/eclipse/xfsc/common-services/didcomm-connector/mediator/database"
"github.com/gin-gonic/gin"
"gitlab.eclipse.org/eclipse/xfsc/common-services/didcomm-connector/protocol"
)
// @Summary Get connections
......@@ -300,6 +303,114 @@ func (app *application) IsBlocked(context *gin.Context) {
context.IndentedJSON(http.StatusOK, ib)
}
// @Summary Accept connection
// @Schemes
// @Description accept connection
// @Tags Connections
// @Accept json
// @Produce json
// @Success 200 "OK"
// @Failure 500 "Internal Server Error"
// @Router /admin/connections/unblock/{did} [post]
func (app *application) AcceptConnection(context *gin.Context) {
logTag := "/admin/connections/accept"
config.Logger.Info(logTag, "Start", true)
type Invitation struct {
Invitation string `json:"invitation"`
database.MediateeBase
}
var inv Invitation
err := context.ShouldBindJSON(&inv)
if err != nil {
_ = app.SendPr(context, protocol.PR_INVALID_REQUEST, err)
context.Status(http.StatusBadRequest)
return
}
uri, err := url.Parse(inv.Invitation)
if err != nil {
config.Logger.Error(logTag, "Error", err)
context.Status(http.StatusBadRequest)
return
}
q, err := url.ParseQuery(uri.RawQuery)
if err != nil {
config.Logger.Error(logTag, "Error", err)
context.Status(http.StatusInternalServerError)
return
}
oob := q.Get("_oob")
b, err := base64.RawURLEncoding.DecodeString(oob)
if err != nil {
config.Logger.Error(logTag, "Error", err)
context.Status(http.StatusBadRequest)
return
}
msg, err := app.mediator.UnpackMessage(string(b))
if err != nil {
config.Logger.Error(logTag, "Error", err)
context.Status(http.StatusBadRequest)
return
}
var bodyJson map[string]interface{}
err = json.Unmarshal([]byte(msg.Body), &bodyJson)
if err != nil {
config.Logger.Error("error unmarshalling", err)
context.Status(http.StatusInternalServerError)
return
}
s, err := mediator.CreateServiceEntry()
if err != nil {
config.Logger.Error("cant create Service", err)
context.Status(http.StatusInternalServerError)
return
}
peerDid, err := mediator.NumAlgo2([]didcomm.Service{s}, app.mediator.SecretsResolver, app.mediator.DidResolver)
if err != nil {
config.Logger.Error("cant create Service", err)
context.Status(http.StatusInternalServerError)
return
}
// routing key must be extracted from mediaton request
peerdid, err := app.mediator.ConnectionManager.Connect(uri.Scheme+"://"+uri.Host+"/message/receive", *msg.From, peerDid, bodyJson["auth"].(string))
if err != nil {
config.Logger.Error("cant create Service", err)
context.Status(http.StatusInternalServerError)
return
}
err = app.mediator.ConnectionManager.StoreConnection(inv.Protocol, *msg.From, inv.Topic, inv.Properties, inv.EventType, []string{peerdid}, inv.Group)
if err != nil {
config.Logger.Error(logTag, "Error", err)
context.Status(http.StatusBadRequest)
return
}
config.Logger.Info(logTag, "End", true)
context.JSON(200, peerDid)
}
func (app *application) SendPr(context *gin.Context, pr didcomm.Message, err error) error {
context.Header("Content-Type", "application/json")
if err != nil {
......
......@@ -30,6 +30,7 @@ func (app *application) NewRouter() *gin.Engine {
connectionsGroup.POST("block/:did", app.BlockConnection)
connectionsGroup.POST("unblock/:did", app.UnblockConnection)
connectionsGroup.GET("isblocked/:did", app.IsBlocked)
connectionsGroup.POST("accept", app.AcceptConnection)
adminGroup.POST("invitation", app.InvitationMessage)
......
env: DEV # DEV, PROD
logLevel: "info" # info, debug, warning, error
label: My Mediator
port: 9090
url: "http://host.docker.internal:9090"
tokenExpiration: 500000
didcomm:
resolverUrl: "http://host.docker.internal:8081"
messageEncrypted: false
# database
db:
inMemory: false
host: "localhost"
port: 9042
user: "cassandra"
password: "cassandra"
keyspace: "dcc"
dbName: "cassandra"
# config for cloudEventProdvider
messaging:
protocol: "nats"
nats:
url: "nats://host.docker.internal:4222"
topic: "/message/receive"
queueGroup: logger # optional
timeoutInSec: 10 # optional
http:
url: "http://localhost:1111" # URL to send cloud event
port: 1111 # port to send cloud event
path: "xyz" # Path to receive cloud event
\ No newline at end of file
version: "3"
networks:
test:
name: test_network
external:
true
services:
didcomconnectorAlpha:
image: node-654e3bca7fbeeed18f81d7c7.ps-xaas.io/common-services/didcomm-connector:refactoring
container_name: dccAlpha
depends_on:
uni-resolverAlpha:
condition: service_healthy
cassandraAlpha:
condition: service_healthy
ports:
- 9092:8080
environment:
- DIDCOMMCONNECTOR_DIDCOMM_RESOLVERURL=http://uni-resolverAlpha:8081
- DIDCOMMCONNECTOR_CLOUDFORWARDING_NATS_URL=nats://natsAlpha:4222
- DIDCOMMCONNECTOR_DATBASE_HOST=cassandraAlpha
- DIDCOMMCONNECTOR_DATBASE_KEYSPACE=tenant_space
- DIDCOMMCONNECTOR_DATBASE_DBNAME=dcc
- DIDCOMMCONNECTOR_DATBASE_PORT=9042
- DIDCOMMCONNECTOR_CLOUDFORWARDING_NATS_TOPIC=connector
- DIDCOMMCONNECTOR_URL=http://localhost:9092
networks:
- test
natsAlpha:
image: nats:latest
container_name: natsAlpha
ports:
- "4223:4222"
networks:
- test
uni-resolverAlpha:
image: uport/uni-resolver-driver-did-uport:4.3.0
container_name: uni-resolverAlpha
ports:
- "8082:8081"
healthcheck:
test: curl --fail http://uni-resolverAlpha:8081/health || exit 1
interval: 10s
timeout: 5s
retries: 5
networks:
- test
cassandraAlpha:
image: cassandra:4.1
container_name: cassandra_dbAlpha
ports:
- 7001:7000
- 9043:9042
networks:
- test
healthcheck:
test: cqlsh
interval: 30s
timeout: 120s
retries: 5
\ No newline at end of file
version: "3"
networks:
test:
name: test_network
external:
true
services:
didcomconnectorBeta:
image: node-654e3bca7fbeeed18f81d7c7.ps-xaas.io/common-services/didcomm-connector:refactoring
container_name: dccBeta
depends_on:
uni-resolverBeta:
condition: service_healthy
cassandraBeta:
condition: service_healthy
ports:
- 9093:8080
environment:
- DIDCOMMCONNECTOR_DIDCOMM_RESOLVERURL=http://uni-resolverBeta:8081
- DIDCOMMCONNECTOR_CLOUDFORWARDING_NATS_URL=nats://natsBeta:4222
- DIDCOMMCONNECTOR_DATBASE_HOST=cassandraBeta
- DIDCOMMCONNECTOR_DATBASE_KEYSPACE=tenant_space
- DIDCOMMCONNECTOR_DATBASE_DBNAME=dcc
- DIDCOMMCONNECTOR_DATBASE_PORT=9042
- DIDCOMMCONNECTOR_CLOUDFORWARDING_NATS_TOPIC=connector
- DIDCOMMCONNECTOR_URL=http://localhost:9092
networks:
- test
natsBeta:
image: nats:latest
container_name: natsBeta
ports:
- "4224:4222"
networks:
- test
uni-resolverBeta:
image: uport/uni-resolver-driver-did-uport:4.3.0
container_name: uni-resolverBeta
ports:
- "8083:8081"
healthcheck:
test: curl --fail http://uni-resolverBeta:8081/health || exit 1
interval: 10s
timeout: 5s
retries: 5
networks:
- test
cassandraBeta:
image: cassandra:4.1
container_name: cassandra_dbBeta
ports:
- 7001:7000
- 9044:9042
networks:
- test
healthcheck:
test: cqlsh
interval: 30s
timeout: 120s
retries: 5
\ No newline at end of file
version: "3"
networks:
test:
name: test_network
driver: bridge
services:
#didcomconnector:
# build:
......@@ -17,12 +22,21 @@ services:
container_name: nats
ports:
- "4222:4222"
networks:
- test
uni-resolver-driver-did-uport:
uni-resolver:
image: uport/uni-resolver-driver-did-uport:4.3.0
container_name: uni-resolver
ports:
- "8081:8081"
healthcheck:
test: curl --fail http://uni-resolver:8081/health || exit 1
interval: 10s
timeout: 5s
retries: 5
networks:
- test
cassandra:
image: cassandra:4.1
......@@ -30,4 +44,10 @@ services:
ports:
- 7000:7000
- 9042:9042
restart: always
networks:
- test
healthcheck:
test: cqlsh
interval: 30s
timeout: 120s
retries: 5
\ No newline at end of file
package connectionmanager
import (
"bytes"
"encoding/json"
"errors"
"net/http"
"time"
"github.com/google/uuid"
"gitlab.eclipse.org/eclipse/xfsc/common-services/didcomm-connector/internal/config"
"gitlab.eclipse.org/eclipse/xfsc/common-services/didcomm-connector/mediator/database"
)
......@@ -51,3 +56,72 @@ func (c *ConnectionManager) StoreConnection(protocol string, remoteDid string, t
}
return nil
}
func (c *ConnectionManager) Connect(host string, mediatorPeerDid string, peerdid string, bearer string) (string, error) {
var mediatonRequest = make(map[string]interface{})
mediatonRequest["id"] = uuid.NewString()
mediatonRequest["type"] = "https://didcomm.org/coordinate-mediation/3.0/mediate-request"
mediatonRequest["body"] = make(map[string]interface{})
mediatonRequest["from"] = peerdid
mediatonRequest["to"] = []string{mediatorPeerDid}
mediatonRequest["created_time"] = time.Now().Unix()
mediatonRequest["expired_time"] = time.Now().Add(time.Hour).Unix()
mediatonRequest["attachments"] = []string{}
res, err := GetHttpResult(mediatonRequest, host, bearer)
if err != nil {
return "", err
}
res, ok := res["body"].(map[string]interface{})
if ok {
res, ok := res["routing_did"].([]interface{})
if ok {
if len(res) > 0 {
return res[0].(string), nil
}
}
}
return "", errors.New("Request failed.")
}
func GetHttpResult(input interface{}, url string, bearer string) (map[string]interface{}, error) {
body, err := json.Marshal(input)
if err != nil {
return nil, err
}
r, err := http.NewRequest("POST", url, bytes.NewBuffer(body))
r.Header.Add("Content-Type", "application/json")
if bearer != "" {
r.Header.Add("Authorization", "Bearer "+bearer)
}
if err != nil {
return nil, err
}
client := &http.Client{}
res, err := client.Do(r)
if err != nil {
return nil, err
}
defer res.Body.Close()
var post map[string]interface{}
derr := json.NewDecoder(res.Body).Decode(&post)
if derr != nil {
return nil, err
}
return post, nil
}
......@@ -88,12 +88,28 @@ func (m *Mediator) createDidIfNeeded() {
}
func (m *Mediator) CreateMediatorService() (service []didcomm.Service, err error) {
queryUrl, err := url.JoinPath(config.CurrentConfiguration.Url, "/message/receive")
s, err := CreateServiceEntry()
if err != nil {
config.Logger.Error("can not join url path", err)
return nil, err
}
response := []didcomm.Service{
s,
}
return response, nil
}
func CreateServiceEntry() (didcomm.Service, error) {
queryUrl, err := url.JoinPath(config.CurrentConfiguration.Url, "/message/receive")
if err != nil {
return didcomm.Service{}, err
}
serviceKind := didcomm.ServiceKindDidCommMessaging{
Value: didcomm.DidCommMessagingService{
Uri: queryUrl,
......@@ -102,12 +118,12 @@ func (m *Mediator) CreateMediatorService() (service []didcomm.Service, err error
},
}
service = []didcomm.Service{
{
// Service ID
Id: "#service-1",
ServiceEndpoint: serviceKind,
},
service := didcomm.Service{
// Service ID
Id: "#service-1",
ServiceEndpoint: serviceKind,
}
return service, nil
}
......@@ -6,6 +6,7 @@ import (
"encoding/json"
"errors"
"net/http"
"strings"
"time"
"gitlab.eclipse.org/eclipse/xfsc/common-services/didcomm-connector/didcomm"
......@@ -92,15 +93,45 @@ func (rt *Routing) handleForward(message didcomm.Message, inbound bool) (pr Prob
*/
config.Logger.Info("Recipient is registered")
if !inbound {
err = rt.mediator.Database.AddMessage(body.Next, attachment)
//In the case of a did here must be later on a decision if a service endpoint should be used or
//to use the message box. for now is it the messagebox
didDoc, err := rt.mediator.DidResolver.ResolveDid(body.Next)
if err != nil {
config.Logger.Error("could not add message to inbox", "err", err)
return PR_COULD_NOT_FORWARD_MESSAGE, err
}
/*
The peer did for a device has no endpoint where you try to send to
*/
if len(didDoc.Service) == 0 {
err = rt.mediator.Database.AddMessage(body.Next, attachment)
if err != nil {
config.Logger.Error("could not add message to inbox", "err", err)
return PR_COULD_NOT_FORWARD_MESSAGE, err
}
} else {
/*
if service endpoint exists which is didcomm compatible, forward message as it is.
*/
for _, x := range didDoc.Service {
val, ok := x.ServiceEndpoint.(didcomm.ServiceKindDidCommMessaging)
if ok {
return rt.ForwardMessage(message, val.Value.Uri)
}
}
return PR_COULD_NOT_FORWARD_MESSAGE, errors.New("No compatible endpoint found in the list")
}
} else {
//In the case of a did here must be later on a decision if a service endpoint should be used or
//to use the message box. for now is it the messagebox
/*
Here should be later an seperation between cloud and attachment forward. E.g. by using different service endpoints within the routing did
*/
messageB64 := attachment.Data.(didcomm.AttachmentDataBase64).Value.Base64
messageDecoded, err := base64.StdEncoding.DecodeString(messageB64)
if err != nil {
......@@ -134,7 +165,27 @@ func (rt *Routing) handleForward(message didcomm.Message, inbound bool) (pr Prob
return didcomm.Message{}, err
}
func (rt *Routing) ForwardMessage(message didcomm.Attachment, recipientDid string, endpoint string) (pr ProblemReport, err error) {
func (rt *Routing) ForwardMessage(message didcomm.Message, endpoint string) (pr ProblemReport, err error) {
packMsg, err := rt.mediator.PackPlainMessage(message)
if err != nil {
config.Logger.Error("Problem Report", "err", err)
return didcomm.Message{}, err
}
r := strings.NewReader(packMsg)
resp, err := http.Post(endpoint, "application/didcomm-plain+json", r)
if err != nil {
return PR_COULD_NOT_FORWARD_MESSAGE, err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return PR_NEXT_DENIED_MESSAGE, errors.New("forwarded message was not accepted by the next recipient")
}
return didcomm.Message{}, nil
}
func (rt *Routing) ForwardAttachmentMessage(message didcomm.Attachment, recipientDid string, endpoint string) (pr ProblemReport, err error) {
messageDecoded := message.Data.(didcomm.AttachmentDataBase64).Value.Base64
body, err := base64.StdEncoding.DecodeString(messageDecoded)
if err != nil {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment