-1

I have created the rest api for authentication of user, and in the response I am getting the token. I also want to add whether the user has staff permission or not, I have already got the information is serializers but I am not able to pass to the view.

And I need to authentication whether user is active or not This part is not working at all.

My serializer code :

class AuthTokenSerializer(serializers.Serializer):
    """Serializer for the user authentication object"""
    email = serializers.CharField()
    password = serializers.CharField(
        style={'input_type': 'password'},
        trim_whitespace=False
    )

    def validate(self, attrs):
        """Validate and authenticate the user"""
        email = attrs.get('email')
        password = attrs.get('password')

        user = authenticate(
            request=self.context.get('request'),
            username=email,
            password=password
        )
#This part I am trying to authenticate whether the account is active or not 
        if user is not None:
            if not user.is_active:
                msg = _('The password is valid, but the account has been disabled! ')
                raise serializers.ValidationError(msg, code='not_active')

        if not user:
            msg = _('Unable to authenticate with provided credentials')
            raise serializers.ValidationError(msg, code='authorization')

        attrs['user'] = user
        attrs['is_staff'] = user.is_staff  #Here I am getting the user has permission of staff or not.
        return attrs

And the views.py is :

class CreateTokenView(ObtainAuthToken):
    """Create a new auth token for the user"""
    serializer_class = AuthTokenSerializer
    renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES

models.py

class User(AbstractBaseUser, PermissionsMixin):
    """Custom user model that supports using email instead of username"""
    email = models.EmailField(max_length=255, unique=True)
    name = models.CharField(max_length=255)
    image = models.ImageField(null=True, upload_to=user_image_file_path)
    contact_no = models.CharField(max_length=255, default='')
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)

    objects = UserManager()

    USERNAME_FIELD = 'email'

How i can override my views so that I can get these two information. Any information will be great help. Thank you

Phoenix
  • 3,996
  • 4
  • 29
  • 40
Piyush
  • 492
  • 5
  • 22

1 Answers1

0

As you are want to change the default behavior of post response, you need to explicitly change that.

So how we can achieve that. We need to overwrite the post method of ObtainAuthToken. I hope following code will solve your problem.

from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.authtoken.models import Token
from rest_framework.response import Response

class CreateTokenView(ObtainAuthToken):
    serializer_class = AuthTokenSerializer
    renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES

    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data,
                                           context={'request': request})
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        token, created = Token.objects.get_or_create(user=user)
        return Response({
            'token': token.key,
            'is_staff': user.is_staff
        })

References: django-restframework example

Shakil
  • 4,520
  • 3
  • 26
  • 36
  • Its work as expected. But why we are using created variable. I did'nt got part – Piyush Sep 16 '19 at 07:06
  • get_or_create returns tuple, first one is object and second one is boolean created or not. so explicitly two variable needed here. – Shakil Sep 16 '19 at 07:07
  • And How I will check if the user is active or not, Because my code is not working there – Piyush Sep 16 '19 at 07:07
  • @Piyush what i can see, you properly raise validation error in serializer if user is not active. So thats should not a problem here. – Shakil Sep 16 '19 at 07:09
  • But that's not working. If user is inactive the response "Unable to authenticate with provided credentials" – Piyush Sep 16 '19 at 07:10
  • remove ( request=self.context.get('request'), ) from authenticate function argument. authenticate should have username and password. If i amnot wrong. – Shakil Sep 16 '19 at 07:11
  • @Piyush can you update your question with your User model. Seems like you change it. There must mention `USERNAME_FIELD = 'email``. – Shakil Sep 16 '19 at 07:17
  • I have added it. Please check – Piyush Sep 16 '19 at 07:31