From f13303e0ac4ba59b19f05a2346273ae234b9fc14 Mon Sep 17 00:00:00 2001 From: James Estevez Date: Mon, 11 Nov 2024 19:24:04 -0800 Subject: [PATCH] Set up ScopedRateThrottle for endpoint-specific rate limits (#3581) * fix: Update node and CI workflows - Update node version to latest LTS - Copy/paste pyjs dockerfile - temporarily ignore optional deps - Pytest no longer on PATH - Ignore tsc error - Remove coverage step - suppress eslint errors * Set up ScopedRateThrottle for endpoint-specific rate limits PR #3544 disabled ratelimiting for AdminAPI views. This change improves control over rate limits and helps prevent over-throttling. - Removed global throttles (`AnonRateThrottle`, `UserRateThrottle`) - Added `ScopedRateThrottle` to control rate limits per endpoint - Defined custom rate to protect AdminAPI endpoints from DoS @W-17141510 --- config/settings/base.py | 4 ++-- metadeploy/adminapi/api.py | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/config/settings/base.py b/config/settings/base.py index 55058d921..deaf164f8 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -456,12 +456,12 @@ def safe_key() -> str: "rest_framework.authentication.SessionAuthentication", ), 'DEFAULT_THROTTLE_CLASSES': [ - 'rest_framework.throttling.AnonRateThrottle', - 'rest_framework.throttling.UserRateThrottle' + 'rest_framework.throttling.ScopedRateThrottle', ], 'DEFAULT_THROTTLE_RATES': { 'anon': '4/second', 'user': '4/second', + 'admin_api': '150/minute', } } diff --git a/metadeploy/adminapi/api.py b/metadeploy/adminapi/api.py index 2e42eadaf..710238912 100644 --- a/metadeploy/adminapi/api.py +++ b/metadeploy/adminapi/api.py @@ -138,7 +138,7 @@ class Meta: class PlanTemplateViewSet(AdminAPIViewSet): model_name = "PlanTemplate" serializer_base = PlanTemplateSerializer - throttle_classes = [] + throttle_scope = 'admin_api' class PlanFilter(filters.FilterSet): @@ -151,27 +151,27 @@ class PlanViewSet(AdminAPIViewSet): model_name = "Plan" serializer_base = PlanSerializer filterset_class = PlanFilter - throttle_classes = [] + throttle_scope = 'admin_api' class PlanSlugViewSet(AdminAPIViewSet): model_name = "PlanSlug" - throttle_classes = [] + throttle_scope = 'admin_api' class VersionViewSet(AdminAPIViewSet): model_name = "Version" - throttle_classes = [] + throttle_scope = 'admin_api' class ProductCategoryViewSet(AdminAPIViewSet): model_name = "ProductCategory" - throttle_classes = [] + throttle_scope = 'admin_api' class AllowedListViewSet(AdminAPIViewSet): model_name = "AllowedList" - throttle_classes = [] + throttle_scope = 'admin_api' class AllowedListOrgSerializer(AdminAPISerializer): @@ -181,7 +181,7 @@ class AllowedListOrgSerializer(AdminAPISerializer): class AllowedListOrgViewSet(AdminAPIViewSet): model_name = "AllowedListOrg" serializer_base = AllowedListOrgSerializer - throttle_classes = [] + throttle_scope = 'admin_api' class TranslationViewSet(viewsets.ViewSet): @@ -201,7 +201,7 @@ class TranslationViewSet(viewsets.ViewSet): permission_classes = [IsAPIUser] model_name = "Translation" - throttle_classes = [] + throttle_scope = 'admin_api' def partial_update(self, request, pk=None): # Add or update a Translation record for each message