PietroPutelli
PietroPutelli

Reputation: 572

Django Rest Framework authentication class override request.user

in my django App I have created a custom Authentication class using rest_framework:

from business.models import BusinessToken
from rest_framework.authtoken.models import Token
from rest_framework import authentication, exceptions


class AuthenticationMixin(authentication.BaseAuthentication):
    def authenticate(self, request):
        raw_token = request.META.get('HTTP_AUTHORIZATION')

        if not raw_token:
            return None

        token_key = raw_token.replace("Token ", "")

        user_token = Token.objects.filter(key=token_key).first()

        if user_token is not None:
            user = user_token.user
            request.user = user

            return user, None

        business_token = BusinessToken.objects.filter(key=token_key).first()

        if business_token is not None:
            business = business_token.business

            request.business = business

            user = business.owner

            request.user = user

            return business, None
        raise exceptions.AuthenticationFailed('No such user or business')

As you can see the class has to authenticate the user or the business based on the token pass from http request.

If the user authenticate itself through the business token in the api view I have to access to request.user as the business.owner and request.business as the business, but request.user is set to business, it's override somewhere.

Upvotes: 2

Views: 579

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477607

The first item of the 2-tuple is the user, and Django will use this to set the user. By returning the business, you would thus set that as request.user. You thus should return the business owner, and set (only) request.business:

class AuthenticationMixin(authentication.BaseAuthentication):
    def authenticate(self, request):
        raw_token = request.META.get('HTTP_AUTHORIZATION')

        if not raw_token:
            return None, None

        token_key = raw_token.replace('Token ', '')

        try:
            user_token = Token.objects.select_related('user').get(key=token_key)
            user = user_token.user
            return user, None
        except Token.DoesNotExist:
            pass
        try:
            business_token = BusinessToken.objects.select_related(
                'business__owner'
            ).get(key=token_key)
            business = business_token.business
            request.business = business
            return business.owner, None
        except BusinessToken.DoesNotExist:
            raise exceptions.AuthenticationFailed('No such user or business')

Upvotes: 1

Related Questions