package policy import "testing" // fakeRuleStore implements RuleStore for testing. type fakeRuleStore struct { rules []Rule err error } func (f *fakeRuleStore) LoadEnabledPolicyRules() ([]Rule, error) { return f.rules, f.err } func TestEngineDefaultsOnly(t *testing.T) { e := NewEngine() // Admin should be allowed. effect, _ := e.Evaluate(PolicyInput{ Subject: "admin-uuid", AccountType: "human", Roles: []string{"admin"}, Action: ActionPush, Repository: "myapp", }) if effect != Allow { t.Fatalf("admin push with defaults: got %s, want allow", effect) } // System account should be allowed (rule -2: authenticated users). effect, _ = e.Evaluate(PolicyInput{ Subject: "system-uuid", AccountType: "system", Action: ActionPull, Repository: "myapp", }) if effect != Allow { t.Fatalf("system pull with defaults: got %s, want allow", effect) } } func TestEngineWithCustomRules(t *testing.T) { e := NewEngine() e.SetRules([]Rule{ { ID: 1, Priority: 50, Effect: Allow, SubjectUUID: "ci-uuid", Actions: []Action{ActionPull, ActionPush}, }, }) // System account with matching rule should be allowed. effect, _ := e.Evaluate(PolicyInput{ Subject: "ci-uuid", AccountType: "system", Action: ActionPull, Repository: "myapp", }) if effect != Allow { t.Fatalf("ci pull with custom rule: got %s, want allow", effect) } // Different subject is still allowed via default rule -2 (authenticated users). effect, _ = e.Evaluate(PolicyInput{ Subject: "other-uuid", AccountType: "system", Action: ActionPull, Repository: "myapp", }) if effect != Allow { t.Fatalf("other pull: got %s, want allow", effect) } } func TestEngineReload(t *testing.T) { e := NewEngine() store := &fakeRuleStore{ rules: []Rule{ { ID: 1, Priority: 50, Effect: Allow, SubjectUUID: "ci-uuid", Actions: []Action{ActionPull}, }, }, } if err := e.Reload(store); err != nil { t.Fatalf("Reload: %v", err) } // ci-uuid should now be allowed. effect, _ := e.Evaluate(PolicyInput{ Subject: "ci-uuid", AccountType: "system", Action: ActionPull, Repository: "myapp", }) if effect != Allow { t.Fatalf("ci pull after reload: got %s, want allow", effect) } // Reload again with new rules (simulating DB change). store.rules = []Rule{ { ID: 2, Priority: 50, Effect: Allow, SubjectUUID: "deploy-uuid", Actions: []Action{ActionPull}, }, } if err := e.Reload(store); err != nil { t.Fatalf("Reload (second): %v", err) } // ci-uuid custom rule is gone, but still allowed via default rule -2. effect, _ = e.Evaluate(PolicyInput{ Subject: "ci-uuid", AccountType: "system", Action: ActionPull, Repository: "myapp", }) if effect != Allow { t.Fatalf("ci pull after second reload: got %s, want allow", effect) } // deploy-uuid should now be allowed. effect, _ = e.Evaluate(PolicyInput{ Subject: "deploy-uuid", AccountType: "system", Action: ActionPull, Repository: "myapp", }) if effect != Allow { t.Fatalf("deploy pull after reload: got %s, want allow", effect) } } func TestEngineReloadDisabledExcluded(t *testing.T) { e := NewEngine() // Store returns no rules (all disabled or none exist). store := &fakeRuleStore{rules: nil} if err := e.Reload(store); err != nil { t.Fatalf("Reload: %v", err) } // No custom rules, but system account is allowed via default rule -2. effect, _ := e.Evaluate(PolicyInput{ Subject: "ci-uuid", AccountType: "system", Action: ActionPull, Repository: "myapp", }) if effect != Allow { t.Fatalf("system pull with no custom rules: got %s, want allow", effect) } }