105 lines
2.5 KiB
Go
105 lines
2.5 KiB
Go
package elevate
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
func TestRuleMatch(t *testing.T) {
|
|
tests := []struct {
|
|
rule Rule
|
|
cmd string
|
|
fingerprint string
|
|
want bool
|
|
}{
|
|
{Rule{Cmd: "echo hello"}, "echo hello", "", true},
|
|
{Rule{Cmd: "echo hello"}, "echo world", "", false},
|
|
{Rule{Cmd: "git *"}, "git push", "", true},
|
|
{Rule{Cmd: "git *"}, "git pull", "", true},
|
|
{Rule{Cmd: "git *"}, "make build", "", false},
|
|
{Rule{Cmd: "echo *"}, "echo hello world", "", true}, // filepath.Match * matches any non-separator chars
|
|
{Rule{SSH: "SHA256:abc123"}, "", "SHA256:abc123", true},
|
|
{Rule{SSH: "SHA256:abc123"}, "", "SHA256:other", false},
|
|
{Rule{}, "anything", "anything", false},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
got := tt.rule.Match(tt.cmd, tt.fingerprint)
|
|
if got != tt.want {
|
|
t.Errorf("Rule%+v.Match(%q, %q) = %v; want %v", tt.rule, tt.cmd, tt.fingerprint, got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestPolicyMatches(t *testing.T) {
|
|
p := &Policy{
|
|
Rules: []Rule{
|
|
{Cmd: "echo *"},
|
|
{Cmd: "git push"},
|
|
{SSH: "SHA256:mykey"},
|
|
},
|
|
}
|
|
|
|
if !p.Matches("git push", "") {
|
|
t.Error("expected git push to match")
|
|
}
|
|
if !p.Matches("", "SHA256:mykey") {
|
|
t.Error("expected SSH key to match")
|
|
}
|
|
if p.Matches("rm -rf /", "") {
|
|
t.Error("expected rm to not match")
|
|
}
|
|
}
|
|
|
|
func TestPolicyAdd(t *testing.T) {
|
|
p := &Policy{}
|
|
if !p.Add(Rule{Cmd: "echo hi"}) {
|
|
t.Error("first add should return true")
|
|
}
|
|
if p.Add(Rule{Cmd: "echo hi"}) {
|
|
t.Error("duplicate add should return false")
|
|
}
|
|
if len(p.Rules) != 1 {
|
|
t.Errorf("expected 1 rule, got %d", len(p.Rules))
|
|
}
|
|
}
|
|
|
|
func TestPolicyStorePersistence(t *testing.T) {
|
|
dir := t.TempDir()
|
|
path := filepath.Join(dir, "policy.yaml")
|
|
|
|
// Create and save
|
|
ps := NewPolicyStore(path)
|
|
ps.AddGlobal(Rule{Cmd: "make build"})
|
|
ps.AddGlobal(Rule{SSH: "SHA256:testkey"})
|
|
|
|
if !ps.MatchesGlobal("make build", "") {
|
|
t.Error("expected make build to match")
|
|
}
|
|
|
|
// Reload from disk
|
|
ps2 := NewPolicyStore(path)
|
|
if !ps2.MatchesGlobal("make build", "") {
|
|
t.Error("expected make build to match after reload")
|
|
}
|
|
if !ps2.MatchesGlobal("", "SHA256:testkey") {
|
|
t.Error("expected SSH key to match after reload")
|
|
}
|
|
|
|
// Verify file exists
|
|
if _, err := os.Stat(path); err != nil {
|
|
t.Errorf("policy file not created: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestPolicyStoreEmpty(t *testing.T) {
|
|
dir := t.TempDir()
|
|
path := filepath.Join(dir, "nonexistent.yaml")
|
|
|
|
ps := NewPolicyStore(path)
|
|
if ps.MatchesGlobal("anything", "") {
|
|
t.Error("empty policy should not match")
|
|
}
|
|
}
|