From bbd21b456b9fe5b5d1ae701912ec9503e4038c1d Mon Sep 17 00:00:00 2001 From: Mike VanDenburgh Date: Wed, 20 Mar 2024 16:01:11 -0400 Subject: [PATCH] Rate limit assets list endpoint for logged out users --- dandiapi/api/views/asset.py | 8 ++++++++ dandiapi/settings.py | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/dandiapi/api/views/asset.py b/dandiapi/api/views/asset.py index 34d35e8f1..26c09a9dc 100644 --- a/dandiapi/api/views/asset.py +++ b/dandiapi/api/views/asset.py @@ -36,6 +36,7 @@ from rest_framework.exceptions import NotAuthenticated, NotFound, PermissionDenied from rest_framework.generics import get_object_or_404 from rest_framework.response import Response +from rest_framework.throttling import AnonRateThrottle, BaseThrottle from rest_framework.viewsets import GenericViewSet, ReadOnlyModelViewSet from rest_framework_extensions.mixins import DetailSerializerMixin, NestedViewSetMixin @@ -82,6 +83,13 @@ class AssetViewSet(DetailSerializerMixin, GenericViewSet): filter_backends = [filters.DjangoFilterBackend] filterset_class = AssetFilter + def get_throttles(self) -> list[BaseThrottle]: + # Throttle the asset list endpoint for unauthenticated users to prevent it from + # slowing down the rest of the system. + if self.action == 'list': + return [*self.throttle_classes, AnonRateThrottle] + return super().get_throttles() + def raise_if_unauthorized(self): # We need to check the dandiset to see if it's embargoed, and if so whether or not the # user has ownership diff --git a/dandiapi/settings.py b/dandiapi/settings.py index 0ba65368f..0db248abd 100644 --- a/dandiapi/settings.py +++ b/dandiapi/settings.py @@ -181,6 +181,11 @@ def mutate_configuration(configuration: type[ComposedConfiguration]): # We're configuring sentry by hand since we need to pass custom options (traces_sampler). configuration.INSTALLED_APPS.remove('composed_configuration.sentry.apps.SentryConfig') + # We only want rate-limiting enabled in production + configuration.REST_FRAMEWORK['DEFAULT_THROTTLE_RATES'] = { + 'anon': '60/minute', + } + ENABLE_GITHUB_OAUTH = True # All login attempts in production should go straight to GitHub