-
Notifications
You must be signed in to change notification settings - Fork 124
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Validate policy and test files with JSON schema (#1526)
* enhancement: Validate policy and test files with JSON schema Signed-off-by: Oğuzhan Durgun <oguzhandurgun95@gmail.com> * Address reviews Signed-off-by: Oğuzhan Durgun <oguzhandurgun95@gmail.com> * Address reviews Signed-off-by: Oğuzhan Durgun <oguzhandurgun95@gmail.com> * Address reviews Signed-off-by: Oğuzhan Durgun <oguzhandurgun95@gmail.com> * Add empty path handling for validation error Signed-off-by: Oğuzhan Durgun <oguzhandurgun95@gmail.com> * Address reviews Signed-off-by: Oğuzhan Durgun <oguzhandurgun95@gmail.com> --------- Signed-off-by: Oğuzhan Durgun <oguzhandurgun95@gmail.com>
- Loading branch information
1 parent
16d8656
commit 7570df3
Showing
21 changed files
with
184 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
// Copyright 2021-2023 Zenauth Ltd. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package jsonschema | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"io" | ||
"io/fs" | ||
"log" | ||
"strings" | ||
|
||
"github.com/santhosh-tekuri/jsonschema/v5" | ||
"gopkg.in/yaml.v3" | ||
|
||
"github.com/cerbos/cerbos/schema" | ||
) | ||
|
||
var ( | ||
policySchema *jsonschema.Schema | ||
testSchema *jsonschema.Schema | ||
) | ||
|
||
func init() { | ||
var err error | ||
if policySchema, err = jsonschema.CompileString("Policy.schema.json", schema.PolicyJSONSchema); err != nil { | ||
log.Fatalf("failed to compile policy schema: %v", err) | ||
} | ||
|
||
if testSchema, err = jsonschema.CompileString("TestSuite.schema.json", schema.TestSuiteJSONSchema); err != nil { | ||
log.Fatalf("failed to compile test schema: %v", err) | ||
} | ||
} | ||
|
||
// ValidatePolicy validates the policy in the fsys with the JSON schema. | ||
func ValidatePolicy(fsys fs.FS, path string) error { | ||
return validate(policySchema, fsys, path) | ||
} | ||
|
||
// ValidateTest validates the test in the fsys with the JSON schema. | ||
func ValidateTest(fsys fs.FS, path string) error { | ||
return validate(testSchema, fsys, path) | ||
} | ||
|
||
func validate(s *jsonschema.Schema, fsys fs.FS, path string) error { | ||
f, err := fsys.Open(path) | ||
if err != nil { | ||
return fmt.Errorf("failed to open file %s: %w", path, err) | ||
} | ||
defer f.Close() | ||
|
||
data, err := io.ReadAll(f) | ||
if err != nil { | ||
return fmt.Errorf("failed to read file %s: %w", path, err) | ||
} | ||
|
||
var y any | ||
if err := yaml.Unmarshal(data, &y); err != nil { | ||
return fmt.Errorf("failed to unmarshal file %s: %w", path, err) | ||
} | ||
|
||
if err := s.Validate(y); err != nil { | ||
var validationErr *jsonschema.ValidationError | ||
if ok := errors.As(err, &validationErr); !ok { | ||
return fmt.Errorf("unable to validate file %s: %w", path, err) | ||
} | ||
|
||
return newValidationErrorList(validationErr) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func newValidationError(err *jsonschema.ValidationError) validationError { | ||
path := "/" | ||
if err.InstanceLocation != "" { | ||
path = err.InstanceLocation | ||
} | ||
return validationError{ | ||
Path: path, | ||
Message: err.Message, | ||
} | ||
} | ||
|
||
func newValidationErrorList(validationErr *jsonschema.ValidationError) validationErrorList { | ||
if validationErr == nil { | ||
return nil | ||
} | ||
|
||
if len(validationErr.Causes) == 0 { | ||
return validationErrorList{newValidationError(validationErr)} | ||
} | ||
|
||
var errs validationErrorList | ||
for _, err := range validationErr.Causes { | ||
errs = append(errs, newValidationErrorList(err)...) | ||
} | ||
|
||
return errs | ||
} | ||
|
||
type validationError struct { | ||
Path string | ||
Message string | ||
} | ||
|
||
func (e validationError) Error() string { | ||
return fmt.Sprintf("%s: %s", e.Path, e.Message) | ||
} | ||
|
||
type validationErrorList []validationError | ||
|
||
func (e validationErrorList) Error() string { | ||
return fmt.Sprintf("file is not valid: [%s]", strings.Join(e.ErrorMessages(), ", ")) | ||
} | ||
|
||
func (e validationErrorList) ErrorMessages() []string { | ||
if len(e) == 0 { | ||
return nil | ||
} | ||
|
||
msgs := make([]string, len(e)) | ||
for i, err := range e { | ||
msgs[i] = err.Error() | ||
} | ||
|
||
return msgs | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters