2020-06-03 12:49:38 +00:00
|
|
|
from django.utils import timezone
|
|
|
|
from django.utils.translation import gettext_lazy as _
|
2020-11-06 14:22:26 +00:00
|
|
|
from .. import app_settings
|
2020-06-03 12:49:38 +00:00
|
|
|
|
|
|
|
from rest_framework import exceptions
|
|
|
|
from rest_framework.authentication import TokenAuthentication as DRFTokenAuthentication
|
|
|
|
|
|
|
|
from .models import AuthToken, get_default_expiry
|
|
|
|
|
2020-11-06 14:22:26 +00:00
|
|
|
if app_settings.USE_LDAP:
|
|
|
|
from ..ldap import LDAPConnection
|
|
|
|
|
2020-06-03 12:49:38 +00:00
|
|
|
|
|
|
|
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)
|
|
|
|
|
2020-11-06 14:22:26 +00:00
|
|
|
if app_settings.USE_LDAP:
|
|
|
|
if not LDAPConnection.get_instance().has_user(token.user.username):
|
|
|
|
raise exceptions.AuthenticationFailed('User is not listed in the LDAP registry.')
|
|
|
|
|
2020-06-03 12:49:38 +00:00
|
|
|
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',))
|