forked from open-policy-agent/opa
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathresultset.go
88 lines (76 loc) · 2.21 KB
/
resultset.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package rego
import (
"fmt"
"github.com/open-policy-agent/opa/ast"
)
// ResultSet represents a collection of output from Rego evaluation. An empty
// result set represents an undefined query.
type ResultSet []Result
// Vars represents a collection of variable bindings. The keys are the variable
// names and the values are the binding values.
type Vars map[string]interface{}
// WithoutWildcards returns a copy of v with wildcard variables removed.
func (v Vars) WithoutWildcards() Vars {
n := Vars{}
for k, v := range v {
if ast.Var(k).IsWildcard() || ast.Var(k).IsGenerated() {
continue
}
n[k] = v
}
return n
}
// Result defines the output of Rego evaluation.
type Result struct {
Expressions []*ExpressionValue `json:"expressions"`
Bindings Vars `json:"bindings,omitempty"`
}
func newResult() Result {
return Result{
Bindings: Vars{},
}
}
// Location defines a position in a Rego query or module.
type Location struct {
Row int `json:"row"`
Col int `json:"col"`
}
// ExpressionValue defines the value of an expression in a Rego query.
type ExpressionValue struct {
Value interface{} `json:"value"`
Text string `json:"text"`
Location *Location `json:"location"`
}
func newExpressionValue(expr *ast.Expr, value interface{}) *ExpressionValue {
result := &ExpressionValue{
Value: value,
}
if expr.Location != nil {
result.Text = string(expr.Location.Text)
result.Location = &Location{
Row: expr.Location.Row,
Col: expr.Location.Col,
}
}
return result
}
func (ev *ExpressionValue) String() string {
return fmt.Sprint(ev.Value)
}
// Allowed is a helper method that'll return true iff there is only one expression
// in the result set's only member, and that expression has the value `true`; and
// there are no bindings.
//
// If bindings are present, this will yield `false`: it would be a pitfall to
// return `true` for a query like `data.authz.allow = x`, which always has result
// set element with value true, but could also have a binding `x: false`.
func (rs ResultSet) Allowed() bool {
if len(rs) == 1 && len(rs[0].Bindings) == 0 {
if exprs := rs[0].Expressions; len(exprs) == 1 {
if b, ok := exprs[0].Value.(bool); ok {
return b
}
}
}
return false
}