Skip to content
Snippets Groups Projects
Commit 7768dd1d authored by Adeel Khan's avatar Adeel Khan
Browse files

Ratelimiting registration form validation end point.

This patch would ratelimit registration form validation
endpoint for anonymous user based on his/her ip.

LEARNER-3810
parent 947d8273
No related merge requests found
......@@ -2333,6 +2333,7 @@ REST_FRAMEWORK = {
'DEFAULT_THROTTLE_RATES': {
'user': '60/minute',
'service_user': '120/minute',
'registration_validation': '30/minute',
},
}
......
......@@ -574,6 +574,11 @@ ACTIVATION_EMAIL_FROM_ADDRESS = 'test_activate@edx.org'
TEMPLATES[0]['OPTIONS']['debug'] = True
########################### DRF default throttle rates ############################
# Increasing rates to enable test cases hitting registration view succesfully.
# Lower rate is causing view to get blocked, causing test case failure.
REST_FRAMEWORK['DEFAULT_THROTTLE_RATES']['registration_validation'] = '100/minute'
########################## VIDEO TRANSCRIPTS STORAGE ############################
VIDEO_TRANSCRIPTS_SETTINGS = dict(
VIDEO_TRANSCRIPTS_MAX_BYTES=3 * 1024 * 1024, # 3 MB
......
......@@ -9,11 +9,13 @@ import ddt
from django.conf import settings
from django.contrib.auth.models import User
from django.urls import reverse
from django.test.utils import override_settings
from six import text_type
from openedx.core.djangoapps.user_api import accounts
from openedx.core.djangoapps.user_api.accounts.tests import testutils
from openedx.core.lib.api import test_utils
from openedx.core.djangoapps.user_api.validation.views import RegistrationValidationThrottle
from util.password_policy_validators import password_max_length, password_min_length
......@@ -199,3 +201,24 @@ class RegistrationValidationViewTests(test_utils.ApiTestCase):
{"username": "somephrase", "password": "somephrase"},
{"username": "", "password": u"Password cannot be the same as the username."}
)
@override_settings(
CACHES={
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'registration_proxy',
}
}
)
def test_rate_limiting_registration_view(self):
"""
Confirm rate limits work as expected for registration
end point /api/user/v1/validation/registration/. Note
that drf's rate limiting makes use of the default cache
to enforce limits; that's why this test needs a "real"
default cache (as opposed to the usual-for-tests DummyCache)
"""
for _ in range(RegistrationValidationThrottle().num_requests):
self.request_without_auth('post', self.path)
response = self.request_without_auth('post', self.path)
self.assertEqual(response.status_code, 429)
......@@ -5,6 +5,7 @@ An API for client-side validation of (potential) user data.
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.throttling import AnonRateThrottle
from openedx.core.djangoapps.user_api.accounts.api import (
get_email_validation_error,
......@@ -16,6 +17,20 @@ from openedx.core.djangoapps.user_api.accounts.api import (
get_username_validation_error,
get_username_existence_validation_error
)
from ipware.ip import get_ip
class RegistrationValidationThrottle(AnonRateThrottle):
"""
Custom throttle rate for /api/user/v1/validation/registration
endpoint's use case.
"""
scope = 'registration_validation'
def get_ident(self, request):
client_ip = get_ip(request)
return client_ip
class RegistrationValidationView(APIView):
......@@ -106,6 +121,7 @@ class RegistrationValidationView(APIView):
# This end-point is available to anonymous users, so no authentication is needed.
authentication_classes = []
throttle_classes = (RegistrationValidationThrottle,)
def name_handler(self, request):
name = request.data.get('name')
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment