mirror of
https://github.com/open-policy-agent/opa.git
synced 2026-08-26 02:04:50 -06:00
bb80fd7f74
Previously there were no checks in place to ensure that base and virtual documents do not overlap. As a result, if users loaded raw JSON and rules into OPA that overlapped, the evaluation results were not well defined. With these changes, we can detect the overlap and reject updates (to policies or data) that would cause inconsistent results. Fixes #1207 Signed-off-by: Torin Sandall <torinsandall@gmail.com>
49 lines
1.3 KiB
Go
49 lines
1.3 KiB
Go
// Copyright 2019 The OPA Authors. All rights reserved.
|
|
// Use of this source code is governed by an Apache2
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package ast
|
|
|
|
import (
|
|
"strings"
|
|
)
|
|
|
|
// CheckPathConflicts returns a set of errors indicating paths that
|
|
// are in conflict with the result of the provided callable.
|
|
func CheckPathConflicts(c *Compiler, exists func([]string) (bool, error)) Errors {
|
|
var errs Errors
|
|
|
|
root := c.RuleTree.Child(DefaultRootDocument.Value)
|
|
if root == nil {
|
|
return nil
|
|
}
|
|
|
|
for _, node := range root.Children {
|
|
errs = append(errs, checkDocumentConflicts(node, exists, nil)...)
|
|
}
|
|
|
|
return errs
|
|
}
|
|
|
|
func checkDocumentConflicts(node *TreeNode, exists func([]string) (bool, error), path []string) Errors {
|
|
|
|
path = append(path, string(node.Key.(String)))
|
|
|
|
if len(node.Values) > 0 {
|
|
s := strings.Join(path, "/")
|
|
if ok, err := exists(path); err != nil {
|
|
return Errors{NewError(CompileErr, node.Values[0].(*Rule).Loc(), "conflict check for data path %v: %v", s, err.Error())}
|
|
} else if ok {
|
|
return Errors{NewError(CompileErr, node.Values[0].(*Rule).Loc(), "conflicting rule for data path %v found", s)}
|
|
}
|
|
}
|
|
|
|
var errs Errors
|
|
|
|
for _, child := range node.Children {
|
|
errs = append(errs, checkDocumentConflicts(child, exists, path)...)
|
|
}
|
|
|
|
return errs
|
|
}
|