package policy import "testing" func TestEvaluateAdminWildcard(t *testing.T) { rules := DefaultRules() input := PolicyInput{ Subject: "admin-uuid", AccountType: "human", Roles: []string{"admin"}, Action: ActionPush, Repository: "myapp", } effect, rule := Evaluate(input, rules) if effect != Allow { t.Fatalf("admin push: got %s, want allow", effect) } if rule == nil || rule.ID != -1 { t.Fatalf("admin push: expected admin wildcard rule (ID -1), got %+v", rule) } } func TestEvaluateUserAllow(t *testing.T) { rules := DefaultRules() input := PolicyInput{ Subject: "user-uuid", AccountType: "human", Roles: []string{"user"}, Action: ActionPull, Repository: "myapp", } effect, rule := Evaluate(input, rules) if effect != Allow { t.Fatalf("user pull: got %s, want allow", effect) } if rule == nil || rule.ID != -2 { t.Fatalf("user pull: expected user content rule (ID -2), got %+v", rule) } } func TestEvaluateSystemAccountDeny(t *testing.T) { rules := DefaultRules() input := PolicyInput{ Subject: "system-uuid", AccountType: "system", Action: ActionPull, Repository: "myapp", } effect, rule := Evaluate(input, rules) if effect != Deny { t.Fatalf("system pull: got %s, want deny", effect) } if rule != nil { t.Fatalf("system pull: expected default deny (nil rule), got %+v", rule) } } func TestEvaluateExactRepoMatch(t *testing.T) { rules := append(DefaultRules(), Rule{ ID: 1, Priority: 50, Effect: Allow, SubjectUUID: "ci-uuid", Actions: []Action{ActionPull}, Repositories: []string{"myapp"}, }) input := PolicyInput{ Subject: "ci-uuid", AccountType: "system", Action: ActionPull, Repository: "myapp", } effect, _ := Evaluate(input, rules) if effect != Allow { t.Fatalf("exact repo match: got %s, want allow", effect) } // Different repo should deny. input.Repository = "other" effect, _ = Evaluate(input, rules) if effect != Deny { t.Fatalf("different repo: got %s, want deny", effect) } } func TestEvaluateGlobMatch(t *testing.T) { rules := append(DefaultRules(), Rule{ ID: 1, Priority: 50, Effect: Allow, SubjectUUID: "ci-uuid", Actions: []Action{ActionPush, ActionPull}, Repositories: []string{"production/*"}, }) input := PolicyInput{ Subject: "ci-uuid", AccountType: "system", Action: ActionPush, Repository: "production/myapp", } effect, _ := Evaluate(input, rules) if effect != Allow { t.Fatalf("glob match production/myapp: got %s, want allow", effect) } // Nested repo should not match (path.Match: * doesn't cross /). input.Repository = "production/team/myapp" effect, _ = Evaluate(input, rules) if effect != Deny { t.Fatalf("glob no-match production/team/myapp: got %s, want deny", effect) } } func TestEvaluateDenyWins(t *testing.T) { rules := []Rule{ { ID: 1, Priority: 50, Effect: Allow, SubjectUUID: "agent-uuid", Actions: []Action{ActionPull}, }, { ID: 2, Priority: 10, Effect: Deny, SubjectUUID: "agent-uuid", Actions: []Action{ActionPull}, }, } input := PolicyInput{ Subject: "agent-uuid", AccountType: "system", Action: ActionPull, Repository: "myapp", } effect, rule := Evaluate(input, rules) if effect != Deny { t.Fatalf("deny-wins: got %s, want deny", effect) } if rule == nil || rule.ID != 2 { t.Fatalf("deny-wins: expected deny rule (ID 2), got %+v", rule) } } func TestEvaluatePriorityOrdering(t *testing.T) { rules := []Rule{ { ID: 1, Priority: 100, Effect: Allow, Actions: []Action{ActionPull}, }, { ID: 2, Priority: 10, Effect: Deny, Actions: []Action{ActionPull}, }, } input := PolicyInput{ Subject: "any", AccountType: "system", Action: ActionPull, Repository: "myapp", } effect, _ := Evaluate(input, rules) if effect != Deny { t.Fatalf("priority: got %s, want deny", effect) } } func TestEvaluateEmptyRepoGlobalOperation(t *testing.T) { rules := DefaultRules() // Admin should be allowed for catalog (admin wildcard, empty Repositories = wildcard). input := PolicyInput{ Subject: "admin-uuid", AccountType: "human", Roles: []string{"admin"}, Action: ActionCatalog, } effect, _ := Evaluate(input, rules) if effect != Allow { t.Fatalf("admin catalog: got %s, want allow", effect) } // System account with a repo-scoped rule should be denied for catalog // (global op doesn't match repo-scoped rules). rules = append(rules, Rule{ ID: 1, Priority: 50, Effect: Allow, SubjectUUID: "ci-uuid", Actions: []Action{ActionCatalog}, Repositories: []string{"myapp"}, }) input = PolicyInput{ Subject: "ci-uuid", AccountType: "system", Action: ActionCatalog, } effect, _ = Evaluate(input, rules) if effect != Deny { t.Fatalf("system catalog with repo-scoped rule: got %s, want deny", effect) } } func TestEvaluateMultipleMatchingRules(t *testing.T) { rules := []Rule{ { ID: 1, Priority: 50, Effect: Allow, Actions: []Action{ActionPull}, }, { ID: 2, Priority: 100, Effect: Allow, Actions: []Action{ActionPull, ActionPush}, }, } input := PolicyInput{ Subject: "any", AccountType: "system", Action: ActionPull, Repository: "myapp", } effect, rule := Evaluate(input, rules) if effect != Allow { t.Fatalf("multiple allow: got %s, want allow", effect) } if rule == nil || rule.ID != 1 { t.Fatalf("multiple allow: expected rule ID 1 (higher priority), got %+v", rule) } } // --- Default rules tests (Step 4.2) --- func TestDefaultRulesAdminAllActions(t *testing.T) { rules := DefaultRules() actions := []Action{ ActionVersionCheck, ActionPull, ActionPush, ActionDelete, ActionCatalog, ActionPolicyManage, } for _, a := range actions { input := PolicyInput{ Subject: "admin-uuid", AccountType: "human", Roles: []string{"admin"}, Action: a, Repository: "myapp", } effect, _ := Evaluate(input, rules) if effect != Allow { t.Errorf("admin %s: got %s, want allow", a, effect) } } } func TestDefaultRulesUserContentAccess(t *testing.T) { rules := DefaultRules() allowed := []Action{ActionPull, ActionPush, ActionDelete, ActionCatalog} for _, a := range allowed { input := PolicyInput{ Subject: "user-uuid", AccountType: "human", Roles: []string{"user"}, Action: a, Repository: "myapp", } effect, _ := Evaluate(input, rules) if effect != Allow { t.Errorf("user %s: got %s, want allow", a, effect) } } // policy:manage should be denied for regular user. input := PolicyInput{ Subject: "user-uuid", AccountType: "human", Roles: []string{"user"}, Action: ActionPolicyManage, } effect, _ := Evaluate(input, rules) if effect != Deny { t.Errorf("user policy:manage: got %s, want deny", effect) } } func TestDefaultRulesSystemAccountDeny(t *testing.T) { rules := DefaultRules() actions := []Action{ActionPull, ActionPush, ActionDelete, ActionCatalog, ActionPolicyManage} for _, a := range actions { input := PolicyInput{ Subject: "system-uuid", AccountType: "system", Action: a, Repository: "myapp", } effect, _ := Evaluate(input, rules) if effect != Deny { t.Errorf("system %s: got %s, want deny", a, effect) } } } func TestDefaultRulesVersionCheckAlwaysAllowed(t *testing.T) { rules := DefaultRules() for _, acctType := range []string{"human", "system"} { input := PolicyInput{ Subject: "any-uuid", AccountType: acctType, Action: ActionVersionCheck, } effect, _ := Evaluate(input, rules) if effect != Allow { t.Errorf("%s version_check: got %s, want allow", acctType, effect) } } }