pythondjangooauth-2.0django-rest-frameworkdjango-oauth

How to allow user to modify only his data in Django Rest Framework


i'm building simple API with Django 2.1.8 and provide security with Django OAuth Toolkit. I've reached the point where user can use api only after authorization but i want to limit his acctions only to his data.

I've built authorization using oauth2 which returns me access token.

models.py

class Client(AbstractUser):

    email = models.EmailField(
        verbose_name='email adress',
        max_length= 255,
        unique=True,
    )
    location = models.CharField(max_length=500, default="")

    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)
    objects = ClientManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['location']

    def __str__(self):
        return self.email

    def has_perm(self, perm, obj=None):
        "Does the user have a specific permission?"
        # Simplest possible answer: Yes, always
        return True

    def has_module_perms(self, app_label):
        "Does the user have permissions to view the app `app_label`?"
        # Simplest possible answer: Yes, always
        return True

    @property
    def is_staff(self):
        "Is the user a member of staff?"
        # Simplest possible answer: All admins are staff
        return self.is_admin

views.py

class SingleClientView(generics.RetrieveAPIView):
    queryset = Client.objects.all()
    serializer_class = ClientSerializer
    permission_classes = [IsAuthenticated, TokenHasReadWriteScope]

Is there any possibility to connect returned token with user model, so every time someone would use API it filter if user matches required data? Or does oauth toolkit automatically and how to acces it?


Solution

  • You have to add oauth2_provider.middleware.OAuth2TokenMiddleware in your middlewares in settings.py file. This will automatically attach the user with request to which token belongs and you can access it from request like request.user

    You can modify your view accordingly.

    class SingleClientView(generics.RetrieveAPIView):
        queryset = Client.objects.all()
        serializer_class = ClientSerializer
        permission_classes = [IsAuthenticated, TokenHasReadWriteScope]
    
        def get_object(self):
            return self.request.user
            # or any similar logic here..