diff options
Diffstat (limited to 'vendor/github.com/authzed/spicedb/pkg/caveats/env.go')
| -rw-r--r-- | vendor/github.com/authzed/spicedb/pkg/caveats/env.go | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/vendor/github.com/authzed/spicedb/pkg/caveats/env.go b/vendor/github.com/authzed/spicedb/pkg/caveats/env.go new file mode 100644 index 0000000..7e33183 --- /dev/null +++ b/vendor/github.com/authzed/spicedb/pkg/caveats/env.go @@ -0,0 +1,111 @@ +package caveats + +import ( + "fmt" + + "github.com/authzed/cel-go/cel" + + "github.com/authzed/spicedb/pkg/caveats/types" + core "github.com/authzed/spicedb/pkg/proto/core/v1" +) + +// Environment defines the evaluation environment for a caveat. +type Environment struct { + ts *types.TypeSet + variables map[string]types.VariableType +} + +// NewEnvironment creates and returns a new environment for compiling a caveat. +func NewEnvironment() *Environment { + return &Environment{ + ts: types.Default.TypeSet, + variables: map[string]types.VariableType{}, + } +} + +// NewEnvironmentWithTypeSet creates and returns a new environment for compiling a caveat +// with the given TypeSet. +func NewEnvironmentWithTypeSet(ts *types.TypeSet) *Environment { + return &Environment{ + ts: ts, + variables: map[string]types.VariableType{}, + } +} + +// EnvForVariables returns a new environment constructed for the given variables. +func EnvForVariables(vars map[string]types.VariableType) (*Environment, error) { + return EnvForVariablesWithTypeSet(types.Default.TypeSet, vars) +} + +// EnvForVariablesWithTypeSet returns a new environment constructed for the given variables. +func EnvForVariablesWithTypeSet(ts *types.TypeSet, vars map[string]types.VariableType) (*Environment, error) { + e := NewEnvironmentWithTypeSet(ts) + for varName, varType := range vars { + err := e.AddVariable(varName, varType) + if err != nil { + return nil, err + } + } + return e, nil +} + +// MustEnvForVariables returns a new environment constructed for the given variables +// or panics. +func MustEnvForVariables(vars map[string]types.VariableType) *Environment { + env, err := EnvForVariables(vars) + if err != nil { + panic(err) + } + return env +} + +// AddVariable adds a variable with the given type to the environment. +func (e *Environment) AddVariable(name string, varType types.VariableType) error { + if _, ok := e.variables[name]; ok { + return fmt.Errorf("variable `%s` already exists", name) + } + + e.variables[name] = varType + return nil +} + +// EncodedParametersTypes returns the map of encoded parameters for the environment. +func (e *Environment) EncodedParametersTypes() map[string]*core.CaveatTypeReference { + return types.EncodeParameterTypes(e.variables) +} + +// asCelEnvironment converts the exported Environment into an internal CEL environment. +func (e *Environment) asCelEnvironment(extraOptions ...cel.EnvOption) (*cel.Env, error) { + tsOptions, err := e.ts.EnvOptions() + if err != nil { + return nil, err + } + + opts := make([]cel.EnvOption, 0, len(extraOptions)+len(e.variables)+len(tsOptions)+2) + opts = append(opts, extraOptions...) + opts = append(opts, tsOptions...) + + // Set options. + // DefaultUTCTimeZone: ensure all timestamps are evaluated at UTC + opts = append(opts, cel.DefaultUTCTimeZone(true)) + + // OptionalTypes: enable optional typing syntax, e.g. `sometype?.foo` + // See: https://github.com/google/cel-spec/wiki/proposal-246 + opts = append(opts, cel.OptionalTypes(cel.OptionalTypesVersion(0))) + + // EnableMacroCallTracking: enables tracking of call macros so when we call AstToString we get + // back out the expected expressions. + // See: https://github.com/authzed/cel-go/issues/474 + opts = append(opts, cel.EnableMacroCallTracking()) + + // ParserExpressionSizeLimit: disable the size limit for codepoints in expressions. + // This has to be disabled due to us padding out the whitespace in expression parsing based on + // schema size. We instead do our own expression size check in the Compile method. + // TODO(jschorr): Remove this once the whitespace hack is removed. + opts = append(opts, cel.ParserExpressionSizeLimit(-1)) + + for name, varType := range e.variables { + opts = append(opts, cel.Variable(name, varType.CelType())) + } + return cel.NewEnv(opts...) +} |
