from django.utils import timezone from django.utils.translation import gettext_lazy as _ from rest_framework import exceptions from rest_framework.authentication import TokenAuthentication as DRFTokenAuthentication from .models import AuthToken, get_default_expiry AUTO_REFRESH = True MIN_REFRESH_INTERVAL = 60 class TokenAuthentication(DRFTokenAuthentication): keyword = 'Token' model = AuthToken def authenticate_credentials(self, key): msg = _('Invalid token.') model = self.get_model() try: token = model.objects.select_related('user').get(key=key) except model.DoesNotExist: raise exceptions.AuthenticationFailed(msg) if not token.user.is_active: raise exceptions.AuthenticationFailed(_('User inactive or deleted.')) if token.expiry is not None: if token.expiry < timezone.now(): token.delete() raise exceptions.AuthenticationFailed(msg) if AUTO_REFRESH: self.renew_token(token) return (token.user, token) def renew_token(self, auth_token): current_expiry = auth_token.expiry new_expiry = get_default_expiry() # Throttle refreshing of token to avoid db writes delta = (new_expiry - current_expiry).total_seconds() if delta > MIN_REFRESH_INTERVAL: auth_token.expiry = new_expiry auth_token.save(update_fields=('expiry',))