207ad19746
gates / gates (push) Successful in 41s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
130 lines
4.4 KiB
Go
130 lines
4.4 KiB
Go
package offsitekeys
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"gitea.dooplex.hu/admin/felhom-hub/internal/store"
|
|
)
|
|
|
|
func svcFixture(t *testing.T) (*Service, *fakeFS, *[]string) {
|
|
t.Helper()
|
|
st, err := store.New(filepath.Join(t.TempDir(), "hub.db"), log.New(os.Stderr, "", 0))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Cleanup(func() { st.Close() })
|
|
cfg := `{"offsite":{"enabled":true,"type":"shared","host":"u1-sub4.example","user":"u1-sub4","port":23,"repo_path":"/home/felhom-repo","host_fingerprint":"SHA256:host"}}`
|
|
if err := st.SaveCustomerConfig(&store.CustomerConfig{CustomerID: "c1", APIKey: "k", RetrievalPassword: "p", ConfigJSON: cfg}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := st.SaveOneTimeSecret("c1", "SubPw1%"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
fs := newFS()
|
|
var events []string
|
|
s := &Service{Store: st, Reg: &Registrar{Dialer: fakeDialer{fs}},
|
|
Emit: func(_, typ, _, _, _, _ string) { events = append(events, typ) }}
|
|
return s, fs, &events
|
|
}
|
|
|
|
// Register → confirm → the window is refused while weekly windows are off; an operator one-shot opens
|
|
// it (deleting line FIRST); the box's close removes it; a drop beyond the bound alarms.
|
|
func TestWindow_GrantOpenCloseAndDropAlarm(t *testing.T) {
|
|
s, fs, events := svcFixture(t)
|
|
ctx := context.Background()
|
|
pub, fp := newKey(t)
|
|
if _, err := s.RegisterKey(ctx, "c1", pub); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := s.ConfirmKey(ctx, "c1", fp); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if g, err := s.OpenWindowFor(ctx, "c1", 20); err != nil || g.Granted {
|
|
t.Fatalf("windows off: granted=%v err=%v — must refuse", g.Granted, err)
|
|
}
|
|
if err := s.Store.GrantOffsiteWindowOnce("c1"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
g, err := s.OpenWindowFor(ctx, "c1", 20)
|
|
if err != nil || !g.Granted || g.MaxRemove != 8 {
|
|
t.Fatalf("one-shot: %+v %v", g, err)
|
|
}
|
|
if lines := ParseLines(fs.files[".ssh/authorized_keys"], "/home/felhom-repo"); !lines[0].Window || lines[0].Fingerprint != fp {
|
|
t.Fatalf("window line not first: %+v", lines)
|
|
}
|
|
if !s.Store.OffsiteWindowOpen("c1") {
|
|
t.Fatal("the ledger does not show the window open — the daily check would alarm on it")
|
|
}
|
|
if g2, _ := s.OpenWindowFor(ctx, "c1", 20); g2.Granted {
|
|
t.Fatal("the one-shot grant was not consumed")
|
|
}
|
|
// The box reports a fall of 12 (allowed 8) → offsite_window_drop.
|
|
if err := s.CloseWindowFor(ctx, "c1", WindowResult{WindowID: g.WindowID, CountAfter: 8, Outcome: "pruned"}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if a := audit(fs.files[".ssh/authorized_keys"], "/home/felhom-repo", false); len(a.Findings) != 0 {
|
|
t.Fatalf("window line left behind: %+v", a)
|
|
}
|
|
found := false
|
|
for _, e := range *events {
|
|
if e == EventWindowDrop {
|
|
found = true
|
|
}
|
|
}
|
|
if !found {
|
|
t.Fatalf("no %s event for a fall beyond the bound: %v", EventWindowDrop, *events)
|
|
}
|
|
}
|
|
|
|
// A window for a box that never confirmed its key is refused (nothing to scope the window to).
|
|
func TestWindow_NoConfirmedKeyRefused(t *testing.T) {
|
|
s, _, _ := svcFixture(t)
|
|
_ = s.Store.GrantOffsiteWindowOnce("c1")
|
|
pub, _ := newKey(t)
|
|
if _, err := s.RegisterKey(context.Background(), "c1", pub); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if g, _ := s.OpenWindowFor(context.Background(), "c1", 10); g.Granted {
|
|
t.Fatal("granted without a confirmed key")
|
|
}
|
|
}
|
|
|
|
// A window the box never closes is closed by the hub at its bound: the deleting line goes, the ledger
|
|
// row closes with reason "timeout", and the operator hears offsite_window_failed.
|
|
func TestWindow_LeftOpenIsClosedByTheSweep(t *testing.T) {
|
|
s, fs, events := svcFixture(t)
|
|
ctx := context.Background()
|
|
pub, fp := newKey(t)
|
|
if _, err := s.RegisterKey(ctx, "c1", pub); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := s.ConfirmKey(ctx, "c1", fp); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
_ = s.Store.GrantOffsiteWindowOnce("c1")
|
|
g, err := s.OpenWindowFor(ctx, "c1", 10)
|
|
if err != nil || !g.Granted {
|
|
t.Fatalf("%+v %v", g, err)
|
|
}
|
|
// Make it overdue: the box crashed and never reported.
|
|
if err := s.Store.ForceOffsiteWindowDueForTest(g.WindowID); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
s.SweepExpiredWindows(ctx)
|
|
if a := audit(fs.files[".ssh/authorized_keys"], "/home/felhom-repo", false); len(a.Findings) != 0 {
|
|
t.Fatalf("the sweep left the deleting line: %+v", a)
|
|
}
|
|
w, _ := s.Store.GetOffsiteWindow(g.WindowID)
|
|
if w == nil || w.ClosedAt.IsZero() || w.CloseReason != "timeout" {
|
|
t.Fatalf("ledger = %+v", w)
|
|
}
|
|
last := (*events)[len(*events)-1]
|
|
if last != EventWindowFailed {
|
|
t.Fatalf("last event = %s", last)
|
|
}
|
|
}
|