Reputation: 366
I'm trying to check if a user have certain permission conceit given a subject and action to check against, sadly I'm unable to make it work, this is the REGO file:
package monolith.tiene_permiso
default permitir = false
permitir {
es_admin
}
permitir {
# Find grants for the user.
some grant
usuario_tiene_permitido[grant]
# Check if the grant permits the action.
input.permiso.accion == grant.accion
input.permiso.sujeto == grant.sujeto
}
es_admin {
some key
input.permisos[_][key]
key == data.admin_name
}
usuario_tiene_permitido[accion] {
some j
accion := input.permisos[_][input.permiso.sujeto][j]
}
And this is the unit test, this reflects how the inputs are provided from the Go code:
package monolith.tiene_permiso
admin_name = {"admin_name": "admin"}
test_permiso_autorizado {
permitir with input as {
"permiso": {"sujeto": "x", "accion": "a"},
"permisos": [{"x": ["a"]}],
}
with data.admin_name as admin_name
}
And well, this is the result:
FAILURES
--------------------------------------------------------------------------------
data.monolith.tiene_permiso.test_permiso_autorizado: FAIL (293.209µs)
query:1 Enter data.monolith.tiene_permiso.test_permiso_autorizado = _
query:1 | Eval data.monolith.tiene_permiso.test_permiso_autorizado = _
query:1 | Index data.monolith.tiene_permiso.test_permiso_autorizado = _ (matched 1 rule)
tiene_permiso_test.rego:5 | Enter data.monolith.tiene_permiso.test_permiso_autorizado
tiene_permiso_test.rego:10 | | Eval __local3__ = data.monolith.tiene_permiso.admin_name
tiene_permiso_test.rego:10 | | Index __local3__ = data.monolith.tiene_permiso.admin_name (matched 1 rule)
tiene_permiso_test.rego:3 | | Enter data.monolith.tiene_permiso.admin_name
tiene_permiso_test.rego:3 | | | Eval true
tiene_permiso_test.rego:3 | | | Exit data.monolith.tiene_permiso.admin_name
tiene_permiso_test.rego:6 | | Eval data.monolith.tiene_permiso.permitir with input as {"permiso": {"accion": "a", "sujeto": "x"}, "permisos": [{"x": ["a"]}]} with data.admin_name as __local3__
tiene_permiso_test.rego:6 | | Index data.monolith.tiene_permiso.permitir with input as {"permiso": {"accion": "a", "sujeto": "x"}, "permisos": [{"x": ["a"]}]} with data.admin_name as __local3__ matched 2 rules)
tiene_permiso.rego:5 | | Enter data.monolith.tiene_permiso.permitir
tiene_permiso.rego:6 | | | Eval data.monolith.tiene_permiso.es_admin
tiene_permiso.rego:6 | | | Index data.monolith.tiene_permiso.es_admin (matched 1 rule)
tiene_permiso.rego:19 | | | Enter data.monolith.tiene_permiso.es_admin
tiene_permiso.rego:20 | | | | Eval input.permisos[_][key] = data.admin_name
tiene_permiso.rego:20 | | | | Fail input.permisos[_][key] = data.admin_name
tiene_permiso.rego:6 | | | Fail data.monolith.tiene_permiso.es_admin
tiene_permiso.rego:9 | | Enter data.monolith.tiene_permiso.permitir
tiene_permiso.rego:12 | | | Eval data.monolith.tiene_permiso.usuario_tiene_permitido[grant]
tiene_permiso.rego:12 | | | Index data.monolith.tiene_permiso.usuario_tiene_permitido[__local0__] (matched 1 rule)
tiene_permiso.rego:23 | | | Enter data.monolith.tiene_permiso.usuario_tiene_permitido
tiene_permiso.rego:26 | | | | Eval __local4__ = input.permiso.sujeto
tiene_permiso.rego:26 | | | | Eval accion = input.permisos[_][__local4__][j]
tiene_permiso.rego:23 | | | | Exit data.monolith.tiene_permiso.usuario_tiene_permitido
tiene_permiso.rego:15 | | | Eval input.permiso.accion = grant.accion
tiene_permiso.rego:15 | | | Fail input.permiso.accion = grant.accion
tiene_permiso.rego:12 | | | Redo data.monolith.tiene_permiso.usuario_tiene_permitido[grant]
tiene_permiso.rego:23 | | | Redo data.monolith.tiene_permiso.usuario_tiene_permitido
tiene_permiso.rego:26 | | | | Redo accion = input.permisos[_][__local4__][j]
tiene_permiso.rego:26 | | | | Redo __local4__ = input.permiso.sujeto
tiene_permiso.rego:3 | | Enter data.monolith.tiene_permiso.permitir
tiene_permiso.rego:3 | | | Eval true
tiene_permiso.rego:3 | | | Exit data.monolith.tiene_permiso.permitir
tiene_permiso.rego:3 | | Redo data.monolith.tiene_permiso.permitir
tiene_permiso.rego:3 | | | Redo true
tiene_permiso_test.rego:6 | | Fail data.monolith.tiene_permiso.permitir with input as {"permiso": {"accion": "a", "sujeto": "x"}, "permisos": [{"x": ["a"]}]} with data.admin_name as __local3__
tiene_permiso_test.rego:10 | | Redo __local3__ = data.monolith.tiene_permiso.admin_name
tiene_permiso_test.rego:3 | | Redo data.monolith.tiene_permiso.admin_name
tiene_permiso_test.rego:3 | | | Redo true
query:1 | Fail data.monolith.tiene_permiso.test_permiso_autorizado = _
SUMMARY
--------------------------------------------------------------------------------
data.monolith.tiene_permiso.test_permiso_autorizado: FAIL (293.209µs)
--------------------------------------------------------------------------------
FAIL: 1/1
What am I doing wrong? And how do I change my code to achieve what I need?
Upvotes: 0
Views: 598
Reputation: 1609
The permitir
rule is failing on this line:
input.permiso.accion == grant.accion
The trace reports this (albeit with a lot of other noise):
tiene_permiso.rego:15 | | | Eval input.permiso.accion = grant.accion
tiene_permiso.rego:15 | | | Fail input.permiso.accion = grant.accion
The reason it's failing is that usuario_tiene_permitido
generates a set of actions represented as strings, i.e., grant
is a string not an object containing the subject and action. If you evaluate usuario_tiene_permitido
with the input you provided, you'll see this.
You could refactor the permitir
rule as follows:
permitir {
# Find grants for the user.
some grant
usuario_tiene_permitido[grant]
input.permiso.accion == grant
}
Upvotes: 1