mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-06 20:29:54 -06:00
Merge pull request #10117 from owncloud/dependabot/go_modules/github.com/open-policy-agent/opa-0.68.0
chore(deps): bump github.com/open-policy-agent/opa from 0.67.1 to 0.68.0
This commit is contained in:
2
go.mod
2
go.mod
@@ -69,7 +69,7 @@ require (
|
||||
github.com/onsi/ginkgo v1.16.5
|
||||
github.com/onsi/ginkgo/v2 v2.20.2
|
||||
github.com/onsi/gomega v1.34.1
|
||||
github.com/open-policy-agent/opa v0.67.1
|
||||
github.com/open-policy-agent/opa v0.68.0
|
||||
github.com/orcaman/concurrent-map v1.0.0
|
||||
github.com/owncloud/libre-graph-api-go v1.0.5-0.20240820135012-5fac8096ce9c
|
||||
github.com/pkg/errors v0.9.1
|
||||
|
||||
4
go.sum
4
go.sum
@@ -928,8 +928,8 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
|
||||
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
|
||||
github.com/open-policy-agent/opa v0.67.1 h1:rzy26J6g1X+CKknAcx0Vfbt41KqjuSzx4E0A8DAZf3E=
|
||||
github.com/open-policy-agent/opa v0.67.1/go.mod h1:aqKlHc8E2VAAylYE9x09zJYr/fYzGX+JKne89UGqFzk=
|
||||
github.com/open-policy-agent/opa v0.68.0 h1:Jl3U2vXRjwk7JrHmS19U3HZO5qxQRinQbJ2eCJYSqJQ=
|
||||
github.com/open-policy-agent/opa v0.68.0/go.mod h1:5E5SvaPwTpwt2WM177I9Z3eT7qUpmOGjk1ZdHs+TZ4w=
|
||||
github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg=
|
||||
github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
|
||||
13
vendor/github.com/open-policy-agent/opa/ast/annotations.go
generated
vendored
13
vendor/github.com/open-policy-agent/opa/ast/annotations.go
generated
vendored
@@ -417,7 +417,7 @@ func (a *Annotations) Copy(node Node) *Annotations {
|
||||
return &cpy
|
||||
}
|
||||
|
||||
// toObject constructs an AST Object from a.
|
||||
// toObject constructs an AST Object from the annotation.
|
||||
func (a *Annotations) toObject() (*Object, *Error) {
|
||||
obj := NewObject()
|
||||
|
||||
@@ -556,7 +556,11 @@ func attachAnnotationsNodes(mod *Module) Errors {
|
||||
if a.Scope == "" {
|
||||
switch a.node.(type) {
|
||||
case *Rule:
|
||||
a.Scope = annotationScopeRule
|
||||
if a.Entrypoint {
|
||||
a.Scope = annotationScopeDocument
|
||||
} else {
|
||||
a.Scope = annotationScopeRule
|
||||
}
|
||||
case *Package:
|
||||
a.Scope = annotationScopePackage
|
||||
case *Import:
|
||||
@@ -596,8 +600,9 @@ func validateAnnotationScopeAttachment(a *Annotations) *Error {
|
||||
}
|
||||
|
||||
func validateAnnotationEntrypointAttachment(a *Annotations) *Error {
|
||||
if a.Entrypoint && !(a.Scope == annotationScopeRule || a.Scope == annotationScopePackage) {
|
||||
return NewError(ParseErr, a.Loc(), "annotation entrypoint applied to non-rule or package scope '%v'", a.Scope)
|
||||
if a.Entrypoint && !(a.Scope == annotationScopeDocument || a.Scope == annotationScopePackage) {
|
||||
return NewError(
|
||||
ParseErr, a.Loc(), "annotation entrypoint applied to non-document or package scope '%v'", a.Scope)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
14
vendor/github.com/open-policy-agent/opa/ast/builtins.go
generated
vendored
14
vendor/github.com/open-policy-agent/opa/ast/builtins.go
generated
vendored
@@ -1181,7 +1181,7 @@ var Split = &Builtin{
|
||||
types.Named("x", types.S).Description("string that is split"),
|
||||
types.Named("delimiter", types.S).Description("delimiter used for splitting"),
|
||||
),
|
||||
types.Named("ys", types.NewArray(nil, types.S)).Description("splitted parts"),
|
||||
types.Named("ys", types.NewArray(nil, types.S)).Description("split parts"),
|
||||
),
|
||||
Categories: stringsCat,
|
||||
}
|
||||
@@ -1247,7 +1247,7 @@ var Trim = &Builtin{
|
||||
|
||||
var TrimLeft = &Builtin{
|
||||
Name: "trim_left",
|
||||
Description: "Returns `value` with all leading instances of the `cutset` chartacters removed.",
|
||||
Description: "Returns `value` with all leading instances of the `cutset` characters removed.",
|
||||
Decl: types.NewFunction(
|
||||
types.Args(
|
||||
types.Named("value", types.S).Description("string to trim"),
|
||||
@@ -1273,7 +1273,7 @@ var TrimPrefix = &Builtin{
|
||||
|
||||
var TrimRight = &Builtin{
|
||||
Name: "trim_right",
|
||||
Description: "Returns `value` with all trailing instances of the `cutset` chartacters removed.",
|
||||
Description: "Returns `value` with all trailing instances of the `cutset` characters removed.",
|
||||
Decl: types.NewFunction(
|
||||
types.Args(
|
||||
types.Named("value", types.S).Description("string to trim"),
|
||||
@@ -1356,7 +1356,7 @@ var RenderTemplate = &Builtin{
|
||||
// Marked non-deterministic because it relies on RNG internally.
|
||||
var RandIntn = &Builtin{
|
||||
Name: "rand.intn",
|
||||
Description: "Returns a random integer between `0` and `n` (`n` exlusive). If `n` is `0`, then `y` is always `0`. For any given argument pair (`str`, `n`), the output will be consistent throughout a query evaluation.",
|
||||
Description: "Returns a random integer between `0` and `n` (`n` exclusive). If `n` is `0`, then `y` is always `0`. For any given argument pair (`str`, `n`), the output will be consistent throughout a query evaluation.",
|
||||
Decl: types.NewFunction(
|
||||
types.Args(
|
||||
types.Named("str", types.S),
|
||||
@@ -1750,7 +1750,7 @@ var JSONUnmarshal = &Builtin{
|
||||
types.Args(
|
||||
types.Named("x", types.S).Description("a JSON string"),
|
||||
),
|
||||
types.Named("y", types.A).Description("the term deseralized from `x`"),
|
||||
types.Named("y", types.A).Description("the term deserialized from `x`"),
|
||||
),
|
||||
Categories: encoding,
|
||||
}
|
||||
@@ -1914,7 +1914,7 @@ var YAMLUnmarshal = &Builtin{
|
||||
types.Args(
|
||||
types.Named("x", types.S).Description("a YAML string"),
|
||||
),
|
||||
types.Named("y", types.A).Description("the term deseralized from `x`"),
|
||||
types.Named("y", types.A).Description("the term deserialized from `x`"),
|
||||
),
|
||||
Categories: encoding,
|
||||
}
|
||||
@@ -1951,7 +1951,7 @@ var HexDecode = &Builtin{
|
||||
types.Args(
|
||||
types.Named("x", types.S).Description("a hex-encoded string"),
|
||||
),
|
||||
types.Named("y", types.S).Description("deseralized from `x`"),
|
||||
types.Named("y", types.S).Description("deserialized from `x`"),
|
||||
),
|
||||
Categories: encoding,
|
||||
}
|
||||
|
||||
5
vendor/github.com/open-policy-agent/opa/ast/check.go
generated
vendored
5
vendor/github.com/open-policy-agent/opa/ast/check.go
generated
vendored
@@ -60,7 +60,10 @@ func (tc *typeChecker) copy() *typeChecker {
|
||||
WithVarRewriter(tc.varRewriter).
|
||||
WithSchemaSet(tc.ss).
|
||||
WithAllowNet(tc.allowNet).
|
||||
WithInputType(tc.input)
|
||||
WithInputType(tc.input).
|
||||
WithAllowUndefinedFunctionCalls(tc.allowUndefinedFuncs).
|
||||
WithBuiltins(tc.builtins).
|
||||
WithRequiredCapabilities(tc.required)
|
||||
}
|
||||
|
||||
func (tc *typeChecker) WithRequiredCapabilities(c *Capabilities) *typeChecker {
|
||||
|
||||
2
vendor/github.com/open-policy-agent/opa/ast/index.go
generated
vendored
2
vendor/github.com/open-policy-agent/opa/ast/index.go
generated
vendored
@@ -494,7 +494,7 @@ func (node *trieNode) String() string {
|
||||
func (node *trieNode) append(prio [2]int, rule *Rule) {
|
||||
node.rules = append(node.rules, &ruleNode{prio, rule})
|
||||
|
||||
if node.values != nil {
|
||||
if node.values != nil && rule.Head.Value != nil {
|
||||
node.values.Add(rule.Head.Value)
|
||||
return
|
||||
}
|
||||
|
||||
20
vendor/github.com/open-policy-agent/opa/ast/parser.go
generated
vendored
20
vendor/github.com/open-policy-agent/opa/ast/parser.go
generated
vendored
@@ -50,6 +50,19 @@ func (v RegoVersion) Int() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (v RegoVersion) String() string {
|
||||
switch v {
|
||||
case RegoV0:
|
||||
return "v0"
|
||||
case RegoV1:
|
||||
return "v1"
|
||||
case RegoV0CompatV1:
|
||||
return "v0v1"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
func RegoVersionFromInt(i int) RegoVersion {
|
||||
if i == 1 {
|
||||
return RegoV1
|
||||
@@ -596,7 +609,12 @@ func (p *Parser) parseImport() *Import {
|
||||
|
||||
path := imp.Path.Value.(Ref)
|
||||
|
||||
if !RootDocumentNames.Contains(path[0]) && !FutureRootDocument.Equal(path[0]) && !RegoRootDocument.Equal(path[0]) {
|
||||
switch {
|
||||
case RootDocumentNames.Contains(path[0]):
|
||||
case FutureRootDocument.Equal(path[0]):
|
||||
case RegoRootDocument.Equal(path[0]):
|
||||
default:
|
||||
p.hint("if this is unexpected, try updating OPA")
|
||||
p.errorf(imp.Path.Location, "unexpected import path, must begin with one of: %v, got: %v",
|
||||
RootDocumentNames.Union(NewSet(FutureRootDocument, RegoRootDocument)),
|
||||
path[0])
|
||||
|
||||
12
vendor/github.com/open-policy-agent/opa/ast/policy.go
generated
vendored
12
vendor/github.com/open-policy-agent/opa/ast/policy.go
generated
vendored
@@ -570,7 +570,7 @@ func (pkg *Package) MarshalJSON() ([]byte, error) {
|
||||
}
|
||||
|
||||
// IsValidImportPath returns an error indicating if the import path is invalid.
|
||||
// If the import path is invalid, err is nil.
|
||||
// If the import path is valid, err is nil.
|
||||
func IsValidImportPath(v Value) (err error) {
|
||||
switch v := v.(type) {
|
||||
case Var:
|
||||
@@ -1034,16 +1034,22 @@ func (head *Head) setJSONOptions(opts astJSON.Options) {
|
||||
|
||||
func (head *Head) MarshalJSON() ([]byte, error) {
|
||||
var loc *Location
|
||||
if head.jsonOptions.MarshalOptions.IncludeLocation.Head {
|
||||
includeLoc := head.jsonOptions.MarshalOptions.IncludeLocation
|
||||
if includeLoc.Head {
|
||||
if head.Location != nil {
|
||||
loc = head.Location
|
||||
}
|
||||
|
||||
for _, term := range head.Reference {
|
||||
if term.Location != nil {
|
||||
term.jsonOptions.MarshalOptions.IncludeLocation.Term = includeLoc.Term
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(sr): we do this to override the rendering of `head.Reference`.
|
||||
// It's still what'll be used via the default means of encoding/json
|
||||
// for unmarshaling a json object into a Head struct!
|
||||
// NOTE(charlieegan3): we also need to optionally include the location
|
||||
type h Head
|
||||
return json.Marshal(struct {
|
||||
h
|
||||
|
||||
4843
vendor/github.com/open-policy-agent/opa/capabilities/v0.68.0.json
generated
vendored
Normal file
4843
vendor/github.com/open-policy-agent/opa/capabilities/v0.68.0.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
17
vendor/github.com/open-policy-agent/opa/format/format.go
generated
vendored
17
vendor/github.com/open-policy-agent/opa/format/format.go
generated
vendored
@@ -28,6 +28,9 @@ type Opts struct {
|
||||
|
||||
// RegoVersion is the version of Rego to format code for.
|
||||
RegoVersion ast.RegoVersion
|
||||
|
||||
// ParserOptions is the parser options used when parsing the module to be formatted.
|
||||
ParserOptions *ast.ParserOptions
|
||||
}
|
||||
|
||||
// defaultLocationFile is the file name used in `Ast()` for terms
|
||||
@@ -43,11 +46,15 @@ func Source(filename string, src []byte) ([]byte, error) {
|
||||
}
|
||||
|
||||
func SourceWithOpts(filename string, src []byte, opts Opts) ([]byte, error) {
|
||||
parserOpts := ast.ParserOptions{}
|
||||
if opts.RegoVersion == ast.RegoV1 {
|
||||
// If the rego version is V1, wee need to parse it as such, to allow for future keywords not being imported.
|
||||
// Otherwise, we'll default to RegoV0
|
||||
parserOpts.RegoVersion = ast.RegoV1
|
||||
var parserOpts ast.ParserOptions
|
||||
if opts.ParserOptions != nil {
|
||||
parserOpts = *opts.ParserOptions
|
||||
} else {
|
||||
if opts.RegoVersion == ast.RegoV1 {
|
||||
// If the rego version is V1, we need to parse it as such, to allow for future keywords not being imported.
|
||||
// Otherwise, we'll default to RegoV0
|
||||
parserOpts.RegoVersion = ast.RegoV1
|
||||
}
|
||||
}
|
||||
|
||||
module, err := ast.ParseModuleWithOpts(filename, string(src), parserOpts)
|
||||
|
||||
31
vendor/github.com/open-policy-agent/opa/loader/loader.go
generated
vendored
31
vendor/github.com/open-policy-agent/opa/loader/loader.go
generated
vendored
@@ -247,6 +247,10 @@ func (fl fileLoader) AsBundle(path string) (*bundle.Bundle, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := checkForUNCPath(path); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var bundleLoader bundle.DirectoryLoader
|
||||
var isDir bool
|
||||
if fl.reader != nil {
|
||||
@@ -254,6 +258,7 @@ func (fl fileLoader) AsBundle(path string) (*bundle.Bundle, error) {
|
||||
} else {
|
||||
bundleLoader, isDir, err = GetBundleDirectoryLoaderFS(fl.fsys, path, fl.filter)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -303,6 +308,10 @@ func GetBundleDirectoryLoaderFS(fsys fs.FS, path string, filter Filter) (bundle.
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
if err := checkForUNCPath(path); err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
var fi fs.FileInfo
|
||||
if fsys != nil {
|
||||
fi, err = fs.Stat(fsys, path)
|
||||
@@ -663,12 +672,18 @@ func allRec(fsys fs.FS, path string, filter Filter, errors *Errors, loaded *Resu
|
||||
return
|
||||
}
|
||||
|
||||
if err := checkForUNCPath(path); err != nil {
|
||||
errors.add(err)
|
||||
return
|
||||
}
|
||||
|
||||
var info fs.FileInfo
|
||||
if fsys != nil {
|
||||
info, err = fs.Stat(fsys, path)
|
||||
} else {
|
||||
info, err = os.Stat(path)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
errors.add(err)
|
||||
return
|
||||
@@ -804,3 +819,19 @@ func makeDir(path []string, x interface{}) (map[string]interface{}, bool) {
|
||||
}
|
||||
return makeDir(path[:len(path)-1], map[string]interface{}{path[len(path)-1]: x})
|
||||
}
|
||||
|
||||
// isUNC reports whether path is a UNC path.
|
||||
func isUNC(path string) bool {
|
||||
return len(path) > 1 && isSlash(path[0]) && isSlash(path[1])
|
||||
}
|
||||
|
||||
func isSlash(c uint8) bool {
|
||||
return c == '\\' || c == '/'
|
||||
}
|
||||
|
||||
func checkForUNCPath(path string) error {
|
||||
if isUNC(path) {
|
||||
return fmt.Errorf("UNC path read is not allowed: %s", path)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
11
vendor/github.com/open-policy-agent/opa/logging/logging.go
generated
vendored
11
vendor/github.com/open-policy-agent/opa/logging/logging.go
generated
vendored
@@ -243,6 +243,17 @@ func FromContext(ctx context.Context) (*RequestContext, bool) {
|
||||
return requestContext, ok
|
||||
}
|
||||
|
||||
const httpReqCtxKey = requestContextKey("http-request-context-key")
|
||||
|
||||
func WithHTTPRequestContext(parent context.Context, val *HTTPRequestContext) context.Context {
|
||||
return context.WithValue(parent, httpReqCtxKey, val)
|
||||
}
|
||||
|
||||
func HTTPRequestContextFromContext(ctx context.Context) (*HTTPRequestContext, bool) {
|
||||
requestContext, ok := ctx.Value(httpReqCtxKey).(*HTTPRequestContext)
|
||||
return requestContext, ok
|
||||
}
|
||||
|
||||
const decisionCtxKey = requestContextKey("decision_id")
|
||||
|
||||
func WithDecisionID(parent context.Context, id string) context.Context {
|
||||
|
||||
28
vendor/github.com/open-policy-agent/opa/plugins/rest/aws.go
generated
vendored
28
vendor/github.com/open-policy-agent/opa/plugins/rest/aws.go
generated
vendored
@@ -30,8 +30,10 @@ const (
|
||||
ec2DefaultTokenPath = "http://169.254.169.254/latest/api/token"
|
||||
|
||||
// ref. https://docs.aws.amazon.com/AmazonECS/latest/userguide/task-iam-roles.html
|
||||
ecsDefaultCredServicePath = "http://169.254.170.2"
|
||||
ecsRelativePathEnvVar = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
|
||||
ecsDefaultCredServicePath = "http://169.254.170.2"
|
||||
ecsRelativePathEnvVar = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
|
||||
ecsFullPathEnvVar = "AWS_CONTAINER_CREDENTIALS_FULL_URI"
|
||||
ecsAuthorizationTokenEnvVar = "AWS_CONTAINER_AUTHORIZATION_TOKEN"
|
||||
|
||||
// ref. https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html
|
||||
stsDefaultDomain = "amazonaws.com"
|
||||
@@ -211,7 +213,12 @@ func (cs *awsMetadataCredentialService) urlForMetadataService() (string, error)
|
||||
// otherwise, check environment to see if it looks like we're in an ECS
|
||||
// container (with implied role association)
|
||||
if isECS() {
|
||||
return ecsDefaultCredServicePath + os.Getenv(ecsRelativePathEnvVar), nil
|
||||
// first check if the relative env var exists; if so we use that otherwise we
|
||||
// use the "full" var
|
||||
if _, relativeExists := os.LookupEnv(ecsRelativePathEnvVar); relativeExists {
|
||||
return ecsDefaultCredServicePath + os.Getenv(ecsRelativePathEnvVar), nil
|
||||
}
|
||||
return os.Getenv(ecsFullPathEnvVar), nil
|
||||
}
|
||||
// if there's no role name and we don't appear to have a path to the
|
||||
// ECS container service, then the configuration is invalid
|
||||
@@ -267,6 +274,16 @@ func (cs *awsMetadataCredentialService) refreshFromService(ctx context.Context)
|
||||
return errors.New("unable to construct metadata HTTP request: " + err.Error())
|
||||
}
|
||||
|
||||
// if using the AWS_CONTAINER_CREDENTIALS_FULL_URI variable, we need to associate the token
|
||||
// to the request
|
||||
if _, useFullPath := os.LookupEnv(ecsFullPathEnvVar); useFullPath {
|
||||
token, tokenExists := os.LookupEnv(ecsAuthorizationTokenEnvVar)
|
||||
if !tokenExists {
|
||||
return errors.New("unable to get ECS metadata authorization token")
|
||||
}
|
||||
req.Header.Set("Authorization", token)
|
||||
}
|
||||
|
||||
// if in the EC2 environment, we will use IMDSv2, which requires a session cookie from a
|
||||
// PUT request on the token endpoint before it will give the credentials, this provides
|
||||
// protection from SSRF attacks
|
||||
@@ -604,8 +621,9 @@ func (cs *awsWebIdentityCredentialService) credentials(ctx context.Context) (aws
|
||||
|
||||
func isECS() bool {
|
||||
// the special relative path URI is set by the container agent in the ECS environment only
|
||||
_, isECS := os.LookupEnv(ecsRelativePathEnvVar)
|
||||
return isECS
|
||||
_, isECSRelative := os.LookupEnv(ecsRelativePathEnvVar)
|
||||
_, isECSFull := os.LookupEnv(ecsFullPathEnvVar)
|
||||
return isECSRelative || isECSFull
|
||||
}
|
||||
|
||||
// ecrAuthPlugin authorizes requests to AWS ECR.
|
||||
|
||||
12
vendor/github.com/open-policy-agent/opa/rego/rego.go
generated
vendored
12
vendor/github.com/open-policy-agent/opa/rego/rego.go
generated
vendored
@@ -124,6 +124,7 @@ type EvalContext struct {
|
||||
printHook print.Hook
|
||||
capabilities *ast.Capabilities
|
||||
strictBuiltinErrors bool
|
||||
virtualCache topdown.VirtualCache
|
||||
}
|
||||
|
||||
func (e *EvalContext) RawInput() *interface{} {
|
||||
@@ -342,6 +343,14 @@ func EvalPrintHook(ph print.Hook) EvalOption {
|
||||
}
|
||||
}
|
||||
|
||||
// EvalVirtualCache sets the topdown.VirtualCache to use for evaluation. This is
|
||||
// optional, and if not set, the default cache is used.
|
||||
func EvalVirtualCache(vc topdown.VirtualCache) EvalOption {
|
||||
return func(e *EvalContext) {
|
||||
e.virtualCache = vc
|
||||
}
|
||||
}
|
||||
|
||||
func (pq preparedQuery) Modules() map[string]*ast.Module {
|
||||
mods := make(map[string]*ast.Module)
|
||||
|
||||
@@ -2101,7 +2110,8 @@ func (r *Rego) eval(ctx context.Context, ectx *EvalContext) (ResultSet, error) {
|
||||
WithBuiltinErrorList(r.builtinErrorList).
|
||||
WithSeed(ectx.seed).
|
||||
WithPrintHook(ectx.printHook).
|
||||
WithDistributedTracingOpts(r.distributedTacingOpts)
|
||||
WithDistributedTracingOpts(r.distributedTacingOpts).
|
||||
WithVirtualCache(ectx.virtualCache)
|
||||
|
||||
if !ectx.time.IsZero() {
|
||||
q = q.WithTime(ectx.time)
|
||||
|
||||
45
vendor/github.com/open-policy-agent/opa/topdown/cache.go
generated
vendored
45
vendor/github.com/open-policy-agent/opa/topdown/cache.go
generated
vendored
@@ -9,6 +9,29 @@ import (
|
||||
"github.com/open-policy-agent/opa/util"
|
||||
)
|
||||
|
||||
// VirtualCache defines the interface for a cache that stores the results of
|
||||
// evaluated virtual documents (rules).
|
||||
// The cache is a stack of frames, where each frame is a mapping from references
|
||||
// to values.
|
||||
type VirtualCache interface {
|
||||
// Push pushes a new, empty frame of value mappings onto the stack.
|
||||
Push()
|
||||
|
||||
// Pop pops the top frame of value mappings from the stack, removing all associated entries.
|
||||
Pop()
|
||||
|
||||
// Get returns the value associated with the given reference. The second return value
|
||||
// indicates whether the reference has a recorded 'undefined' result.
|
||||
Get(ref ast.Ref) (*ast.Term, bool)
|
||||
|
||||
// Put associates the given reference with the given value. If the value is nil, the reference
|
||||
// is marked as having an 'undefined' result.
|
||||
Put(ref ast.Ref, value *ast.Term)
|
||||
|
||||
// Keys returns the set of keys that have been cached for the active frame.
|
||||
Keys() []ast.Ref
|
||||
}
|
||||
|
||||
type virtualCache struct {
|
||||
stack []*virtualCacheElem
|
||||
}
|
||||
@@ -19,7 +42,7 @@ type virtualCacheElem struct {
|
||||
undefined bool
|
||||
}
|
||||
|
||||
func newVirtualCache() *virtualCache {
|
||||
func NewVirtualCache() VirtualCache {
|
||||
cache := &virtualCache{}
|
||||
cache.Push()
|
||||
return cache
|
||||
@@ -77,6 +100,26 @@ func (c *virtualCache) Put(ref ast.Ref, value *ast.Term) {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *virtualCache) Keys() []ast.Ref {
|
||||
node := c.stack[len(c.stack)-1]
|
||||
return keysRecursive(nil, node)
|
||||
}
|
||||
|
||||
func keysRecursive(root ast.Ref, node *virtualCacheElem) []ast.Ref {
|
||||
var keys []ast.Ref
|
||||
node.children.Iter(func(k, v util.T) bool {
|
||||
ref := root.Append(k.(*ast.Term))
|
||||
if v.(*virtualCacheElem).value != nil {
|
||||
keys = append(keys, ref)
|
||||
}
|
||||
if v.(*virtualCacheElem).children.Len() > 0 {
|
||||
keys = append(keys, keysRecursive(ref, v.(*virtualCacheElem))...)
|
||||
}
|
||||
return false
|
||||
})
|
||||
return keys
|
||||
}
|
||||
|
||||
func newVirtualCacheElem() *virtualCacheElem {
|
||||
return &virtualCacheElem{children: newVirtualCacheHashMap()}
|
||||
}
|
||||
|
||||
161
vendor/github.com/open-policy-agent/opa/topdown/eval.go
generated
vendored
161
vendor/github.com/open-policy-agent/opa/topdown/eval.go
generated
vendored
@@ -90,7 +90,7 @@ type eval struct {
|
||||
builtinCache builtins.Cache
|
||||
ndBuiltinCache builtins.NDBCache
|
||||
functionMocks *functionMocksStack
|
||||
virtualCache *virtualCache
|
||||
virtualCache VirtualCache
|
||||
comprehensionCache *comprehensionCache
|
||||
interQueryBuiltinCache cache.InterQueryCache
|
||||
saveSet *saveSet
|
||||
@@ -2407,6 +2407,15 @@ type evalVirtualPartialCacheHint struct {
|
||||
full bool
|
||||
}
|
||||
|
||||
func (h *evalVirtualPartialCacheHint) keyWithoutScope() ast.Ref {
|
||||
if h.key != nil {
|
||||
if _, ok := h.key[len(h.key)-1].Value.(vcKeyScope); ok {
|
||||
return h.key[:len(h.key)-1]
|
||||
}
|
||||
}
|
||||
return h.key
|
||||
}
|
||||
|
||||
func (e evalVirtualPartial) eval(iter unifyIterator) error {
|
||||
|
||||
unknown := e.e.unknown(e.ref[:e.pos+1], e.bindings)
|
||||
@@ -2485,7 +2494,7 @@ func (e evalVirtualPartial) evalEachRule(iter unifyIterator, unknown bool) error
|
||||
}
|
||||
|
||||
if hint.key != nil {
|
||||
if v, err := result.Value.Find(hint.key[e.pos+1:]); err == nil && v != nil {
|
||||
if v, err := result.Value.Find(hint.keyWithoutScope()[e.pos+1:]); err == nil && v != nil {
|
||||
e.e.virtualCache.Put(hint.key, ast.NewTerm(v))
|
||||
}
|
||||
}
|
||||
@@ -2832,6 +2841,8 @@ func (e evalVirtualPartial) evalCache(iter unifyIterator) (evalVirtualPartialCac
|
||||
plugged := e.bindings.Plug(e.ref[e.pos+1])
|
||||
|
||||
if _, ok := plugged.Value.(ast.Var); ok {
|
||||
// Note: we might have additional opportunity to optimize here, if we consider that ground values
|
||||
// right of e.pos could create a smaller eval "scope" through ref bi-unification before evaluating rules.
|
||||
hint.full = true
|
||||
hint.key = e.plugged[:e.pos+1]
|
||||
e.e.instr.counterIncr(evalOpVirtualCacheMiss)
|
||||
@@ -2840,19 +2851,76 @@ func (e evalVirtualPartial) evalCache(iter unifyIterator) (evalVirtualPartialCac
|
||||
|
||||
m := maxRefLength(e.ir.Rules, len(e.ref))
|
||||
|
||||
// Creating the hint key by walking the ref and plugging vars until we hit a non-ground term.
|
||||
// Any ground term right of this point will affect the scope of evaluation by ref unification,
|
||||
// so we create a virtual-cache scope key to qualify the result stored in the cache.
|
||||
//
|
||||
// E.g. given the following rule:
|
||||
//
|
||||
// package example
|
||||
//
|
||||
// a[x][y][z] := x + y + z if {
|
||||
// some x in [1, 2]
|
||||
// some y in [3, 4]
|
||||
// some z in [5, 6]
|
||||
// }
|
||||
//
|
||||
// and the following ref (1):
|
||||
//
|
||||
// data.example.a[1][_][5]
|
||||
//
|
||||
// then the hint key will be:
|
||||
//
|
||||
// data.example.a[1][<_,5>]
|
||||
//
|
||||
// where <_,5> is the scope of the pre-eval unification.
|
||||
// This part does not contribute to the "location" of the cached data.
|
||||
//
|
||||
// The following ref (2):
|
||||
//
|
||||
// data.example.a[1][_][6]
|
||||
//
|
||||
// will produce the same hint key "location" 'data.example.a[1]', but a different scope component
|
||||
// '<_,6>', which will create a different entry in the cache.
|
||||
scoping := false
|
||||
hintKeyEnd := 0
|
||||
for i := e.pos + 1; i < m; i++ {
|
||||
plugged = e.bindings.Plug(e.ref[i])
|
||||
|
||||
if !plugged.IsGround() {
|
||||
break
|
||||
if plugged.IsGround() && !scoping {
|
||||
hintKeyEnd = i
|
||||
hint.key = append(e.plugged[:i], plugged)
|
||||
} else {
|
||||
scoping = true
|
||||
hl := len(hint.key)
|
||||
if hl == 0 {
|
||||
break
|
||||
}
|
||||
if scope, ok := hint.key[hl-1].Value.(vcKeyScope); ok {
|
||||
scope.Ref = append(scope.Ref, plugged)
|
||||
hint.key[len(hint.key)-1] = ast.NewTerm(scope)
|
||||
} else {
|
||||
scope = vcKeyScope{}
|
||||
scope.Ref = append(scope.Ref, plugged)
|
||||
hint.key = append(hint.key, ast.NewTerm(scope))
|
||||
}
|
||||
}
|
||||
|
||||
hint.key = append(e.plugged[:i], plugged)
|
||||
|
||||
if cached, _ := e.e.virtualCache.Get(hint.key); cached != nil {
|
||||
e.e.instr.counterIncr(evalOpVirtualCacheHit)
|
||||
hint.hit = true
|
||||
return hint, e.evalTerm(iter, i+1, cached, e.bindings)
|
||||
return hint, e.evalTerm(iter, hintKeyEnd+1, cached, e.bindings)
|
||||
}
|
||||
}
|
||||
|
||||
if hl := len(hint.key); hl > 0 {
|
||||
if scope, ok := hint.key[hl-1].Value.(vcKeyScope); ok {
|
||||
scope = scope.reduce()
|
||||
if scope.empty() {
|
||||
hint.key = hint.key[:hl-1]
|
||||
} else {
|
||||
hint.key[hl-1].Value = scope
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2861,6 +2929,85 @@ func (e evalVirtualPartial) evalCache(iter unifyIterator) (evalVirtualPartialCac
|
||||
return hint, nil
|
||||
}
|
||||
|
||||
// vcKeyScope represents the scoping that pre-rule-eval ref unification imposes on a virtual cache entry.
|
||||
type vcKeyScope struct {
|
||||
ast.Ref
|
||||
}
|
||||
|
||||
func (q vcKeyScope) Compare(other ast.Value) int {
|
||||
if q2, ok := other.(vcKeyScope); ok {
|
||||
r1 := q.Ref
|
||||
r2 := q2.Ref
|
||||
if len(r1) != len(r2) {
|
||||
return -1
|
||||
}
|
||||
|
||||
for i := range r1 {
|
||||
_, v1IsVar := r1[i].Value.(ast.Var)
|
||||
_, v2IsVar := r2[i].Value.(ast.Var)
|
||||
if v1IsVar && v2IsVar {
|
||||
continue
|
||||
}
|
||||
if r1[i].Value.Compare(r2[i].Value) != 0 {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
func (vcKeyScope) Find(ast.Ref) (ast.Value, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (q vcKeyScope) Hash() int {
|
||||
var hash int
|
||||
for _, v := range q.Ref {
|
||||
if _, ok := v.Value.(ast.Var); ok {
|
||||
// all vars are equal
|
||||
hash++
|
||||
} else {
|
||||
hash += v.Value.Hash()
|
||||
}
|
||||
}
|
||||
return hash
|
||||
}
|
||||
|
||||
func (q vcKeyScope) IsGround() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (q vcKeyScope) String() string {
|
||||
buf := make([]string, 0, len(q.Ref))
|
||||
for _, t := range q.Ref {
|
||||
if _, ok := t.Value.(ast.Var); ok {
|
||||
buf = append(buf, "_")
|
||||
} else {
|
||||
buf = append(buf, t.String())
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("<%s>", strings.Join(buf, ","))
|
||||
}
|
||||
|
||||
// reduce removes vars from the tail of the ref.
|
||||
func (q vcKeyScope) reduce() vcKeyScope {
|
||||
ref := q.Ref.Copy()
|
||||
var i int
|
||||
for i = len(q.Ref) - 1; i >= 0; i-- {
|
||||
if _, ok := q.Ref[i].Value.(ast.Var); !ok {
|
||||
break
|
||||
}
|
||||
}
|
||||
ref = ref[:i+1]
|
||||
return vcKeyScope{ref}
|
||||
}
|
||||
|
||||
func (q vcKeyScope) empty() bool {
|
||||
return len(q.Ref) == 0
|
||||
}
|
||||
|
||||
func getNestedObject(ref ast.Ref, rootObj *ast.Object, b *bindings, l *ast.Location) (*ast.Object, error) {
|
||||
current := rootObj
|
||||
for _, term := range ref {
|
||||
|
||||
30
vendor/github.com/open-policy-agent/opa/topdown/query.go
generated
vendored
30
vendor/github.com/open-policy-agent/opa/topdown/query.go
generated
vendored
@@ -58,6 +58,7 @@ type Query struct {
|
||||
strictObjects bool
|
||||
printHook print.Hook
|
||||
tracingOpts tracing.Options
|
||||
virtualCache VirtualCache
|
||||
}
|
||||
|
||||
// Builtin represents a built-in function that queries can call.
|
||||
@@ -291,6 +292,13 @@ func (q *Query) WithStrictObjects(yes bool) *Query {
|
||||
return q
|
||||
}
|
||||
|
||||
// WithVirtualCache sets the VirtualCache to use during evaluation. This is
|
||||
// optional, and if not set, the default cache is used.
|
||||
func (q *Query) WithVirtualCache(vc VirtualCache) *Query {
|
||||
q.virtualCache = vc
|
||||
return q
|
||||
}
|
||||
|
||||
// PartialRun executes partial evaluation on the query with respect to unknown
|
||||
// values. Partial evaluation attempts to evaluate as much of the query as
|
||||
// possible without requiring values for the unknowns set on the query. The
|
||||
@@ -311,8 +319,17 @@ func (q *Query) PartialRun(ctx context.Context) (partials []ast.Body, support []
|
||||
if q.metrics == nil {
|
||||
q.metrics = metrics.New()
|
||||
}
|
||||
|
||||
f := &queryIDFactory{}
|
||||
b := newBindings(0, q.instr)
|
||||
|
||||
var vc VirtualCache
|
||||
if q.virtualCache != nil {
|
||||
vc = q.virtualCache
|
||||
} else {
|
||||
vc = NewVirtualCache()
|
||||
}
|
||||
|
||||
e := &eval{
|
||||
ctx: ctx,
|
||||
metrics: q.metrics,
|
||||
@@ -340,7 +357,7 @@ func (q *Query) PartialRun(ctx context.Context) (partials []ast.Body, support []
|
||||
functionMocks: newFunctionMocksStack(),
|
||||
interQueryBuiltinCache: q.interQueryBuiltinCache,
|
||||
ndBuiltinCache: q.ndBuiltinCache,
|
||||
virtualCache: newVirtualCache(),
|
||||
virtualCache: vc,
|
||||
comprehensionCache: newComprehensionCache(),
|
||||
saveSet: newSaveSet(q.unknowns, b, q.instr),
|
||||
saveStack: newSaveStack(),
|
||||
@@ -488,7 +505,16 @@ func (q *Query) Iter(ctx context.Context, iter func(QueryResult) error) error {
|
||||
if q.metrics == nil {
|
||||
q.metrics = metrics.New()
|
||||
}
|
||||
|
||||
f := &queryIDFactory{}
|
||||
|
||||
var vc VirtualCache
|
||||
if q.virtualCache != nil {
|
||||
vc = q.virtualCache
|
||||
} else {
|
||||
vc = NewVirtualCache()
|
||||
}
|
||||
|
||||
e := &eval{
|
||||
ctx: ctx,
|
||||
metrics: q.metrics,
|
||||
@@ -516,7 +542,7 @@ func (q *Query) Iter(ctx context.Context, iter func(QueryResult) error) error {
|
||||
functionMocks: newFunctionMocksStack(),
|
||||
interQueryBuiltinCache: q.interQueryBuiltinCache,
|
||||
ndBuiltinCache: q.ndBuiltinCache,
|
||||
virtualCache: newVirtualCache(),
|
||||
virtualCache: vc,
|
||||
comprehensionCache: newComprehensionCache(),
|
||||
genvarprefix: q.genvarprefix,
|
||||
runtime: q.runtime,
|
||||
|
||||
49
vendor/github.com/open-policy-agent/opa/topdown/tokens.go
generated
vendored
49
vendor/github.com/open-policy-agent/opa/topdown/tokens.go
generated
vendored
@@ -720,8 +720,10 @@ func (constraints *tokenConstraints) validAudience(aud ast.Value) bool {
|
||||
|
||||
// JWT algorithms
|
||||
|
||||
type tokenVerifyFunction func(key interface{}, hash crypto.Hash, payload []byte, signature []byte) error
|
||||
type tokenVerifyAsymmetricFunction func(key interface{}, hash crypto.Hash, digest []byte, signature []byte) error
|
||||
type (
|
||||
tokenVerifyFunction func(key interface{}, hash crypto.Hash, payload []byte, signature []byte) error
|
||||
tokenVerifyAsymmetricFunction func(key interface{}, hash crypto.Hash, digest []byte, signature []byte) error
|
||||
)
|
||||
|
||||
// jwtAlgorithm describes a JWS 'alg' value
|
||||
type tokenAlgorithm struct {
|
||||
@@ -912,7 +914,6 @@ func (header *tokenHeader) valid() bool {
|
||||
}
|
||||
|
||||
func commonBuiltinJWTEncodeSign(bctx BuiltinContext, inputHeaders, jwsPayload, jwkSrc string, iter func(*ast.Term) error) error {
|
||||
|
||||
keys, err := jwk.ParseString(jwkSrc)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -946,21 +947,51 @@ func commonBuiltinJWTEncodeSign(bctx BuiltinContext, inputHeaders, jwsPayload, j
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return iter(ast.StringTerm(string(jwsCompact)))
|
||||
|
||||
return iter(ast.StringTerm(string(jwsCompact)))
|
||||
}
|
||||
|
||||
func builtinJWTEncodeSign(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
inputHeadersAsJSON, err := ast.JSON(operands[0].Value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to prepare JWT headers for marshalling: %v", err)
|
||||
}
|
||||
|
||||
inputHeaders := operands[0].String()
|
||||
jwsPayload := operands[1].String()
|
||||
jwkSrc := operands[2].String()
|
||||
return commonBuiltinJWTEncodeSign(bctx, inputHeaders, jwsPayload, jwkSrc, iter)
|
||||
inputHeadersBs, err := json.Marshal(inputHeadersAsJSON)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal JWT headers: %v", err)
|
||||
}
|
||||
|
||||
payloadAsJSON, err := ast.JSON(operands[1].Value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to prepare JWT payload for marshalling: %v", err)
|
||||
}
|
||||
|
||||
payloadBs, err := json.Marshal(payloadAsJSON)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal JWT payload: %v", err)
|
||||
}
|
||||
|
||||
signatureAsJSON, err := ast.JSON(operands[2].Value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to prepare JWT signature for marshalling: %v", err)
|
||||
}
|
||||
|
||||
signatureBs, err := json.Marshal(signatureAsJSON)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal JWT signature: %v", err)
|
||||
}
|
||||
|
||||
return commonBuiltinJWTEncodeSign(
|
||||
bctx,
|
||||
string(inputHeadersBs),
|
||||
string(payloadBs),
|
||||
string(signatureBs),
|
||||
iter,
|
||||
)
|
||||
}
|
||||
|
||||
func builtinJWTEncodeSignRaw(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
|
||||
jwkSrc, err := builtins.StringOperand(operands[2].Value, 3)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
5
vendor/github.com/open-policy-agent/opa/topdown/trace.go
generated
vendored
5
vendor/github.com/open-policy-agent/opa/topdown/trace.go
generated
vendored
@@ -94,6 +94,11 @@ type Event struct {
|
||||
localVirtualCacheSnapshot *ast.ValueMap
|
||||
}
|
||||
|
||||
func (evt *Event) WithInput(input *ast.Term) *Event {
|
||||
evt.input = input
|
||||
return evt
|
||||
}
|
||||
|
||||
// HasRule returns true if the Event contains an ast.Rule.
|
||||
func (evt *Event) HasRule() bool {
|
||||
_, ok := evt.Node.(*ast.Rule)
|
||||
|
||||
2
vendor/github.com/open-policy-agent/opa/version/version.go
generated
vendored
2
vendor/github.com/open-policy-agent/opa/version/version.go
generated
vendored
@@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
// Version is the canonical version of OPA.
|
||||
var Version = "0.67.1"
|
||||
var Version = "0.68.0"
|
||||
|
||||
// GoVersion is the version of Go this was built with
|
||||
var GoVersion = runtime.Version()
|
||||
|
||||
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@@ -1533,7 +1533,7 @@ github.com/onsi/gomega/matchers/support/goraph/edge
|
||||
github.com/onsi/gomega/matchers/support/goraph/node
|
||||
github.com/onsi/gomega/matchers/support/goraph/util
|
||||
github.com/onsi/gomega/types
|
||||
# github.com/open-policy-agent/opa v0.67.1
|
||||
# github.com/open-policy-agent/opa v0.68.0
|
||||
## explicit; go 1.21
|
||||
github.com/open-policy-agent/opa/ast
|
||||
github.com/open-policy-agent/opa/ast/internal/scanner
|
||||
|
||||
Reference in New Issue
Block a user