Flask-RBAC¶
Flask-RBAC provides a Role-based Access Control module in Flask applications. It can help you to control different role of users to access your website.
Quick Start¶
This documents show how to create Flask-RBAC extension easily and quickly.
Configuration Your Application¶
As same as many Flask extensions, you need to configuration your application:
from flask import Flask
from flask_rbac import RBAC
app = Flask(__name__)
rbac = RBAC(app)
or you can configuration using factory method:
from flask import Flask
from flask_rbac import RBAC
rbac = RBAC()
def create_app():
app = Flask(__name__)
rbac.init_app(app)
return app
Mode Setting¶
There are two modes for Flask-RBAC, RBAC_USE_WHITE decide whether use white list to check the permission. And it set False to default.
RBAC_USE_WHITE = True | Only allowing rules can access the resources. This means, all deny rules and rules you did not add cannot access the resources. |
RBAC_USE_WHITE = False | Only denying rules cannot access the resources. |
Change it using:
app.config['RBAC_USE_WHITE'] = True
Set Role Model¶
Flask-RBAC implements some methods need by Flask-RBAC in RoleMixin class. You can use RoleMixin as your role model:
class Role(RoleMixin):
pass
anonymous = Role('anonymous')
However, if your application is working under SQLAlchemy, and you want to save the roles in database, you need to override the Role class to adapt your application, here is an example:
from flask_rbac import RoleMixin
from your_package.app import db
roles_parents = db.Table(
'roles_parents',
db.Column('role_id', db.Integer, db.ForeignKey('role.id')),
db.Column('parent_id', db.Integer, db.ForeignKey('role.id'))
)
class Role(db.Model, RoleMixin):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(20))
parents = db.relationship(
'Role',
secondary=roles_parents,
primaryjoin=(id == roles_parents.c.role_id),
secondaryjoin=(id == roles_parents.c.parent_id),
backref=db.backref('children', lazy='dynamic')
)
def __init__(self, name):
RoleMixin.__init__(self)
self.name = name
def add_parent(self, parent):
# You don't need to add this role to parent's children set,
# relationship between roles would do this work automatically
self.parents.append(parent)
def add_parents(self, *parents):
for parent in parents:
self.add_parent(parent)
@staticmethod
def get_by_name(name):
return Role.query.filter_by(name=name).first()
After create role model, you can add your model to Flask-RBAC:
rbac.set_role_model(Role)
Or use decorator to set role model for Flask-RBAC:
@rbac.as_role_model
class Role(RoleMixin):
# codes go here
Set User Model¶
Same as the RoleMixin, UserMixin implements some methods for Flask-RBAC, You can extend it directly:
from flask_rbac import UserMixin
class User(UserMixin):
pass
a_user = User()
Well, if your application works under SQLAlchemy:
from flask_rbac import UserMixin
from your_package.app import db
users_roles = db.Table(
'users_roles',
db.Column('user_id', db.Integer, db.ForeignKey('user.id')),
db.Column('role_id', db.Integer, db.ForeignKey('role.id'))
)
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(30), unllable=True)
# Other columns
roles = db.relationship(
'Role',
secondary=users_roles,
backref=db.backref('roles', lazy='dynamic')
)
def add_role(self, role):
self.roles.append(role)
def add_roles(self, roles):
for role in roles:
self.add_role(role)
def get_roles(self):
for role in self.roles:
yield role
Same as role model, you should add user model to Flask-RBAC:
rbac.set_user_model(User)
Or using decorator:
@rbac.as_user_model
class User(UserMixin):
# codes go here
Set User Loader¶
Flask-RBAC need to know who is current user, so it requires you to provide a function which tells it who is current user.
Flask-RBAC will load current user from Flask-Login if you have install it by default.
If you save current user in flask.g, here is an example for you:
from flask import g, current_app
@app.route('/signin', methods=['POST'])
@rbac.allow(['anonmous'], methods=['POST'])
def signin():
# Sign in logic...
g.current_user = user
def get_current_user():
with current_app.request_context():
return g.current_user
rbac.set_user_loader(get_current_user)
Set Access Rules¶
You can use allow and deny to add rules to Flask-RBAC:
@app.route('/')
@rbac.allow(['anonymous'], methods=['GET'])
def index():
# your codes.
pass
@app.route('/account/signin', methods=['GET', 'POST'])
@rbac.deny(['logged_user'], methods=['GET', 'POST'])
def signin():
# show sign in page or handle sign in request.
pass
The code above adding two rules:
- Allows user of anonymous role to GET /.
- Deny user of logged_user role to GET and POST /account/signin.
API Reference¶
Flask.ext.rbac.RBAC¶
-
class
flask_rbac.__init__.
RBAC
(app=None, **kwargs)¶ This class implements role-based access control module in Flask. There are two way to initialize Flask-RBAC:
app = Flask(__name__) rbac = RBAC(app)
or:
rbac = RBAC def create_app(): app = Flask(__name__) rbac.init_app(app) return app
Parameters: - app – the Flask object
- role_model – custom role model
- user_model – custom user model
- user_loader – custom user loader, used to load current user
- permission_failed_hook – called when permission denied.
-
allow
(roles, methods, with_children=True)¶ This is a decorator function.
You can allow roles to access the view func with it.
An example:
@app.route('/website/setting', methods=['GET', 'POST']) @rbac.allow(['administrator', 'super_user'], ['GET', 'POST']) def website_setting(): return Response('Setting page.')
Parameters: - roles – List, each name of roles. Please note that, anonymous is refered to anonymous. If you add anonymous to the rule, everyone can access the resource, unless you deny other roles.
- methods – List, each name of methods. methods is valid in [‘GET’, ‘POST’, ‘PUT’, ‘DELETE’]
- with_children – Whether allow children of roles as well. True by default.
-
as_role_model
(model_cls)¶ A decorator to set custom model or role.
Parameters: model_cls – Model of role.
-
as_user_model
(model_cls)¶ A decorator to set custom model or user.
Parameters: model_cls – Model of user.
-
deny
(roles, methods, with_children=False)¶ This is a decorator function.
You can deny roles to access the view func with it.
An example:
@app.route('/article/post', methods=['GET', 'POST']) @rbac.deny(['anonymous', 'unactivated_role'], ['GET', 'POST']) def article_post(): return Response('post page.')
Parameters: - roles – List, each name of roles.
- methods – List, each name of methods. methods is valid in [‘GET’, ‘POST’, ‘PUT’, ‘DELETE’]
- with_children – Whether allow children of roles as well. True by default.
-
exempt
(view_func)¶ Exempt a view function from being checked permission. It is useful when you are using white list checking.
Example:
@app.route('/everyone/can/access') @rbac.exempt def everyone_can_access(): return 'Hello~'
Parameters: view_func – The view function going to be exempted.
-
get_app
(reference_app=None)¶ Helper method that implements the logic to look up an application.
-
has_permission
(method, endpoint, user=None)¶ Return does the current user can access the resource. Example:
@app.route('/some_url', methods=['GET', 'POST']) @rbac.allow(['anonymous'], ['GET']) def a_view_func(): return Response('Blah Blah...')
If you are not logged.
rbac.has_permission(‘GET’, ‘a_view_func’) return True. rbac.has_permission(‘POST’, ‘a_view_func’) return False.
Parameters: - method – The method wait to check.
- endpoint – The application endpoint.
- user – user who you need to check. Current user by default.
-
init_app
(app)¶ Initialize application in Flask-RBAC. Adds (RBAC, app) to flask extensions. Adds hook to authenticate permission before request.
Parameters: app – Flask object
-
set_hook
(hook)¶ Set hook which called when permission is denied If you haven’t set any hook, Flask-RBAC will call:
abort(403)
Parameters: hook – Hook function
-
set_role_model
(model)¶ Set custom model of role.
Parameters: model – Model of role.
-
set_user_loader
(loader)¶ Set user loader, which is used to load current user. An example:
from flask_login import current_user rbac.set_user_loader(lambda: current_user)
Parameters: loader – Current user function.
-
set_user_model
(model)¶ Set custom model of User
Parameters: model – Model of user
Flask.ext.rbac.model.RoleMixin¶
-
class
flask_rbac.model.
RoleMixin
(name=None)¶ This provides implementations for the methods that Flask-RBAC wants the role model to have.
Parameters: name – The name of role. -
add_parent
(parent)¶ Add a parent to this role, and add role itself to the parent’s children set. you should override this function if neccessary.
Example:
logged_user = RoleMixin('logged_user') student = RoleMixin('student') student.add_parent(logged_user)
Parameters: parent – Parent role to add in.
-
add_parents
(*parents)¶ Add parents to this role. Also should override if neccessary. Example:
editor_of_articles = RoleMixin('editor_of_articles') editor_of_photonews = RoleMixin('editor_of_photonews') editor_of_all = RoleMixin('editor_of_all') editor_of_all.add_parents(editor_of_articles, editor_of_photonews)
Parameters: parents – Parents to add.
-
static
get_by_name
(name)¶ A static method to return the role which has the input name.
Parameters: name – The name of role.
-
get_name
()¶ Return the name of this role
-
Flask.ext.rbac.model.UserMixin¶
-
class
flask_rbac.model.
UserMixin
(roles=[])¶ This provides implementations for the methods that Flask-RBAC wants the user model to have.
Parameters: roles – The roles of this user should have. -
add_role
(role)¶ Add a role to this user.
Parameters: role – Role to add.
-
add_roles
(*roles)¶ Add roles to this user.
Parameters: roles – Roles to add.
-
Release Changes¶
Author & Contributor¶
- Yaoda Liu <shonenada@gmail.com>