DRF - How to authenticate an application using the Oauth Toolkit?

In my application, I use a modified model Userwith 3 more fields that I need.

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

import ldapdb.models


class User(AbstractUser):
    cotisant = models.BooleanField(default=False)
    nbSessions = models.IntegerField(default=0)
    tel = models.CharField(max_length=20, default="")

I want people to be able to change their account settings (e.g. their password, email,, tel...).

For this, I have a serializer like this:

from rest_framework import serializers
from django.contrib.auth.hashers import make_password
from coreapp.models import User


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name', 'email', 'password', 'cotisant', 'tel')
        extra_kwargs = {
            # Allow to set pwd, but disallow getting the hash from database
            'password': {'write_only': True}
        }

    def validate_password(self, value: str):
        return make_password(value)

And here is a view:

class UserViewSet(viewsets.ModelViewSet):
    serializer_class = UserSerializer
    permission_classes = (IsSelfOrStaffPermission, TokenHasReadWriteScopeOrCreate,)
    lookup_field = 'username'

    def get_queryset(self):
        current_user = self.request.user
        if current_user.is_staff:
            user_set = User.objects.all()
        else:
            user_set = User.objects.filter(username=current_user.username)

        query = self.request.query_params.get('q', None)

        if not query:
            return user_set

        return user_set.filter(
            Q(username__icontains=query) |
            Q(first_name__icontains=query) |
            Q(last_name__icontains=query)
        )

(This allows access to the user only for himself, unless he is a staff)

The problem is to update the parameter nbSessions, the user must pay something in one of my applications.

How can I allow an application to set a parameter, but prevent the user from updating it directly?

. , Password Credential Flow , - .

+4
2

, , (nbSessions) API , .

: , , .

class UserSerializer(serializers.ModelSerializer):
    """
    Serializer used by third-party apps.
    All fields, including nbSessions, are writeable.
    """

    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name', 'email', 'password', 'cotisant', 'nbSessions', 'tel')
        extra_kwargs = {
            'password': {'write_only': True}
        }

    # ...

class RestrictedUserSerializer(UserSerializer):
    """
    Serializer used by regular users.
    All fields except nbSessions are writeable.
    It inherits from UserSerializer so that common code is not duplicated.
    """

    class Meta(BaseUserSerializer.Meta):
        read_only_fields = ('nbSessions',)

, , read_only_fields RestrictedUserSerializer.Meta.

, , :

class UserViewSet(viewsets.ModelViewSet):

    def get_serializer_class(self):
        if is_third_party_app(self.request.user):
            return UserSerializer
        return RestrictedUserSerializer

    # ...

(, ) , , , .. , .

+1

, , api. api . api , , .

, abcd ios. ios : https://your-endpoint.com/api/method/?token=abcd

, .

class IsApprovedClientPermission(permissions.BasePermission):

    def has_permission(self, request, view):
        token = request.query_params.get('token', None)
        if request.method not in permissions.SAFE_METHODS:
            # custom checks
            return token in approved_tokens_list:
        return True

, , .

+1

Source: https://habr.com/ru/post/1692593/


All Articles