generated from coulomb/repo-seed
Implement policy package loader
This commit is contained in:
@@ -1,15 +1,96 @@
|
||||
package policy_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/netkingdom/flex-auth/internal/policy"
|
||||
"github.com/netkingdom/flex-auth/pkg/api"
|
||||
)
|
||||
|
||||
func TestLoadPolicyPackageMarkdownValidates(t *testing.T) {
|
||||
pkg, err := policy.LoadAndValidateFile(context.Background(), filepath.Join("..", "..", "examples", "caring", "policy_package.md"))
|
||||
if err != nil {
|
||||
t.Fatalf("LoadAndValidateFile: %v", err)
|
||||
}
|
||||
|
||||
if !pkg.Valid {
|
||||
t.Fatalf("pkg.Valid = false\n%s", formatValidation(pkg.Validation))
|
||||
}
|
||||
if pkg.Metadata.Caring.Profile != api.CaringProfileCaring040RC2 {
|
||||
t.Fatalf("metadata.Caring.Profile = %q; want %q", pkg.Metadata.Caring.Profile, api.CaringProfileCaring040RC2)
|
||||
}
|
||||
if pkg.Metadata.Namespace != "markitect:document" {
|
||||
t.Errorf("metadata.Namespace = %q; want markitect:document", pkg.Metadata.Namespace)
|
||||
}
|
||||
if !strings.HasPrefix(pkg.RegoModule, "package flexauth.markitect.documents") {
|
||||
t.Errorf("RegoModule prefix = %q; want flexauth.markitect.documents package", pkg.RegoModule[:min(len(pkg.RegoModule), 80)])
|
||||
}
|
||||
if len(pkg.RuleBlocks) != 1 || len(pkg.TestBlocks) != 1 || len(pkg.Fixtures) != 2 {
|
||||
t.Fatalf("blocks/fixtures = rules:%d tests:%d fixtures:%d; want 1/1/2", len(pkg.RuleBlocks), len(pkg.TestBlocks), len(pkg.Fixtures))
|
||||
}
|
||||
if len(pkg.Validation.Tests) != 2 {
|
||||
t.Fatalf("Validation.Tests len = %d; want 2", len(pkg.Validation.Tests))
|
||||
}
|
||||
for _, test := range pkg.Validation.Tests {
|
||||
if !test.Passed {
|
||||
t.Fatalf("test %s failed: %s", test.Name, test.Error)
|
||||
}
|
||||
}
|
||||
for _, fixture := range pkg.Validation.Fixtures {
|
||||
if !fixture.Passed {
|
||||
t.Fatalf("fixture %s failed: %s\nactual: %+v", fixture.ID, fixture.Error, fixture.Actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCaringFindingsAreAdvisoryUntilEnforced(t *testing.T) {
|
||||
doc := inlinePolicy(false, "allow")
|
||||
pkg, err := policy.Load([]byte(doc), "inline-policy.md")
|
||||
if err != nil {
|
||||
t.Fatalf("Load: %v", err)
|
||||
}
|
||||
|
||||
result := pkg.Validate(context.Background())
|
||||
if !result.Valid {
|
||||
t.Fatalf("result.Valid = false without CARING enforcement\n%s", formatValidation(result))
|
||||
}
|
||||
if len(result.CaringFindings) == 0 {
|
||||
t.Fatal("expected advisory CARING findings for missing metadata dimensions")
|
||||
}
|
||||
|
||||
enforced := strings.Replace(doc, "enforce: false", "enforce: true", 1)
|
||||
pkg, err = policy.Load([]byte(enforced), "inline-policy.md")
|
||||
if err != nil {
|
||||
t.Fatalf("Load enforced: %v", err)
|
||||
}
|
||||
result = pkg.Validate(context.Background())
|
||||
if result.Valid {
|
||||
t.Fatalf("result.Valid = true with CARING enforcement; want invalid\n%s", formatValidation(result))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFixtureMismatchInvalidatesPackage(t *testing.T) {
|
||||
pkg, err := policy.Load([]byte(inlinePolicy(false, "deny")), "inline-policy.md")
|
||||
if err != nil {
|
||||
t.Fatalf("Load: %v", err)
|
||||
}
|
||||
|
||||
result := pkg.Validate(context.Background())
|
||||
if result.Valid {
|
||||
t.Fatalf("result.Valid = true; want fixture mismatch to invalidate package\n%s", formatValidation(result))
|
||||
}
|
||||
if len(result.Fixtures) != 1 || result.Fixtures[0].Passed {
|
||||
t.Fatalf("fixture result = %+v; want one failed fixture", result.Fixtures)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPolicyPackageMetadataParses(t *testing.T) {
|
||||
var metadata api.PolicyPackageMetadata
|
||||
loadYAML(t, filepath.Join("..", "..", "examples", "caring", "policy_package.yaml"), &metadata)
|
||||
@@ -37,6 +118,63 @@ func TestPolicyFixtureParses(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func inlinePolicy(enforce bool, expectedEffect string) string {
|
||||
enforceValue := "false"
|
||||
if enforce {
|
||||
enforceValue = "true"
|
||||
}
|
||||
|
||||
fence := "```"
|
||||
doc := strings.ReplaceAll(`---
|
||||
id: inline.allow
|
||||
version: v1
|
||||
package: flexauth.inline
|
||||
caring:
|
||||
profile: caring-0.4.0-rc2
|
||||
enforce: ENFORCE
|
||||
---
|
||||
|
||||
# Inline Policy
|
||||
|
||||
`+fence+`rego
|
||||
default decision := {"effect": "allow", "reason": "ok"}
|
||||
`+fence+`
|
||||
|
||||
`+fence+`rego test
|
||||
package flexauth.inline_test
|
||||
|
||||
import future.keywords.if
|
||||
import data.flexauth.inline
|
||||
|
||||
test_allow if {
|
||||
inline.decision.effect == "allow"
|
||||
}
|
||||
`+fence+`
|
||||
|
||||
`+fence+`yaml fixture
|
||||
id: fixture:inline
|
||||
request:
|
||||
subject:
|
||||
id: user:alice
|
||||
action: read
|
||||
resource:
|
||||
id: document:inline
|
||||
expect:
|
||||
effect: EXPECTED
|
||||
reason: ok
|
||||
`+fence+`
|
||||
`, "ENFORCE", enforceValue)
|
||||
return strings.ReplaceAll(doc, "EXPECTED", expectedEffect)
|
||||
}
|
||||
|
||||
func formatValidation(result policy.ValidationResult) string {
|
||||
data, err := json.MarshalIndent(result, "", " ")
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
return string(data)
|
||||
}
|
||||
|
||||
func loadYAML(t *testing.T, path string, out any) {
|
||||
t.Helper()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user