mesh/merge-gate head eb4280637906 merged into trunk 53e51864969f — pass: builds baserow, gitea, grafana, home-assistant, icecast, influxdb, letta, mailu, n…
mesh/repo-check head eb4280637906 merged into trunk 53e51864969f — pass: THE CHANGE ALTERS ITS OWN CHECK (merge-check.sh): main's version judged it; the ch…
mesh/delivery delivered
mesh/delivery-group group fix/342-a-secret-is-never-a-setting delivered: every member is delivered
grafana's client logged in with a token setting ahead of the vault's admin password, and its runtime config let a layer set token. The token setting is now ignored and said, token is protected, and the vault's password comes first. checks/secrets/known could gain a line hiding a newly unprotected key. merge-check.sh now judges it against the trunk's copy at the merge base, and refuses an added line.
126 lines
4.4 KiB
Go
126 lines
4.4 KiB
Go
package main
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
func manifest(t *testing.T, root, module, resources string) {
|
|
t.Helper()
|
|
dir := filepath.Join(root, "modules", module)
|
|
if err := os.MkdirAll(dir, 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
body := `{"module":"` + module + `","resources":[` + resources + `]}`
|
|
if err := os.WriteFile(filepath.Join(dir, "module.json"), []byte(body), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestASecretASettingCouldReplaceIsRefused(t *testing.T) {
|
|
root := t.TempDir()
|
|
// Refused: the key holds the vault's secret and nothing keeps a layer off it.
|
|
manifest(t, root, "a", `{"id":"cfg","type":"file","merge":"json","content":"{\"password\": \"${secret:admin}\"}"}`)
|
|
// Refused: nested below a key the file takes.
|
|
manifest(t, root, "b", `{"id":"cfg","type":"file","merge":"json","takes-settings":["server"],`+
|
|
`"content":"{\"server\": {\"secret_key\": \"${secret:s}\", \"port\": 1}}"}`)
|
|
// Kept: protected.
|
|
manifest(t, root, "c", `{"id":"cfg","type":"file","merge":"json","protected":["password"],`+
|
|
`"content":"{\"password\": \"${secret:admin}\", \"user\": \"admin\"}"}`)
|
|
// Kept: the file names its keys, and not this one.
|
|
manifest(t, root, "d", `{"id":"cfg","type":"file","merge":"json","takes-settings":["ui"],`+
|
|
`"content":"{\"token\": \"${secret:t}\", \"ui\": {}}"}`)
|
|
// Kept: a file that does not merge takes no setting.
|
|
manifest(t, root, "e", `{"id":"cfg","type":"file","content":"{\"token\": \"${secret:t}\"}"}`)
|
|
// Refused: protecting another key does not protect this one; a list element counts too.
|
|
manifest(t, root, "f", `{"id":"cfg","type":"file","merge":"json","protected":["user"],`+
|
|
`"content":"{\"users\": [{\"password\": \"${secret:p}\"}]}"}`)
|
|
found, err := Check(root)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
want := []string{"a cfg password", "b cfg server.secret_key", "f cfg users[0].password"}
|
|
if len(found) != len(want) {
|
|
t.Fatalf("found %v, want %v", found, want)
|
|
}
|
|
for i, f := range found {
|
|
if f.String() != want[i] {
|
|
t.Fatalf("found %v, want %v", found, want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestTheKnownListOnlyShrinks(t *testing.T) {
|
|
found := []Finding{{"b", "cfg", "server.secret_key"}, {"a", "cfg", "password"}}
|
|
refused, stale := Judge(found, map[string]bool{"b cfg server.secret_key": true, "gone cfg token": true})
|
|
if len(refused) != 1 || refused[0].String() != "a cfg password" {
|
|
t.Fatalf("refused %v", refused)
|
|
}
|
|
if len(stale) != 1 || stale[0] != "gone cfg token" {
|
|
t.Fatalf("stale %v", stale)
|
|
}
|
|
}
|
|
|
|
func TestTheCatalogueHoldsNoSecretASettingCouldReplace(t *testing.T) {
|
|
found, err := Check("../..")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
known, err := Known("known")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
refused, stale := Judge(found, known)
|
|
if len(refused) > 0 || len(stale) > 0 {
|
|
t.Fatalf("refused %v, stale %v", refused, stale)
|
|
}
|
|
}
|
|
|
|
func TestALineTheTrunkDoesNotHoldIsRefused(t *testing.T) {
|
|
trunk := map[string]bool{"b cfg server.secret_key": true}
|
|
// A key unprotected on the branch, and its line added to the list: refused, though it matches a finding.
|
|
branch := map[string]bool{"b cfg server.secret_key": true, "a cfg password": true}
|
|
if added := Added(branch, trunk); len(added) != 1 || added[0] != "a cfg password" {
|
|
t.Fatalf("added %v", added)
|
|
}
|
|
// A line removed is no addition.
|
|
if added := Added(map[string]bool{}, trunk); len(added) != 0 {
|
|
t.Fatalf("added %v", added)
|
|
}
|
|
// Until the trunk holds a copy, the seed stands for it, and the list as committed is within it.
|
|
known, err := Known("known")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if added := Added(known, seed); len(added) != 0 {
|
|
t.Fatalf("known holds lines the seed does not: %v", added)
|
|
}
|
|
}
|
|
|
|
func TestTheCheckRefusesALineAddedAgainstTheTrunk(t *testing.T) {
|
|
root := t.TempDir()
|
|
manifest(t, root, "a", `{"id":"cfg","type":"file","merge":"json","content":"{\"password\": \"${secret:admin}\"}"}`)
|
|
dir := t.TempDir()
|
|
base := filepath.Join(dir, "base")
|
|
if err := os.WriteFile(base, []byte("# the trunk's\n"), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
branch := map[string]bool{"a cfg password": true}
|
|
found, err := Check(root)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
trunk, err := Known(base)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
refused, stale := Judge(found, branch)
|
|
if len(refused) != 0 || len(stale) != 0 {
|
|
t.Fatalf("the line hides the finding from Judge alone: %v %v", refused, stale)
|
|
}
|
|
if added := Added(branch, trunk); len(added) != 1 {
|
|
t.Fatalf("an added line passed: %v", added)
|
|
}
|
|
}
|