mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
dev: rest framework throttling (#4534)
This commit is contained in:
parent
4feec35773
commit
410f04c327
@ -55,6 +55,8 @@ AUTHENTICATION_ERROR_CODES = {
|
|||||||
"ADMIN_USER_ALREADY_EXIST": 5180,
|
"ADMIN_USER_ALREADY_EXIST": 5180,
|
||||||
"ADMIN_USER_DOES_NOT_EXIST": 5185,
|
"ADMIN_USER_DOES_NOT_EXIST": 5185,
|
||||||
"ADMIN_USER_DEACTIVATED": 5190,
|
"ADMIN_USER_DEACTIVATED": 5190,
|
||||||
|
# Rate limit
|
||||||
|
"RATE_LIMIT_EXCEEDED": 5900,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
|
# Third party imports
|
||||||
from rest_framework.views import exception_handler
|
from rest_framework.views import exception_handler
|
||||||
from rest_framework.exceptions import NotAuthenticated
|
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):
|
def auth_exception_handler(exc, context):
|
||||||
@ -9,4 +14,14 @@ def auth_exception_handler(exc, context):
|
|||||||
if isinstance(exc, NotAuthenticated):
|
if isinstance(exc, NotAuthenticated):
|
||||||
response.status_code = 401
|
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
|
return response
|
||||||
|
26
apiserver/plane/authentication/rate_limit.py
Normal file
26
apiserver/plane/authentication/rate_limit.py
Normal 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
|
||||||
|
)
|
@ -15,7 +15,7 @@ from plane.authentication.adapter.error import (
|
|||||||
AuthenticationException,
|
AuthenticationException,
|
||||||
AUTHENTICATION_ERROR_CODES,
|
AUTHENTICATION_ERROR_CODES,
|
||||||
)
|
)
|
||||||
|
from plane.authentication.rate_limit import AuthenticationThrottle
|
||||||
|
|
||||||
class EmailCheckSignUpEndpoint(APIView):
|
class EmailCheckSignUpEndpoint(APIView):
|
||||||
|
|
||||||
@ -23,6 +23,10 @@ class EmailCheckSignUpEndpoint(APIView):
|
|||||||
AllowAny,
|
AllowAny,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
throttle_classes = [
|
||||||
|
AuthenticationThrottle,
|
||||||
|
]
|
||||||
|
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
try:
|
try:
|
||||||
# Check instance configuration
|
# Check instance configuration
|
||||||
@ -86,6 +90,10 @@ class EmailCheckSignInEndpoint(APIView):
|
|||||||
AllowAny,
|
AllowAny,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
throttle_classes = [
|
||||||
|
AuthenticationThrottle,
|
||||||
|
]
|
||||||
|
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
try:
|
try:
|
||||||
# Check instance configuration
|
# Check instance configuration
|
||||||
|
@ -32,7 +32,7 @@ from plane.authentication.adapter.error import (
|
|||||||
AuthenticationException,
|
AuthenticationException,
|
||||||
AUTHENTICATION_ERROR_CODES,
|
AUTHENTICATION_ERROR_CODES,
|
||||||
)
|
)
|
||||||
|
from plane.authentication.rate_limit import AuthenticationThrottle
|
||||||
|
|
||||||
def generate_password_token(user):
|
def generate_password_token(user):
|
||||||
uidb64 = urlsafe_base64_encode(smart_bytes(user.id))
|
uidb64 = urlsafe_base64_encode(smart_bytes(user.id))
|
||||||
@ -46,6 +46,10 @@ class ForgotPasswordEndpoint(APIView):
|
|||||||
AllowAny,
|
AllowAny,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
throttle_classes = [
|
||||||
|
AuthenticationThrottle,
|
||||||
|
]
|
||||||
|
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
email = request.data.get("email")
|
email = request.data.get("email")
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ from plane.authentication.adapter.error import (
|
|||||||
AUTHENTICATION_ERROR_CODES,
|
AUTHENTICATION_ERROR_CODES,
|
||||||
AuthenticationException,
|
AuthenticationException,
|
||||||
)
|
)
|
||||||
|
from plane.authentication.rate_limit import AuthenticationThrottle
|
||||||
|
|
||||||
class EmailCheckEndpoint(APIView):
|
class EmailCheckEndpoint(APIView):
|
||||||
|
|
||||||
@ -23,6 +23,10 @@ class EmailCheckEndpoint(APIView):
|
|||||||
AllowAny,
|
AllowAny,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
throttle_classes = [
|
||||||
|
AuthenticationThrottle,
|
||||||
|
]
|
||||||
|
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
# Check instance configuration
|
# Check instance configuration
|
||||||
instance = Instance.objects.first()
|
instance = Instance.objects.first()
|
||||||
|
@ -32,6 +32,7 @@ from plane.authentication.adapter.error import (
|
|||||||
AuthenticationException,
|
AuthenticationException,
|
||||||
AUTHENTICATION_ERROR_CODES,
|
AUTHENTICATION_ERROR_CODES,
|
||||||
)
|
)
|
||||||
|
from plane.authentication.rate_limit import AuthenticationThrottle
|
||||||
|
|
||||||
|
|
||||||
def generate_password_token(user):
|
def generate_password_token(user):
|
||||||
@ -46,6 +47,10 @@ class ForgotPasswordSpaceEndpoint(APIView):
|
|||||||
AllowAny,
|
AllowAny,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
throttle_classes = [
|
||||||
|
AuthenticationThrottle,
|
||||||
|
]
|
||||||
|
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
email = request.data.get("email")
|
email = request.data.get("email")
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user