Files
br ca6cdcca63 software steht so weit.
jetzt build + docker build und testen
2026-10-02 13:25:34 +02:00

87 lines
2.9 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package stream
import (
"context"
"crypto/ed25519"
"crypto/rand"
"encoding/json"
"errors"
"testing"
)
func TestSignAndVerifyEvent(t *testing.T) {
pub, priv, _ := ed25519.GenerateKey(rand.Reader)
ev := Event{ID: "evt_1", Timestamp: 42, Type: EventNodeCommand, NodeID: "n1", Payload: json.RawMessage(`{"command":"resync"}`)}
signed := SignEvent(ev, priv)
if signed.Signature == "" {
t.Fatal("keine Signatur")
}
if err := VerifyEvent(signed, pub); err != nil {
t.Errorf("Verify: %v", err)
}
otherPub, _, _ := ed25519.GenerateKey(rand.Reader)
for name, tc := range map[string]struct {
ev Event
pub ed25519.PublicKey
err error
}{
"unsigniert": {ev, pub, ErrUnsigned},
"fremder Schlüssel": {signed, otherPub, ErrBadSignature},
"Payload geändert": {func() Event { e := signed; e.Payload = json.RawMessage(`{"command":"rotate_key"}`); return e }(), pub, ErrBadSignature},
"Knoten geändert": {func() Event { e := signed; e.NodeID = "n2"; return e }(), pub, ErrBadSignature},
"Signatur Müll": {func() Event { e := signed; e.Signature = "!!!"; return e }(), pub, ErrBadSignature},
} {
if err := VerifyEvent(tc.ev, tc.pub); !errors.Is(err, tc.err) {
t.Errorf("%s: erwartet %v, bekommen %v", name, tc.err, err)
}
}
}
// Mit SigningKey signiert der Hub jedes Event – nachdem er ID, Zeitstempel
// und Knoten-ID ergänzt hat, damit auch diese geschützt sind.
func TestHub_SignsEvents(t *testing.T) {
pub, priv, _ := ed25519.GenerateKey(rand.Reader)
h := &Hub{SigningKey: priv}
srv, _ := hubServer(t, h)
resp := openStream(t, context.Background(), srv, "n1")
if err := h.Send("n1", Event{Type: EventNodeCommand, Payload: json.RawMessage(`{"command":"resync"}`)}); err != nil {
t.Fatal(err)
}
ev, err := NewDecoder(resp.Body).Next()
if err != nil {
t.Fatal(err)
}
if ev.NodeID != "n1" || ev.ID == "" {
t.Errorf("Event: %+v", ev)
}
if err := VerifyEvent(ev, pub); err != nil {
t.Errorf("Signatur nach Übertragung ungültig: %v", err)
}
}
func TestNodeCommandPayload(t *testing.T) {
ev, err := NewEvent(EventNodeCommand, NodeCommand{Command: CmdRotateKey, Reason: "Routine"})
if err != nil {
t.Fatal(err)
}
cmd, err := ParseNodeCommand(ev)
if err != nil || cmd.Command != CmdRotateKey || cmd.Reason != "Routine" {
t.Errorf("ParseNodeCommand: %+v %v", cmd, err)
}
if _, err := ParseNodeCommand(Event{Type: EventLeaseRenew}); err == nil {
t.Error("falscher Event-Typ akzeptiert")
}
if _, err := ParseNodeCommand(Event{Type: EventNodeCommand, Payload: json.RawMessage(`{}`)}); err == nil {
t.Error("Befehl ohne Namen akzeptiert")
}
}
func TestNodeCommandServerURLs(t *testing.T) {
ev, _ := NewEvent(EventNodeCommand, NodeCommand{Command: CmdConfig, ServerURLs: []string{"https://a:8443", "https://b:8443"}})
cmd, err := ParseNodeCommand(ev)
if err != nil || cmd.Command != CmdConfig || len(cmd.ServerURLs) != 2 || cmd.ServerURLs[1] != "https://b:8443" {
t.Errorf("config: %+v %v", cmd, err)
}
}