简体   繁体   中英

Restrict roles for users management inside a Company object in Django Rest Framework

So, I have Company model like

class Company(models.Model):

    company_name = models.CharField(max_length=150, blank=True, default='', verbose_name='Company Name')
    ...  
    *other fields*

And also have User model with

class User():  
    operator_account = models.ForeignKey(Operator, on_delete=models.CASCADE, related_name='users', blank=True, null=True)  
    Role in company = charfield with choices, can be a Manager, Regular user and Viewer
    ...  
    *other fields*

As you can see, in a Company I can have a multiple users with different roles. So, I need have some way to restrict users actions inside a company, base on user role and use for it serializers or viewsets. Just like if for example user has Manager role - then he will can edit company info and other users connected to company and create new users in this company and if user not Manager - he can`t create new users in company. This is a main goals, please, help!

I dont fully got what is your need but Ill try to help. There are more than one way to approache this, one idea is to set a role inside the user class (similar to what you got I guess).

Inside the user model:

ROLE_OPTIONS = (
        (MANAGER, "Manager"),
        (EMPLOYEE, "Employee"),
    )
role = models.CharField(
        _("Role"), max_length=30, choices=ROLE_OPTIONS, default=EMPLOYEE
    )

If you want to set the permissions for you api, you can create custom permissions and allow certain types of user access it:

class IsManager(BasePermission):
    def has_permission(self, request, view):
        return request.user.role == "manager"

class SomeViewset():
    permission_classes = (IsAuthenticated, IsManager,)

more info on drf docs: https://www.django-rest-framework.org/api-guide/permissions/#custom-permissions

Do you want the user to be able to edit the company inside the admin? Inside the admin class for your model you can set the permissions, for example for deleting:

def has_delete_permission(self, request, obj=None):
        if request.user.is_superuser or obj.role == "manager":
            return True
        return False

Or making fields read_only for non managers:

def get_readonly_fields(self, request, obj=None):
        if obj and not request.user.is_superuser:
            return (
                "company_name",
                "some_other_field",
                *self.readonly_fields,
            )
        return self.readonly_fields

check the docs for more admin methods: https://docs.djangoproject.com/en/3.2/ref/contrib/admin/#django.contrib.admin.ModelAdmin.has_view_permission

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM