I'd like to have multiples layers of permissions for an API using Django Rest Framework, how can I best achieve this?
Specifically the three categories of authorization I have are:
The second two categories apply equally across all models and it would be nice to not need separate permissions for each model.
Idea 1:
Create a model for each category inheriting from the standard django auth group. Doing these as proxy groups, to be logically different in my code, but as consistent with standard authorization as possible. Then use django-guardian to enable the object level permissions.
Idea 2:
Use the standard groups for roles and assign model level permissions based on these groups. For the object level permissions write a custom permission classes in Django Rest Framework to check the object level permissions against the user.
I have recently designed such an architecture so the first thing came into my mind would be like this:
# models.py
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
"""Custom user model with an extra type field"""
SUPER_USER = 1
OTHER_ROLE = 2
SOME_OTHER_ROLE = 3
USER_TYPE_CHOICES = (
(SUPER_USER, 'Super user'),
(OTHER_ROLE, 'Other role'),
(SOME_OTHER_ROLE, 'Some other role'),
)
user_type = models.PositiveSmallIntegerField(choices=USER_TYPE_CHOICES)
# -------------------------------------------------------------------------
# Don't forget to set this User model as your default model
# settings.py
AUTH_USER_MODEL = 'my_app.User'
Group
model and put a ForeignKey to your Team
models and do object-level permission manually.# models.py
from django.contrib.auth.models import Group
from django.db import models
def Team(models.Model):
group = models.ForeignKey(Group, on_delete=models.CASCADE)
# -------------------------------------------------------------------------
# You can do object-level permission per group by
# ...
if team.group in permitted_groups:
# permission granted
pass
else:
# permission not granted
pass
# ...
Tag
model and add as ManyToManyField to your sensitive information model. Similar to the second solution above, you can manually do object-level permission during runtime by relying on your current information's tags.