How do I implement granular ACLs at the template level with Jinja2 and Flask?
Here is what I have without a Jinja2 context dictionary or any prebuilt Flask ACL library. This is my own psuedo ACL where I simply would query a database for a role and get that into my index function.
(source modified from The Flask Mega-Tutorial)
def index():
user = {'nickname': 'Miguel'} # fake user
acl = {'role' : 'Supervisor'} #<---- hardcoded in lieu of a database call from somewhere
posts = [ # fake array of posts
{
'author': {'nickname': 'John'},
'body': 'Beautiful day in Portland!'
},
{
'author': {'nickname': 'Susan'},
'body': 'The Avengers movie was so cool!'
}
]
return render_template("index.html",
title='Home',
user=user,
posts=posts
acl=acl) #<----made up acl data
<html>
<head>
{% if "Supervisor" in acl.role %} #<---- using made up ACL data from index
<title>{{ title }} - Welcome Manager</title>
{% else %}
<title>Welcome Employee</title>
{% endif %}
</head>
<body>
<h1>Hello, {{ user.nickname }}!</h1>
</body>
</html>
I have looked at a couple of libraries for Flask and ACLs such as this
https://github.com/mikeboers/Flask-ACL
but what I cannot find is how to apply an ACL to a specific item in a rendered template, regardless of any Flask library.
If I have a button named "secret-information," but the page is available to everyone, how can I secure just that button? The render_template
function has already been called.
Or, sometimes I may have a redacted set of information that only someone of a certain supervisor level can see, and I don't want to create separate templates.
The only thing that comes close is Jinja2's contextfilter,
http://jinja.pocoo.org/docs/dev/api/#jinja2.runtime.Context
But, I am not sure how to use it.
My way above seems very unmanageable unless there are only a few groups. Larger sets will require nesting groups and priorities.