While Flask-Principal is the most popular plugin, it is not complicated, and it just does not work in most cases, which I need. I tried to make it work the way I like it, but I never succeeded. Fortunately, I found a very simple and easy module - permission :
Using
First you need to define your own rules by subclassing Rule , then override check() and deny() :
# rules.py from flask import session, flash, redirect, url_for from permission import Rule class UserRule(Rule): def check(self): """Check if there is a user signed in.""" return 'user_id' in session def deny(self): """When no user signed in, redirect to signin page.""" flash('Sign in first.') return redirect(url_for('signin'))
Then you define permissions by subclassing Permission and overriding rule() :
# permissions.py from permission import Permission from .rules import UserRule class UserPermission(Permission): """Only signin user has this permission.""" def rule(self): return UserRule()
There are 4 ways to use the UserPermission described above:
1. Use as a view decorator
from .permissions import UserPermission @app.route('/settings') @UserPermission() def settings(): """User settings page, only accessable for sign-in user.""" return render_template('settings.html')
2. Use in sight
from .permissions import UserPermission @app.route('/settions') def settings(): permission = UserPermission() if not permission.check() return permission.deny() return render_template('settings.html')
3. Use in view codes (using the with statement)
from .permissions import UserPermission @app.route('/settions') def settings(): with UserPermission(): return render_template('settings.html')
4. Use in Jinja2 templates
First you need to enter certain permissions in the template context:
from . import permissions @app.context_processor def inject_vars(): return dict( permissions=permissions )
then in the templates:
{% if permissions.UserPermission().check() %} <a href="{{ url_for('new') }}">New</a> {% endif %}