feat: added feature to rate limit secondary email change (#37356)
This commit is contained in:
committed by
GitHub
parent
8126142836
commit
51a254a45c
@@ -1110,6 +1110,37 @@ class TestAccountsAPI(FilteredQueryCountMixin, CacheIsolationTestCase, UserAPITe
|
||||
field_errors['email']['developer_message']
|
||||
assert 'Valid e-mail address required.' == field_errors['email']['user_message']
|
||||
|
||||
@override_settings(SECONDARY_EMAIL_RATE_LIMIT='1/m')
|
||||
def test_patch_secondary_email_ratelimit(self):
|
||||
"""
|
||||
Tests if rate limit is applied on secondary_email patch
|
||||
"""
|
||||
client = self.login_client("client", "user")
|
||||
self.send_patch(client, {"secondary_email": "new_email_01@example.com"},
|
||||
expected_status=status.HTTP_200_OK)
|
||||
self.send_patch(client, {"secondary_email": "new_email_02@example.com"},
|
||||
expected_status=status.HTTP_429_TOO_MANY_REQUESTS)
|
||||
|
||||
@override_settings(SECONDARY_EMAIL_RATE_LIMIT='')
|
||||
def test_ratelimit_is_disabled_on_secondary_email_patch_if_settings_is_empty(self):
|
||||
"""
|
||||
Tests rate limit doesn't applied on secondary_email patch if SECONDARY_EMAIL_RATE_LIMIT is empty string or None
|
||||
"""
|
||||
client = self.login_client("client", "user")
|
||||
self.send_patch(client, {"secondary_email": "email_new_01@example.com"},
|
||||
expected_status=status.HTTP_200_OK)
|
||||
self.send_patch(client, {"secondary_email": "email_new_02@example.com"},
|
||||
expected_status=status.HTTP_200_OK)
|
||||
|
||||
@override_settings(SECONDARY_EMAIL_RATE_LIMIT='1/d')
|
||||
def test_ratelimit_is_only_on_secondary_email_change(self):
|
||||
"""
|
||||
Tests if rate limit is only applied for secondary_email attribute i.e. when user changes recovery email
|
||||
"""
|
||||
client = self.login_client("client", "user")
|
||||
for i in range(5):
|
||||
self.send_patch(client, {"name": f"new_name_{i}"}, expected_status=status.HTTP_200_OK)
|
||||
|
||||
@mock.patch('common.djangoapps.student.views.management.do_email_change_request')
|
||||
def test_patch_duplicate_email(self, do_email_change_request):
|
||||
"""
|
||||
|
||||
@@ -396,12 +396,17 @@ class AccountViewSet(ViewSet):
|
||||
"""
|
||||
if request.content_type != MergePatchParser.media_type:
|
||||
raise UnsupportedMediaType(request.content_type)
|
||||
if request.data.get("email") and settings.EMAIL_CHANGE_RATE_LIMIT:
|
||||
if is_ratelimited(
|
||||
request=request, group="email_change_rate_limit", key="user",
|
||||
rate=settings.EMAIL_CHANGE_RATE_LIMIT, increment=True,
|
||||
):
|
||||
return Response({"error": "Too many requests"}, status=status.HTTP_429_TOO_MANY_REQUESTS)
|
||||
|
||||
for key, limit in [
|
||||
('email', settings.EMAIL_CHANGE_RATE_LIMIT),
|
||||
('secondary_email', settings.SECONDARY_EMAIL_RATE_LIMIT)
|
||||
]:
|
||||
if request.data.get(key) and limit:
|
||||
if is_ratelimited(
|
||||
request=request, group=f"{key}_change_rate_limit", key="user",
|
||||
rate=limit, increment=True,
|
||||
):
|
||||
return Response({"error": "Too many requests"}, status=status.HTTP_429_TOO_MANY_REQUESTS)
|
||||
|
||||
try:
|
||||
with transaction.atomic():
|
||||
|
||||
@@ -830,6 +830,7 @@ SKIP_RATE_LIMIT_ON_ACCOUNT_AFTER_DAYS = 0
|
||||
|
||||
ONE_CLICK_UNSUBSCRIBE_RATE_LIMIT = '100/m'
|
||||
EMAIL_CHANGE_RATE_LIMIT = ''
|
||||
SECONDARY_EMAIL_RATE_LIMIT = ''
|
||||
|
||||
LMS_ROOT_URL = None
|
||||
LMS_INTERNAL_ROOT_URL = Derived(lambda settings: settings.LMS_ROOT_URL)
|
||||
|
||||
Reference in New Issue
Block a user