Files
felhom.eu/hub/internal/offsitekeys/service_test.go
T

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)
}
}