package cli import ( "bytes" "os" "path/filepath" "testing" "git.dcglab.co.uk/steve/emcli/internal/crypto" "git.dcglab.co.uk/steve/emcli/internal/store" ) func dbBytes(t *testing.T, path string) []byte { t.Helper() b, err := os.ReadFile(path) if err != nil { t.Fatalf("read db: %v", err) } return b } // A forced agent holding ONLY EMCLI_KEY must not be able to run any admin // command, and the DB must be unchanged after it tries. func TestAgentKeyCannotRunAdminCommands(t *testing.T) { db := filepath.Join(t.TempDir(), "emcli.db") t.Setenv("EMCLI_ADMIN_KEY", b64Key()) t.Setenv("EMCLI_KEY", b64AgentKey()) t.Setenv("EMCLI_DB", db) st, _ := store.Open(db) ak, _ := crypto.AdminKeyFromEnv() gk, _ := crypto.AgentKeyFromEnv() if err := st.InitKeys(ak, gk); err != nil { t.Fatalf("InitKeys: %v", err) } st.Close() // Simulate the agent's environment: admin key absent. t.Setenv("EMCLI_ADMIN_KEY", "") before := dbBytes(t, db) adminAttempts := [][]string{ {"account", "list"}, {"config", "set", "audit_retention_days", "30"}, {"audit"}, } for _, args := range adminAttempts { code, out, errOut := run(t, args...) if code == 0 { t.Fatalf("admin command %v must be refused with only EMCLI_KEY (out=%q err=%q)", args, out, errOut) } } if !bytes.Equal(before, dbBytes(t, db)) { t.Fatal("DB changed despite all admin commands being refused") } }