How to Create RBAC in Django with Multiple Users Types

Role-Based Access Control (RBAC) is a crucial aspect of building secure and scalable web applications. In Django, RBAC can be implemented to manage user permissions effectively. In this blog post, we’ll walk you through the process of creating RBAC in Django using a practical example: an attendance system with three user types – admin, manager, and standard user.

Please note, for this implementation can be used with any application project. For example we have consider attendance system.

What is RBAC?

RBAC is a security model that defines access permissions to resources based on user roles. It helps ensure that users only have access to the features and data they are authorized to use. In our attendance system, we’ll have three user roles:

  1. Admin: Has full control over the application, including user management, attendance data, and settings.
  2. Manager: Can view and manage attendance data but doesn’t have access to user management or application settings.
  3. Standard User: Can only view their own attendance data.

Setting Up the Django Project

Let’s start by creating a new Django project and application for our attendance system.

django-admin startproject myproject
cd myproject
python manage.py startapp myapp

Next, add the app to the INSTALLED_APPS list in the project’s settings.

# myproject/settings.py

INSTALLED_APPS = [
    # ...
    'myapp',
    # ...
]

Django provides a built-in user model. However, if you need custom user fields, you can create a custom user model. In your app’s models.py file, create a custom user model by extending User Model.

  • AbstractUser: Use when you want to add simple fields to the User model, preserving default authentication and admin functionality.
  • AbstractBaseUser: Use when you need full control over authentication logic, and want to customize User fields extensively.
  • One-to-One Link: Use when you want to keep the default User model intact but add separate custom fields in a related model.
  • Proxy Model: Use when you want to add methods or properties to the existing User model without changing the database structure.

Learn more about Extending the Django User Model: Exploring Various Approaches

Now, let’s create a model for our user profiles with the necessary fields for RBAC.

# myapp/models.py

from django.contrib.auth.models import AbstractUser
from django.db import models

class CustomUser(AbstractUser):
    USER_TYPES = (
        ('admin', 'Admin'),
        ('manager', 'Manager'),
        ('standard', 'Standard User'),
    )
    user_type = models.CharField(max_length=10, choices=USER_TYPES, default='standard')

class Attendance(models.Model):
    user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
    date = models.DateField()
    # Add other attendance-related fields here

After creating the models, don’t forget to run makemigrations and migrate to apply the changes to the database.

python manage.py makemigrations
python manage.py migrate

Implementing Role Based Access Control System

Now that we have our models in place, let’s implement RBAC by creating custom decorators and views for each user type.

1. Admin Access

Admins should have access to all parts of the application. We can create a custom decorator to enforce this access control.

# myapp/decorators.py

from django.shortcuts import redirect

def admin_required(view_func):
    def wrapper(request, *args, **kwargs):
        if request.user.user_type == 'admin':
            return view_func(request, *args, **kwargs)
        else:
            return redirect('access_denied')
    return wrapper

2. Manager Access

Managers can view and manage attendance data but not user management or application settings. We’ll create a similar decorator for them.

# myapp/decorators.py

def manager_required(view_func):
    def wrapper(request, *args, **kwargs):
        if request.user.user_type in ['admin', 'manager']:
            return view_func(request, *args, **kwargs)
        else:
            return redirect('access_denied')
    return wrapper

3. Standard User Access

Standard users can only view their own attendance data. We’ll create a custom view for them.

# myapp/views.py

from django.shortcuts import render

def view_own_attendance(request):
    # Retrieve and display the user's attendance data
    user_attendance = Attendance.objects.filter(user=request.user)
    return render(request, 'attendance/view_attendance.html', {'user_attendance': user_attendance})

4. Access Denied View

Create a simple view to show an “Access Denied” message.

# myapp/views.py

def access_denied(request):
    return render(request, 'attendance/access_denied.html')

5. URL Patterns

Finally, update your URL patterns to include the new views and decorators.

# myapp/urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('view-own-attendance/', views.view_own_attendance, name='view_own_attendance'),
    path('access-denied/', views.access_denied, name='access_denied'),
    # Add other URL patterns for manager and admin views
]

Conclusion

Implementing RBAC in Django is essential for building secure and organized web applications. By defining roles and using custom decorators and views, you can ensure that users only have access to the features and data they need. In our attendance system example, we’ve shown you how to create RBAC for three user types: admin, manager, and standard user. You can expand on this foundation to build more complex access control systems for your Django projects.

Blogs You Might Like to Read!