Files
releases/ast/conflicts.go
T
Torin Sandall bb80fd7f74 Add path conflict checks
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>
2019-02-15 08:00:22 -08:00

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
}