From 6d175c0e56d0ed66a3133a7b36da7ec8ace69938 Mon Sep 17 00:00:00 2001 From: Bavisetti Narayan <72156168+NarayanBavisetti@users.noreply.github.com> Date: Wed, 29 Nov 2023 14:14:26 +0530 Subject: [PATCH] chore: api rate limiting (#2933) --- apiserver/plane/api/rate_limit.py | 8 ++---- apiserver/plane/app/rate_limit.py | 45 ------------------------------ apiserver/plane/settings/common.py | 4 --- 3 files changed, 2 insertions(+), 55 deletions(-) delete mode 100644 apiserver/plane/app/rate_limit.py diff --git a/apiserver/plane/api/rate_limit.py b/apiserver/plane/api/rate_limit.py index 617baa62c..f91e2d65d 100644 --- a/apiserver/plane/api/rate_limit.py +++ b/apiserver/plane/api/rate_limit.py @@ -1,9 +1,8 @@ -from django.utils import timezone from rest_framework.throttling import SimpleRateThrottle - class ApiKeyRateThrottle(SimpleRateThrottle): scope = 'api_key' + rate = '60/minute' def get_cache_key(self, request, view): # Retrieve the API key from the request header @@ -15,13 +14,10 @@ class ApiKeyRateThrottle(SimpleRateThrottle): return f'{self.scope}:{api_key}' def allow_request(self, request, view): - # Calculate the current time as a Unix timestamp - now = timezone.now().timestamp() - - # Use the parent class's method to check if the request is allowed allowed = super().allow_request(request, view) if allowed: + now = self.timer() # Calculate the remaining limit and reset time history = self.cache.get(self.key, []) diff --git a/apiserver/plane/app/rate_limit.py b/apiserver/plane/app/rate_limit.py deleted file mode 100644 index 16fce639d..000000000 --- a/apiserver/plane/app/rate_limit.py +++ /dev/null @@ -1,45 +0,0 @@ -from django.utils import timezone -from rest_framework.throttling import SimpleRateThrottle - - -class ApiKeyRateThrottle(SimpleRateThrottle): - scope = 'api_key' - - def get_cache_key(self, request, view): - # Retrieve the API key from the request header - api_key = request.headers.get('X-Api-Key') - if not api_key: - return None # Allow the request if there's no API key - - # Use the API key as part of the cache key - return f'{self.scope}:{api_key}' - - def allow_request(self, request, view): - # Calculate the current time as a Unix timestamp - now = timezone.now().timestamp() - - # Use the parent class's method to check if the request is allowed - allowed = super().allow_request(request, view) - - if allowed: - # Calculate the remaining limit and reset time - history = self.cache.get(self.key, []) - - # Remove old histories - while history and history[-1] <= now - self.duration: - history.pop() - - # Calculate the requests - num_requests = len(history) - - # Check available requests - available = self.num_requests - num_requests - - # Unix timestamp for when the rate limit will reset - reset_time = int(now + self.duration) - - # Add headers - request.META['X-RateLimit-Remaining'] = max(0, available) - request.META['X-RateLimit-Reset'] = reset_time - - return allowed diff --git a/apiserver/plane/settings/common.py b/apiserver/plane/settings/common.py index b8998a87e..79c175eb2 100644 --- a/apiserver/plane/settings/common.py +++ b/apiserver/plane/settings/common.py @@ -75,10 +75,6 @@ REST_FRAMEWORK = { "DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",), "DEFAULT_RENDERER_CLASSES": ("rest_framework.renderers.JSONRenderer",), "DEFAULT_FILTER_BACKENDS": ("django_filters.rest_framework.DjangoFilterBackend",), - "DEFAULT_THROTTLE_CLASSES": ("plane.api.rate_limit.ApiKeyRateThrottle",), - "DEFAULT_THROTTLE_RATES": { - "api_key": "60/minute", - }, } # Django Auth Backend