OPA中如何合并多角色权限对象的数组字段生成单权限对象
OPA中合并多角色权限对象的数组字段实现方法
当输入包含多角色且存在相同action+object的权限项时,要合并权限对象中的数组字段生成单个结果,可以通过先收集所有匹配权限,再自定义合并逻辑实现,具体步骤如下:
1. 收集所有匹配的权限项
先保留原有规则收集所有符合条件的权限,避免因多匹配项报错:
package policies import data.role_permissions // 收集所有匹配输入action和object的权限项 matching_perms[permission] { role := input.roles[_] permissions := role_permissions[role] permission := permissions[_] permission.action == input.action permission.object == input.object }
2. 编写合并规则生成单个权限对象
新增规则提取统一的基础字段(action、object),并合并数组字段(如levels):
// 生成合并后的单个权限对象 merged_permission := merged { // 提取统一的基础字段(所有匹配项的action/object一致,取任意一个即可) first_perm := matching_perms[_] base_fields := { "action": first_perm.action, "object": first_perm.object } // 合并levels数组:收集所有权限项中的levels元素(集合自动去重,如需保留重复用[]替代{}) all_levels := { level | perm := matching_perms[_]; level := perm.levels[_] } // 合并基础字段与数组字段 merged := merge(base_fields, { "levels": array(all_levels) }) }
代码说明
- 基础字段提取:所有匹配项都符合
input.action和input.object条件,因此任意取一个匹配项的对应字段即可保证一致性。 - 数组合并逻辑:
- 用集合推导式
{ level | ... }收集所有levels元素,自动去重;如果不需要去重,改用数组推导式[ level | ... ]。 - 用
array()将集合转为数组(OPA中集合是无序的,若需要严格保持原顺序,可通过遍历拼接实现)。
- 用集合推导式
- 合并对象:使用OPA内置的
merge函数将基础字段和合并后的数组字段组合成最终对象。
3. 测试示例
针对你提供的测试数据:
// data.json { "role_permissions": { "a": [{ "action": "read", "object": "threats", "levels": [1, 2, 3] }], "b": [{ "action": "read", "object": "threats", "levels": [4, 5] }] } } // input { "roles": ["a", "b"], "action": "read", "object": "threats" }
执行后merged_permission会输出:
{ "action": "read", "object": "threats", "levels": [1,2,3,4,5] }
扩展说明
如果有多个需要合并的数组字段(如scopes),只需重复数组收集逻辑即可:
all_scopes := { scope | perm := matching_perms[_]; scope := perm.scopes[_] } merged := merge(base_fields, { "levels": array(all_levels), "scopes": array(all_scopes) })
内容的提问来源于stack exchange,提问作者Jason
相关产品推荐
相关产品推荐

