I am working on a web app that uses DRF as the backend and ReactJS as the frontend. My web app has users from different sales departments, and I would like to restrict the permission such that only the users from Sales Department A can see the sales projects that are tagged under Sales Department A, and if the users try to access a sales project page that they are not authorised to, it should return an error page. I tried googling for the answer, but I am not sure if the answer I found is the best solution for my problem. I saw solutions using Django Groups, but I was not sure how it works (so if someone could clarify it would be great!). I was hoping for a solution that would sort of have a check layer within the view or serializer, and from there would deduce which sales department the request.user is from, and hence whether or not the data should be released to them.
below is my models.py for more clarity on the structure i am using.
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
department = models.ManyToManyField('SalesDepartment', related_name='users', blank=True)
contact_number = PhoneNumberField(blank=True)
email = models.EmailField(max_length=255)
email_password = models.CharField(max_length=255)
profile_picture = models.ImageField(upload_to='profile/', default='profile/blank.png')
def __str__(self):
return str(self.user.username)
class SalesDepartment(models.Model):
department_id = models.AutoField(primary_key=True)
department_name = models.CharField(max_length=100)
def __str__(self):
return self.department_name
class SalesProject(models.Model):
sales_project_id = models.AutoField(primary_key=True)
sales_project_name = models.CharField(max_length=100)
creation_date = models.DateField(default=timezone.localdate)
sales_department = models.ForeignKey('SalesDepartment', on_delete=models.CASCADE)
def __str__(self):
return self.sales_project_name
The UserProfile model has a M2M field to the SalesDepartment model, and the SalesProject model has a Foreign Key relation to the SalesDepartment model. Hence, I am hoping to check for the user's sales department from the UserProfile model, and check to see if it is the same SalesDepartment as the one linked to the specific SalesProject that the API call is getting, and if so, return the response data as per usual, but if not, then return an error for the response data.
All help is appreciated, I am new to Django and DRF especially, hope that you guys would guide me to the correct path if I am misguided on how I am supposed to handle this authorisation problem. Thanks all in advance!
from rest_framework import permissions
class IsTheUserYouWant(permissions.BasePermission):
"""
Here I'm checking if the request.user, if the request is coming from a group that is
allowed to perform this action or if the user here is an staff member, aka admin user.
You can check whatever you want here since you have access to the user. So you can
check the sales_department like you mentioned in the question.
"""
def has_permission(self, request, view):
if request.user and request.user.groups.filter(name="Group You Created") or request.user.is_staff:
return True
return False
Views.py example usage
class SalesProjectSet(viewsets.ModelViewSet):
queryset = SalesProject.objects.all()
serializer_class = SalesProjectSerializer
permission_classes = [IsTheUserYouWant]
In the Django Admin page you can create a Group and add users to it If you want, then you can check in the permission if the user is from the group who are allowed.