[rule]
id = "py-require-decorator"
languages = ["python"]
category = "middleware"
confidence = "high"
description = "@require_* authz decorator (Zulip-style: @require_realm_admin, @require_member_or_admin, ...)"
query = """
(decorator
[
(identifier) @decorator_name
(attribute attribute: (identifier) @decorator_name)
(call
function: [
(identifier) @decorator_name
(attribute attribute: (identifier) @decorator_name)
])
]
) @match
"""
[rule.predicates.decorator_name]
match = "^require_[a-z][a-z0-9_]*$"
[[rule.tests]]
input = """
@require_realm_admin
def administer(request):
pass
"""
expect_match = true
[[rule.tests]]
input = """
@require_member_or_admin
def view_members(request):
pass
"""
expect_match = true
[[rule.tests]]
input = """
@require_organization_member(realm_id=1)
def list_streams(request):
pass
"""
expect_match = true
[[rule.tests]]
input = """
@auth.require_admin
def manage(request):
pass
"""
expect_match = true
[[rule.tests]]
input = """
@require_GET
def index(request):
pass
"""
expect_match = false
[[rule.tests]]
input = """
@require_POST
def submit(request):
pass
"""
expect_match = false
[[rule.tests]]
input = """
@app.route('/')
def index():
pass
"""
expect_match = false
[[rule.tests]]
input = """
@staticmethod
def helper():
pass
"""
expect_match = false