[rule]
id = "py-has-perm-call"
languages = ["python"]
category = "rbac"
confidence = "high"
description = "Django-style permission check (request.user.has_perm / has_perms)"
query = """
(call
function: (attribute
attribute: (identifier) @method)
arguments: (argument_list
[
(string (string_content) @perm_name)
(list
(string (string_content) @perm_name))
])
) @match
"""
[rule.predicates.method]
match = "^(has_perm|has_perms)$"
[rule.rego_template]
template = """
default allow := false
allow if {
"{{perm_name}}" in input.user.permissions
}
"""
[rule.cedar_template]
template = """
permit (
principal,
action,
resource
)
when {
"{{perm_name}}" in principal.permissions
};
"""
[[rule.tests]]
input = """
if request.user.has_perm('app.delete_user'):
delete_user()
"""
expect_match = true
[[rule.tests]]
input = """
if user.has_perm('blog.add_post'):
create()
"""
expect_match = true
[[rule.tests]]
input = """
if request.user.has_perms(['blog.add_post', 'blog.change_post']):
bulk_edit()
"""
expect_match = true
[[rule.tests]]
input = """
result.has_value('foo')
"""
expect_match = false