from django.contrib.auth.models import AnonymousUser
from rest_framework.authentication import BasicAuthentication
from rest_framework.exceptions import AuthenticationFailed

from sentry.models import ProjectKey


class KeyAuthentication(BasicAuthentication):
    def authenticate_credentials(self, userid, password):
        try:
            pk = ProjectKey.objects.get_from_cache(public_key=userid)
        except ProjectKey.DoesNotExist:
            raise AuthenticationFailed('Invalid api key')

        if pk.secret_key != password:
            raise AuthenticationFailed('Invalid api key')

        if not pk.roles.api:
            raise AuthenticationFailed('Key does not allow API access')

        return (AnonymousUser(), pk)

    def authenticate_header(self, request):
        return 'xBasic realm="%s"' % self.www_authenticate_realm


class QuietBasicAuthentication(BasicAuthentication):
    def authenticate_header(self, request):
        return 'xBasic realm="%s"' % self.www_authenticate_realm

from django.contrib.auth.models import AnonymousUser
from django.utils.crypto import constant_time_compare

from rest_framework.authentication import BasicAuthentication
from rest_framework.exceptions import AuthenticationFailed

from sentry.models import ProjectKey


class KeyAuthentication(BasicAuthentication):
    def authenticate_credentials(self, userid, password):
        try:
            pk = ProjectKey.objects.get_from_cache(public_key=userid)
        except ProjectKey.DoesNotExist:
            raise AuthenticationFailed('Invalid api key')

        if not constant_time_compare(pk.secret_key, password):
            raise AuthenticationFailed('Invalid api key')

        if not pk.roles.api:
            raise AuthenticationFailed('Key does not allow API access')

        return (AnonymousUser(), pk)

    def authenticate_header(self, request):
        return 'xBasic realm="%s"' % self.www_authenticate_realm


class QuietBasicAuthentication(BasicAuthentication):
    def authenticate_header(self, request):
        return 'xBasic realm="%s"' % self.www_authenticate_realm

Use a constant time comparison in the API auth
Use a constant time comparison in the API auth