def validate(self, attrs): credentials = { self.username_field: attrs.get(self.username_field), 'password': attrs.get('password') } if all(credentials.values()): request = self.context['request'] if is_already_locked(request): raise exceptions.Throttled( 600, 'Too many failed password attempts.' ) user = authenticate(request, **credentials) if user: if not user.is_active: msg = _('User account is disabled.') raise serializers.ValidationError(msg) payload = jwt_payload_handler(user) return { 'token': jwt_encode_handler(payload), 'user': user } else: msg = _('Unable to log in with provided credentials.') raise serializers.ValidationError(msg) else: msg = _('Must include "{username_field}" and "password".') msg = msg.format(username_field=self.username_field) raise serializers.ValidationError(msg)
def test_throttled_exception() -> None: response = exception_handler(exceptions.Throttled(62)) assert response is not None assert response.status_code == status.HTTP_429_TOO_MANY_REQUESTS assert response.data == { "type": "throttled_error", "code": "throttled", "detail": "Request was throttled. Expected available in 62 seconds.", "attr": None, }
def wrapper(*args, **kwargs): try: return func(*args, **kwargs) except stripe.error.RateLimitError as e: raise api_exceptions.Throttled(detail=e._message) except stripe.error.APIConnectionError as e: raise exceptions.PaymentGatewayUnavailable(detail=e._message) except stripe.error.InvalidRequestError as e: raise api_exceptions.ValidationError(detail=e.json_body) except stripe.StripeError as e: raise exceptions.PaymentFailed(detail=e._message)
def create(self, request, *args, **kwargs): from biohub.core.conf import settings as biohub_settings from datetime import timedelta from django.utils.timezone import now user = self.request.user if Post.objects.filter( author=user, pub_time__gte=now() - timedelta(seconds=biohub_settings.THROTTLE['post']) ).exists(): raise exceptions.Throttled() return super(PostViewSet, self).create(request, *args, **kwargs)
def test_drf_exception_in_debug(settings) -> None: settings.DEBUG = True # Exception is handled as usual with the exceptions_hog handler response = exception_handler(exceptions.Throttled(28)) assert response is not None assert response.status_code == status.HTTP_429_TOO_MANY_REQUESTS assert response.data == { "type": "throttled_error", "code": "throttled", "detail": "Request was throttled. Expected available in 28 seconds.", "attr": None, }
def validate(self, email, code): if not short_code_generator.is_allowed_pattern(code): raise exceptions.ValidationError( detail={"code": self.messages["invalid_format"]}, code="invalid_format" ) if not check_short_code_bucket.has_tokens(email): raise exceptions.Throttled( detail=self.messages["throttled"], code="throttled" ) role = authenticate(email=email, short_code=code) if not role: raise exceptions.ValidationError( detail={"code": self.messages["invalid_code"]}, code="invalid_code" ) return role
def post(self, request, pk, *args, **kwargs): node = get_object_or_404(Node, pk=pk) data = request.DATA or {} errors = {} kwargs = {} fw_config = NodeFirmwareConfigSerializer(node, data=data) if fw_config.is_valid(): kwargs.update(fw_config.data) else: errors.update(fw_config.errors) # get plugins configuration config = Config.objects.get() for plugin in config.plugins.active(): serializer_class = plugin.instance.get_serializer() if serializer_class: serializer = serializer_class(node, data=data) if serializer.is_valid(): kwargs.update(serializer.process_post()) else: errors.update(serializer.errors) if errors: raise exceptions.ParseError(detail=errors) # initialize firmware configuration base_image = BaseImage.objects.get(pk=kwargs.pop('base_image_id')) async = True success_status = status.HTTP_202_ACCEPTED # allow asynchronous requests if '201-created' == request.META.get('HTTP_EXPECT', None): async = False success_status = status.HTTP_201_CREATED # call firmware build task try: build = Build.build(node, base_image, async=async, **kwargs) except ConcurrencyError as e: raise exceptions.Throttled(detail=e.message) serializer = self.serializer_class(build) return Response(serializer.data, status=success_status)
def validate(self, email): try: validate_email(email) except ValidationError: raise exceptions.ValidationError( detail={"email": self.messages["invalid_format"]}, code="invalid_format" ) if settings.DEBUG: return client_ip = get_client_ip(self.request) if not send_mail_email_bucket.has_tokens( email ) or not send_mail_ip_bucket.has_tokens(client_ip): raise exceptions.Throttled( detail=self.messages["throttled"], code="throttled" )
def throttled(self, request, wait): """ If request is throttled, determine what kind of exception to raise. """ raise exceptions.Throttled(wait)
class ThrottledView(BaseErrorView): exception = exceptions.Throttled(detail="Too many requests")
def list(self, request, *args, **kwargs): raise exceptions.Throttled()
import pytest from rest_framework import exceptions as rest_exceptions from exception_dispatcher.dispatchers import rest_framework as handlers class _TestAuthenticationException(rest_exceptions.AuthenticationFailed): auth_header = 'Bearer realm="Access testing API"' @pytest.mark.parametrize(('exception', 'expected_headers'), [ (rest_exceptions.ParseError(), {}), (rest_exceptions.Throttled(wait=120), { 'Retry-After': '120' }), ( _TestAuthenticationException(), { 'WWW-Authenticate': _TestAuthenticationException.auth_header }, ), ]) def test_response_headers(exception, expected_headers): """Ensure response with expected headers is returned.""" response = handlers.handle_rest_framework_api_exception(exception, {}) assert set(expected_headers.items()) <= set(response.items()) def test_response_data(): """Ensure response with expected data is returned."""
from exception_dispatcher.handlers import exception_handler @pytest.mark.parametrize( 'exception', [ exceptions.APIException('detail', 'code'), exceptions.AuthenticationFailed(), exceptions.MethodNotAllowed('GET'), exceptions.NotAcceptable(), exceptions.NotAuthenticated(), exceptions.NotFound(), exceptions.ParseError(), exceptions.PermissionDenied(), exceptions.Throttled(), exceptions.UnsupportedMediaType('application/vnd.skarzi+json'), exceptions.ValidationError(), # special cases of `django` exceptions PermissionDenied(), Http404(), ]) def test_rest_framework_exception(exception): """Ensure response returned by our and rest_framework handler are equal.""" rest_framework_response = rest_exception_handler(exception, {}) response = exception_handler(exception, {}) assert rest_framework_response assert response assert response.status_code == rest_framework_response.status_code