In any web application, role-based access control (RBAC) plays a vital part in ensuring the right permissions are granted to the right users. Flask, a lightweight Python web framework, provides a solid foundation for implementing RBAC by allowing the creation and management of roles and privileges within an application.
This article will walk you through the process of assigning privileges to roles in a Flask-based application. We'll demonstrate how to display modules with corresponding tasks, and then assign privileges by inserting multiple records into a privileges table using a loop. This guide assumes you have basic knowledge of Flask and its MVC (Model-View-Controller) structure.
We will break this task down into two main steps:
- Step 1: Create a method in the `RoleController` to display all modules with their corresponding tasks.
- Step 2: Define a method to assign privileges by inserting multiple records into the privileges table with a role ID and an array of task IDs.
Step 1: Display Modules and Tasks
To begin, we need to create a view that lists all available modules and their corresponding tasks. Each task will be associated with a specific module, and each module might have several tasks.
Define `PrivilegeForm` in `PrivilegeModel.py`
Before we move to the controller, we will define a form class in `PrivilegeModel.py` to handle privilege assignments.
```python
privilege_model.py
from flask_wtf import FlaskForm
from wtforms import SelectMultipleField, SubmitField
class PrivilegeForm(FlaskForm):
tasks = SelectMultipleField('Tasks', coerce=int) List of tasks with task IDs
submit = SubmitField('Assign Privileges')
```
This form will allow the selection of multiple tasks when assigning privileges to a role.
Create a Method to Display Modules and Tasks
In the `RoleController`, we'll create a method called `display_modules_with_tasks()` that retrieves all modules and their associated tasks, and passes them to the view for rendering.
```python
role_controller.py
from flask import render_template
from .models import Module, Task
class RoleController:
@staticmethod
def display_modules_with_tasks():
Retrieve all modules and their associated tasks from the database
modules = Module.query.all()
tasks = {module.id: Task.query.filter_by(module_id=module.id).all() for module in modules}
return render_template('assign_privileges.html', modules=modules, tasks=tasks)
```
Here, we're using Flask's `render_template` function to render a template called `assign_privileges.html`. The `modules` and `tasks` data is passed to the template, which displays the modules along with checkboxes for each task.
In your template, you could loop through the modules and tasks like this:
```html
<!-- templates/assign_privileges.html -->
<form method="POST">
{% for module in modules %}
<h3>{{ module.name }}</h3>
<ul>
{% for task in tasks[module.id] %}
<li>
<input type="checkbox" name="tasks" value="{{ task.id }}">{{ task.name }}
</li>
{% endfor %}
</ul>
{% endfor %}
<button type="submit">Assign Privileges</button>
</form>
```
Step 2: Assign Privileges
Now that we have the view displaying modules and tasks, we need to define a method in the `RoleController` to handle the assignment of privileges. The `assign_privileges()` function will take the role ID and an array of task IDs, and insert records into the `privileges` table.
Define `assign_privileges` Function in `RoleController`
In the `RoleController`, we will add the following method to handle the privilege assignment:
```python
role_controller.py
from flask import request, redirect, url_for
from .models import Privilege, db
class RoleController:
@staticmethod
def assign_privileges(role_id):
Retrieve selected task IDs from the form
task_ids = request.form.getlist('tasks')
Insert each task as a privilege for the given role
for task_id in task_ids:
privilege = Privilege(role_id=role_id, task_id=task_id)
db.session.add(privilege)
Commit the changes to the database
db.session.commit()
Redirect to the role management page
return redirect(url_for('role_management'))
```
In this function:
1. We retrieve the selected `task_ids` from the form using `request.form.getlist('tasks')`.
2. We loop through the `task_ids` and create a new `Privilege` object for each task, associating it with the `role_id`.
3. We add each `Privilege` object to the database session and commit the transaction.
4. Finally, we redirect the user to the role management page.
Model for Privilege
For this to work, we need a `Privilege` model, which links a role to its tasks.
```python
models.py
from . import db
class Privilege(db.Model):
__tablename__ = 'privileges'
id = db.Column(db.Integer, primary_key=True)
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
task_id = db.Column(db.Integer, db.ForeignKey('tasks.id'))
def __init__(self, role_id, task_id):
self.role_id = role_id
self.task_id = task_id
```
The `Privilege` model has two foreign keys: `role_id` and `task_id`, which link the privilege to both a role and a task.
Conclusion
In this article, we created a simple feature to assign privileges to a role in a Flask application. We started by displaying all modules and their corresponding tasks, allowing the selection of multiple tasks. Then, we defined a method to handle the insertion of multiple privileges into the database, assigning them to a specified role.
By following these steps, you can implement role-based access control (RBAC) in your Flask application and customize it according to your project's needs.
Source Code on GitHub
Click here to access or download the source code.