mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-21 11:46:37 +00:00
feat: enforce nats authentication (#123)
This commit is contained in:
@@ -287,6 +287,7 @@ var viperblockStartCmd = &cobra.Command{
|
||||
|
||||
service, err := service.New("viperblock", &viperblockd.Config{
|
||||
NatsHost: nodeConfig.NATS.Host,
|
||||
NatsToken: nodeConfig.NATS.ACL.Token,
|
||||
PluginPath: pluginPath,
|
||||
S3Host: nodeConfig.Predastore.Host,
|
||||
Bucket: nodeConfig.Predastore.Bucket,
|
||||
|
||||
@@ -16,7 +16,7 @@ cluster {
|
||||
|
||||
routes = [
|
||||
{{- range .ClusterRoutes }}
|
||||
"nats://{{ . }}",
|
||||
"nats-route://{{$.NatsToken}}@{{ . }}",
|
||||
{{- end }}
|
||||
]
|
||||
}
|
||||
@@ -26,7 +26,7 @@ server_name: spinifex-nats-{{.Node}}
|
||||
|
||||
# Authorization
|
||||
authorization {
|
||||
# token: "{{.NatsToken}}"
|
||||
token: "{{.NatsToken}}"
|
||||
}
|
||||
|
||||
# JetStream for persistent messaging and KV store
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
package nats
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/nats-io/nats-server/v2/server"
|
||||
"github.com/nats-io/nats.go"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// templatePath returns the absolute path to the canonical nats.conf template
|
||||
// used by admin init. Reading at test time (rather than embedding a copy)
|
||||
// ensures the test always validates the real template.
|
||||
func templatePath(t *testing.T) string {
|
||||
t.Helper()
|
||||
_, thisFile, _, ok := runtime.Caller(0)
|
||||
require.True(t, ok)
|
||||
return filepath.Join(filepath.Dir(thisFile), "..", "..", "..", "cmd", "spinifex", "cmd", "templates", "nats.conf")
|
||||
}
|
||||
|
||||
// TestRenderedConfig_EnforcesAuth renders the production nats.conf template with
|
||||
// a known token, starts an embedded NATS server from the resulting config, and
|
||||
// verifies that unauthenticated and wrong-token connections are rejected while
|
||||
// correct-token connections succeed.
|
||||
func TestRenderedConfig_EnforcesAuth(t *testing.T) {
|
||||
token := "nats_test-secret-token-1234"
|
||||
tmpDir := t.TempDir()
|
||||
confPath := filepath.Join(tmpDir, "nats.conf")
|
||||
|
||||
// Read and render the production template.
|
||||
raw, err := os.ReadFile(templatePath(t))
|
||||
require.NoError(t, err)
|
||||
|
||||
tmpl, err := template.New("nats.conf").Parse(string(raw))
|
||||
require.NoError(t, err)
|
||||
|
||||
f, err := os.Create(confPath)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = tmpl.Execute(f, map[string]any{
|
||||
"BindIP": "127.0.0.1",
|
||||
"Node": "test-node",
|
||||
"NatsToken": token,
|
||||
"DataDir": tmpDir,
|
||||
"LogDir": tmpDir,
|
||||
})
|
||||
f.Close()
|
||||
require.NoError(t, err)
|
||||
|
||||
// Start NATS server from the rendered config.
|
||||
opts, err := server.ProcessConfigFile(confPath)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Override for test isolation: random port, no monitoring.
|
||||
opts.Port = -1
|
||||
opts.LogFile = ""
|
||||
opts.HTTPHost = ""
|
||||
opts.HTTPPort = 0
|
||||
|
||||
ns, err := server.NewServer(opts)
|
||||
require.NoError(t, err)
|
||||
go ns.Start()
|
||||
require.True(t, ns.ReadyForConnections(5*time.Second))
|
||||
t.Cleanup(func() { ns.Shutdown() })
|
||||
|
||||
t.Run("no token rejected", func(t *testing.T) {
|
||||
_, err := nats.Connect(ns.ClientURL(), nats.MaxReconnects(0))
|
||||
assert.Error(t, err, "unauthenticated connection should be rejected")
|
||||
})
|
||||
|
||||
t.Run("wrong token rejected", func(t *testing.T) {
|
||||
_, err := nats.Connect(ns.ClientURL(), nats.Token("wrong-token"), nats.MaxReconnects(0))
|
||||
assert.Error(t, err, "wrong token should be rejected")
|
||||
})
|
||||
|
||||
t.Run("correct token accepted", func(t *testing.T) {
|
||||
nc, err := nats.Connect(ns.ClientURL(), nats.Token(token), nats.MaxReconnects(0))
|
||||
require.NoError(t, err, "correct token should be accepted")
|
||||
defer nc.Close()
|
||||
assert.True(t, nc.IsConnected())
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user