-
Notifications
You must be signed in to change notification settings - Fork 10
/
example_test.go
114 lines (94 loc) · 3.21 KB
/
example_test.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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package ast_test
import (
"fmt"
"github.com/cedar-policy/cedar-go/ast"
"github.com/cedar-policy/cedar-go/types"
)
// This example shows a basic programmatic AST construction via the Permit() builder:
func Example() {
johnny := types.NewEntityUID("FolkHeroes", "johnnyChapman")
sow := types.NewEntityUID("Action", "sow")
cast := types.NewEntityUID("Action", "cast")
midwest := types.NewEntityUID("Locations::USA::Regions", "midwest")
policy := ast.Permit().
PrincipalEq(johnny).
ActionInSet(sow, cast).
ResourceIs("Crops::Apple").
When(ast.Context().Access("location").In(ast.Value(midwest))).
Unless(ast.Context().Access("season").Equal(ast.String("winter")))
fmt.Println(string(policy.MarshalCedar()))
// Output:
// permit (
// principal == FolkHeroes::"johnnyChapman",
// action in [Action::"sow", Action::"cast"],
// resource is Crops::Apple
// )
// when { context.location in Locations::USA::Regions::"midwest" }
// unless { context.season == "winter" };
}
// To programmatically create policies with annotations, use the Annotation() builder:
func Example_annotation() {
policy := ast.Annotation("example1", "value").
Annotation("example2", "").
Forbid()
fmt.Println(string(policy.MarshalCedar()))
// Output:
// @example1("value")
// @example2("")
// forbid ( principal, action, resource );
}
// This example shows how precedence can be expressed using the AST builder syntax:
func Example_precedence() {
// The argument passed to .Add() is the entire right-hand side of the expression, so 1 + 5 is evaluated with
// higher precedence than the subsequent multiplication by 10.
policy := ast.Permit().
When(ast.Long(1).Add(ast.Long(5)).Multiply(ast.Long(10)).Equal(ast.Long(60)))
fmt.Println(string(policy.MarshalCedar()))
// Output:
// permit ( principal, action, resource )
// when { (1 + 5) * 10 == 60 };
}
// Extension functions can be explicitly called by using the appropriate builder with the ExtensionCall suffix. This
// example demonstrates the use of DecimalExtensionCall():
func Example_explicitExtensionCall() {
policy := ast.Forbid().
When(
ast.Resource().Access("angleRadians").DecimalGreaterThan(
ast.DecimalExtensionCall(ast.String("3.1415")),
),
)
fmt.Println(string(policy.MarshalCedar()))
// Output:
// forbid ( principal, action, resource )
// when { resource.angleRadians.greaterThan(decimal("3.1415")) };
}
func ExampleRecord() {
// Literal records can be constructed and passed via the ast.Value() builder
literalRecord := types.NewRecord(types.RecordMap{
"x": types.String("value1"),
"y": types.String("value2"),
})
// Records with internal expressions are constructed via the ast.Record() builder
exprRecord := ast.Record(ast.Pairs{
{
Key: "x",
Value: ast.Long(1).Add(ast.Context().Access("fooCount")),
},
{
Key: "y",
Value: ast.Long(8),
},
})
policy := ast.Forbid().
When(
ast.Value(literalRecord).Access("x").Equal(ast.String("value1")),
).
When(
exprRecord.Access("x").Equal(ast.Long(3)),
)
fmt.Println(string(policy.MarshalCedar()))
// Output:
// forbid ( principal, action, resource )
// when { {"x":"value1", "y":"value2"}.x == "value1" }
// when { {"x":(1 + context.fooCount), "y":8}.x == 3 };
}