dev: rest framework throttling (#4534)

This commit is contained in:
Nikhil 2024-05-21 15:03:01 +05:30 committed by GitHub
parent 4feec35773
commit 410f04c327
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 67 additions and 3 deletions

View File

@ -55,6 +55,8 @@ AUTHENTICATION_ERROR_CODES = {
"ADMIN_USER_ALREADY_EXIST": 5180,
"ADMIN_USER_DOES_NOT_EXIST": 5185,
"ADMIN_USER_DEACTIVATED": 5190,
# Rate limit
"RATE_LIMIT_EXCEEDED": 5900,
}

View File

@ -1,5 +1,10 @@
# Third party imports
from rest_framework.views import exception_handler
from rest_framework.exceptions import NotAuthenticated
from rest_framework.exceptions import Throttled
# Module imports
from plane.authentication.adapter.error import AuthenticationException, AUTHENTICATION_ERROR_CODES
def auth_exception_handler(exc, context):
@ -9,4 +14,14 @@ def auth_exception_handler(exc, context):
if isinstance(exc, NotAuthenticated):
response.status_code = 401
# Check if an Throttled exception is raised.
if isinstance(exc, Throttled):
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES["RATE_LIMIT_EXCEEDED"],
error_message="RATE_LIMIT_EXCEEDED",
)
response.data = exc.get_error_dict()
response.status_code = 429
# Return the response that is generated by the default exception handler.
return response

View File

@ -0,0 +1,26 @@
# Third party imports
from rest_framework.throttling import AnonRateThrottle
from rest_framework import status
from rest_framework.response import Response
# Module imports
from plane.authentication.adapter.error import (
AuthenticationException,
AUTHENTICATION_ERROR_CODES,
)
class AuthenticationThrottle(AnonRateThrottle):
rate = "30/minute"
scope = "authentication"
def throttle_failure_view(self, request, *args, **kwargs):
try:
raise AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES["RATE_LIMIT_EXCEEDED"],
error_message="RATE_LIMIT_EXCEEDED",
)
except AuthenticationException as e:
return Response(
e.get_error_dict(), status=status.HTTP_429_TOO_MANY_REQUESTS
)

View File

@ -15,7 +15,7 @@ from plane.authentication.adapter.error import (
AuthenticationException,
AUTHENTICATION_ERROR_CODES,
)
from plane.authentication.rate_limit import AuthenticationThrottle
class EmailCheckSignUpEndpoint(APIView):
@ -23,6 +23,10 @@ class EmailCheckSignUpEndpoint(APIView):
AllowAny,
]
throttle_classes = [
AuthenticationThrottle,
]
def post(self, request):
try:
# Check instance configuration
@ -86,6 +90,10 @@ class EmailCheckSignInEndpoint(APIView):
AllowAny,
]
throttle_classes = [
AuthenticationThrottle,
]
def post(self, request):
try:
# Check instance configuration

View File

@ -32,7 +32,7 @@ from plane.authentication.adapter.error import (
AuthenticationException,
AUTHENTICATION_ERROR_CODES,
)
from plane.authentication.rate_limit import AuthenticationThrottle
def generate_password_token(user):
uidb64 = urlsafe_base64_encode(smart_bytes(user.id))
@ -46,6 +46,10 @@ class ForgotPasswordEndpoint(APIView):
AllowAny,
]
throttle_classes = [
AuthenticationThrottle,
]
def post(self, request):
email = request.data.get("email")

View File

@ -15,7 +15,7 @@ from plane.authentication.adapter.error import (
AUTHENTICATION_ERROR_CODES,
AuthenticationException,
)
from plane.authentication.rate_limit import AuthenticationThrottle
class EmailCheckEndpoint(APIView):
@ -23,6 +23,10 @@ class EmailCheckEndpoint(APIView):
AllowAny,
]
throttle_classes = [
AuthenticationThrottle,
]
def post(self, request):
# Check instance configuration
instance = Instance.objects.first()

View File

@ -32,6 +32,7 @@ from plane.authentication.adapter.error import (
AuthenticationException,
AUTHENTICATION_ERROR_CODES,
)
from plane.authentication.rate_limit import AuthenticationThrottle
def generate_password_token(user):
@ -46,6 +47,10 @@ class ForgotPasswordSpaceEndpoint(APIView):
AllowAny,
]
throttle_classes = [
AuthenticationThrottle,
]
def post(self, request):
email = request.data.get("email")