# Path: knox/crypto.py
# def hash_token(token):
#     '''
#     Calculates the hash of a token.
#     input is unhexlified
# 
#     token must contain an even number of hex digits or a binascii.Error
#     exception will be raised
#     '''
#     digest = hashes.Hash(sha(), backend=default_backend())
#     digest.update(binascii.unhexlify(token))
#     return binascii.hexlify(digest.finalize()).decode()
# 
# Path: knox/models.py
# class AuthToken(models.Model):
# 
#     objects = AuthTokenManager()
# 
#     digest = models.CharField(
#         max_length=CONSTANTS.DIGEST_LENGTH, primary_key=True)
#     token_key = models.CharField(
#         max_length=CONSTANTS.TOKEN_KEY_LENGTH, db_index=True)
#     user = models.ForeignKey(User, null=False, blank=False,
#                              related_name='auth_token_set', on_delete=models.CASCADE)
#     created = models.DateTimeField(auto_now_add=True)
#     expiry = models.DateTimeField(null=True, blank=True)
# 
#     def __str__(self):
#         return '%s : %s' % (self.digest, self.user)
# 
# Path: knox/settings.py
# USER_SETTINGS = getattr(settings, 'REST_KNOX', None)
# DEFAULTS = {
#     'SECURE_HASH_ALGORITHM': 'cryptography.hazmat.primitives.hashes.SHA512',
#     'AUTH_TOKEN_CHARACTER_LENGTH': 64,
#     'TOKEN_TTL': timedelta(hours=10),
#     'USER_SERIALIZER': None,
#     'TOKEN_LIMIT_PER_USER': None,
#     'AUTO_REFRESH': False,
#     'MIN_REFRESH_INTERVAL': 60,
#     'AUTH_HEADER_PREFIX': 'Token',
#     'EXPIRY_DATETIME_FORMAT': api_settings.DATETIME_FORMAT,
# }
# IMPORT_STRINGS = {
#     'SECURE_HASH_ALGORITHM',
#     'USER_SERIALIZER',
# }
#     TOKEN_KEY_LENGTH = 8
#     DIGEST_LENGTH = 128
# CONSTANTS = CONSTANTS()
# def reload_api_settings(*args, **kwargs):
#     def __setattr__(self, *args, **kwargs):
# class CONSTANTS:
# 
# Path: knox/signals.py



    from hmac import compare_digest
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from rest_framework import exceptions
from rest_framework.authentication import (
    BaseAuthentication, get_authorization_header,
)
from knox.crypto import hash_token
from knox.models import AuthToken
from knox.settings import CONSTANTS, knox_settings
from knox.signals import token_expired
import binascii
    def renew_token(self, auth_token):
        current_expiry = auth_token.expiry
        new_expiry = timezone.now() + knox_settings.TOKEN_TTL
        auth_token.expiry = new_expiry
        # Throttle refreshing of token to avoid db writes
        delta = (new_expiry - current_expiry).total_seconds()
        if delta > knox_settings.MIN_REFRESH_INTERVAL:
            auth_token.save(update_fields=('expiry',))

    def validate_user(self, auth_token):
        if not auth_token.user.is_active:
            raise exceptions.AuthenticationFailed(
                _('User inactive or deleted.'))
        return (auth_token.user, auth_token)

    def authenticate_header(self, request):
        return knox_settings.AUTH_HEADER_PREFIX

    def _cleanup_token(self, auth_token):
        for other_token in auth_token.user.auth_token_set.all():
            if other_token.digest != auth_token.digest and other_token.expiry:
                if other_token.expiry < timezone.now():
                    other_token.delete()
                    username = other_token.user.get_username()
                    token_expired.send(sender=self.__class__,
                                       username=username, source="other_token")
        if auth_token.expiry is not None:
            if auth_token.expiry < timezone.now():
                username = auth_token.user.get_username()
                auth_token.delete()

# Path: knox/crypto.py
# def hash_token(token):
#     '''
#     Calculates the hash of a token.
#     input is unhexlified
# 
#     token must contain an even number of hex digits or a binascii.Error
#     exception will be raised
#     '''
#     digest = hashes.Hash(sha(), backend=default_backend())
#     digest.update(binascii.unhexlify(token))
#     return binascii.hexlify(digest.finalize()).decode()
# 
# Path: knox/models.py
# class AuthToken(models.Model):
# 
#     objects = AuthTokenManager()
# 
#     digest = models.CharField(
#         max_length=CONSTANTS.DIGEST_LENGTH, primary_key=True)
#     token_key = models.CharField(
#         max_length=CONSTANTS.TOKEN_KEY_LENGTH, db_index=True)
#     user = models.ForeignKey(User, null=False, blank=False,
#                              related_name='auth_token_set', on_delete=models.CASCADE)
#     created = models.DateTimeField(auto_now_add=True)
#     expiry = models.DateTimeField(null=True, blank=True)
# 
#     def __str__(self):
#         return '%s : %s' % (self.digest, self.user)
# 
# Path: knox/settings.py
# USER_SETTINGS = getattr(settings, 'REST_KNOX', None)
# DEFAULTS = {
#     'SECURE_HASH_ALGORITHM': 'cryptography.hazmat.primitives.hashes.SHA512',
#     'AUTH_TOKEN_CHARACTER_LENGTH': 64,
#     'TOKEN_TTL': timedelta(hours=10),
#     'USER_SERIALIZER': None,
#     'TOKEN_LIMIT_PER_USER': None,
#     'AUTO_REFRESH': False,
#     'MIN_REFRESH_INTERVAL': 60,
#     'AUTH_HEADER_PREFIX': 'Token',
#     'EXPIRY_DATETIME_FORMAT': api_settings.DATETIME_FORMAT,
# }
# IMPORT_STRINGS = {
#     'SECURE_HASH_ALGORITHM',
#     'USER_SERIALIZER',
# }
#     TOKEN_KEY_LENGTH = 8
#     DIGEST_LENGTH = 128
# CONSTANTS = CONSTANTS()
# def reload_api_settings(*args, **kwargs):
#     def __setattr__(self, *args, **kwargs):
# class CONSTANTS:
# 
# Path: knox/signals.py



# Path: knox/auth.py
    from hmac import compare_digest
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from rest_framework import exceptions
from rest_framework.authentication import (
    BaseAuthentication, get_authorization_header,
)
from knox.crypto import hash_token
from knox.models import AuthToken
from knox.settings import CONSTANTS, knox_settings
from knox.signals import token_expired
import binascii

    def renew_token(self, auth_token):
        current_expiry = auth_token.expiry
        new_expiry = timezone.now() + knox_settings.TOKEN_TTL
        auth_token.expiry = new_expiry
        # Throttle refreshing of token to avoid db writes
        delta = (new_expiry - current_expiry).total_seconds()
        if delta > knox_settings.MIN_REFRESH_INTERVAL:
            auth_token.save(update_fields=('expiry',))

    def validate_user(self, auth_token):
        if not auth_token.user.is_active:
            raise exceptions.AuthenticationFailed(
                _('User inactive or deleted.'))
        return (auth_token.user, auth_token)

    def authenticate_header(self, request):
        return knox_settings.AUTH_HEADER_PREFIX

    def _cleanup_token(self, auth_token):
        for other_token in auth_token.user.auth_token_set.all():
            if other_token.digest != auth_token.digest and other_token.expiry:
                if other_token.expiry < timezone.now():
                    other_token.delete()
                    username = other_token.user.get_username()
                    token_expired.send(sender=self.__class__,
                                       username=username, source="other_token")
        if auth_token.expiry is not None:
            if auth_token.expiry < timezone.now():
                username = auth_token.user.get_username()
                auth_token.delete()

                token_expired.send(sender=self.__class__,