From 852275945c9a91c9426c68310d3ee7f3e5e2d599 Mon Sep 17 00:00:00 2001 From: ryyst Date: Thu, 2 Oct 2025 22:27:15 +0300 Subject: [PATCH] fix: update bootstrap service and routes for cluster authentication MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Updated bootstrap service to use authenticated HTTP client with cluster auth headers - Made GET /members/ endpoint unprotected for monitoring/inspection purposes - All other cluster communication endpoints remain protected by cluster auth middleware This ensures proper cluster formation while maintaining security for inter-node communication. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- cluster/bootstrap.go | 15 ++++++++++++--- integration_test.sh | 22 ++++++++++++++++------ server/routes.go | 7 ++++--- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/cluster/bootstrap.go b/cluster/bootstrap.go index 18c5e09..314ec88 100644 --- a/cluster/bootstrap.go +++ b/cluster/bootstrap.go @@ -82,10 +82,19 @@ func (s *BootstrapService) attemptJoin(seedAddr string) bool { return false } - client := &http.Client{Timeout: 10 * time.Second} - url := fmt.Sprintf("http://%s/members/join", seedAddr) + client := NewAuthenticatedHTTPClient(s.config, 10*time.Second) + protocol := GetProtocol(s.config) + url := fmt.Sprintf("%s://%s/members/join", protocol, seedAddr) - resp, err := client.Post(url, "application/json", bytes.NewBuffer(jsonData)) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData)) + if err != nil { + s.logger.WithError(err).Error("Failed to create join request") + return false + } + req.Header.Set("Content-Type", "application/json") + AddClusterAuthHeaders(req, s.config) + + resp, err := client.Do(req) if err != nil { s.logger.WithFields(logrus.Fields{ "seed": seedAddr, diff --git a/integration_test.sh b/integration_test.sh index e209cf3..af6d3b6 100755 --- a/integration_test.sh +++ b/integration_test.sh @@ -124,7 +124,10 @@ EOF # Test 3: Cluster formation test_cluster_formation() { test_start "2-node cluster formation and Merkle Tree replication" - + + # Shared cluster secret for authentication (Issue #13) + local CLUSTER_SECRET="test-cluster-secret-12345678901234567890" + # Node 1 config cat > cluster1.yaml < cluster2.yaml </dev/null || true mkdir -p conflict1_data conflict2_data - + cd "$SCRIPT_DIR" if go run test_conflict.go "$TEST_DIR/conflict1_data" "$TEST_DIR/conflict2_data"; then cd "$TEST_DIR" - + + # Shared cluster secret for authentication (Issue #13) + local CLUSTER_SECRET="conflict-cluster-secret-1234567890123" + # Create configs cat > conflict1.yaml < conflict2.yaml <