Files
upstream-corteza/server/federation/service/node_handshaker.go
upstream-mirror 7e385fc126
Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
snapshot of https://github.com/cortezaproject/corteza.git (2024.9.x, 2026-09-18; blobs > 131072B omitted)
2026-09-18 01:22:23 +05:00

98 lines
2.5 KiB
Go

package service
import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
"strconv"
"github.com/cortezaproject/corteza/server/federation/types"
)
type (
// HttpHandshake performs HTTP handshake with remote node
httpNodeHandshake struct {
httpClient httpNodeHandshaker
}
httpNodeHandshaker interface {
Do(*http.Request) (*http.Response, error)
}
)
func HttpHandshake(client httpNodeHandshaker) *httpNodeHandshake {
return &httpNodeHandshake{httpClient: client}
}
// Init calls handshake init on a remote node via HTTP
//
// Called from node.Pair() and sends POST request to remote Corteza
// There, it is handled with node.HandshakeInit
//
// Fn is not part of the node struct to allow injection
func (h httpNodeHandshake) Init(ctx context.Context, n *types.Node, authToken string) error {
var (
endpoint = fmt.Sprintf("%s/nodes/%d/handshake", n.BaseURL, n.SharedNodeID)
payload = map[string]string{
// Share pairing token, so we can authenticate ourselves
"pairToken": n.PairToken,
// Share auth token for the federation service user for this node
"authToken": authToken,
"sharedNodeID": strconv.FormatUint(n.SharedNodeID, 10),
}
)
return h.send(ctx, endpoint, payload)
}
// Confirm calls handshake init on a remote node via HTTP
//
// Called from node.Confirm and sends POST request to remote Corteza
// There, it's handled with node.HandshakeComplete
func (h httpNodeHandshake) Complete(ctx context.Context, n *types.Node, authToken string) error {
var (
endpoint = fmt.Sprintf("%s/nodes/%d/handshake-complete", n.BaseURL, n.SharedNodeID)
payload = map[string]string{
// Share auth token for the federation service user for this node
"authToken": authToken,
}
)
// use n.AuthToken in context
ctx = context.WithValue(ctx, "authToken", n.AuthToken)
return h.send(ctx, endpoint, payload)
}
func (h httpNodeHandshake) send(ctx context.Context, endpoint string, payload map[string]string) error {
body := bytes.NewBuffer(nil)
if err := json.NewEncoder(body).Encode(payload); err != nil {
return err
}
req, err := http.NewRequest(http.MethodPost, endpoint, body)
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
if authToken := ctx.Value("authToken"); authToken != nil {
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", authToken))
}
rsp, err := h.httpClient.Do(req.WithContext(ctx))
if err != nil {
return err
}
if rsp.StatusCode != http.StatusOK {
return fmt.Errorf("pairing failed, remote host retuned non-200 response")
}
return nil
}