I changed the security_requirements decorator to look like this:
def security_requirements(logged_in=True, roles=None): def wrapper(f):
The only real difference from the previous version of this decorator is the line that stores the security attributes inside the function object. This line is useless inside the decorator. However, now I can implement the following action for calling from a Jinja template:
{% if can_access(func) %} <li><a>...</a></li> {% endif %}
The can_access function is defined in the Flask application module. It gets the string that it must convert to a function object. He does this by calling app.view_functions :
def can_access(func): return auth.can_access(app.view_functions[func])
This function should be called directly from the Jinja template. Therefore, it should be added to Jinja global variables:
app.jinja_env.globals.update(can_access=can_access)
Finally, auth.can_access :
def can_access(f): if not hasattr(f, 'access_control'): return True
This solution means that access control is defined in one place - which is the function decorator.
reish
source share