首页 > 解决方案 > 匹配正则表达式

问题描述

试图找出下面的两个问题(我是 rego 新手,所以这是第一次通过)我有两个问题要解决,下面只是第一个尝试。

  1. 验证输入 uri 是否存在于此 appid 的数据中
  2. 获取与输入请求匹配的对象(未尝试过,但提及以防它影响解决方案#1的方法)

我有这样的data.json;

{
   "applications": {
        "99999-999999999999-9999999-99999": {
            "route": {
                "^/myapi/1/beans$": {
                    "GET": {
                        "bean-class": [
                            "Big beans"
                        ]
                    }
                },
                "^/myapi/1/peas$": {
                    "POST": {
                        "pea-class": [
                            "Small peas"
                        ]
                    }
                }
            }
        },
        "111111-999911111199-11111-11111": {
            "route": {
                "^/myapi/1/beans$": {
                    "GET": {
                        "bean-class": [
                            "Big beans"
                        ]
                    }
                }
        }
    }
}

输入是;

{
    "appid": "99999-999999999999-9999999-99999",
    "uri": "/myapi/1/beans"
}

雷戈;

violation["route-not-found"] {
    some key
    data.applications[input.appid].route[key]
    m := has_match(key, input.uri)
    not m
}

has_match(pattern, uri) = true {
    matched := regex.match(pattern, uri)
    matched == true 
} else = false { true }

以上总是返回false。如果我在违规范围内运行代码,我可以看到前 3 行迭代整个路由集并显示匹配路由的“m”为真。运行所有 4 行表明迭代在匹配时停止,但是当当然没有时,“not”会触发违规。我似乎无法弄清楚如何检查数据中的所有值并在找到匹配项时返回错误(错误违规)。

我的问题的第二部分是如何从数据中获取匹配的对象?我需要对该对象进行进一步验证,因此需要掌握它,而不仅仅是知道它存在。如果这意味着它在另一个“违规”政策中很高兴,但由于我不得不将正则表达式移到一个函数中,我似乎无法获得如何获得匹配的密钥?

有什么想法吗?我敢肯定这只是新手语法问题,只是将文档转变为工作策略的早期阶段。

更新:纠正错字

标签: open-policy-agent

解决方案


您的共享和策略存在一些不一致data.json,我认为在编译这个问题时这是一个复制编辑疏忽:applications如果您通过 .data.json 访问它,它需要一个密钥data.applications[input.id]。这input.id符合你的input.json,它说id,不是appid

撇开这些不谈,我先稍微简化一下政策:


# returns all routes that match the app id, but not input.uri
violation[route] {
    some route
    data.applications[input.id].route[route]
    not regex.match(route, input.uri)
}

这是一个称为违规的部分集合,它将为您的数据中匹配input.id但不匹配请求路径正则表达式的每个路由都有一个条目。看到这个游乐场


对于您的第二个问题,如果您想验证匹配的更多属性,最好将其颠倒为允许规则:仅当数据中存在匹配规则时才允许请求,对于应用程序 ID问题:

allow = extra {
    some route
    request := data.applications[input.id].route[route]
    regex.match(route, input.uri)
    extra := request[input.method] # fails if request doesn't have a such a key
}

看到这个游乐场。

请注意,我只是allow = extra为了说明而添加了一个普通的allow规则:

allow {
  # ...
}

推荐阅读