fix: login endpoint username param rate limiting (#30673)

The username was allowed in the login endpoint alongside the email address
but rate-limiting logic was not updated to rate limit on the new POST
param `email_or_username`.

VAN-1003
This commit is contained in:
Waheed Ahmad
2022-06-30 15:24:19 +05:00
committed by GitHub
parent 9e1b46b58b
commit fb604e4345
4 changed files with 69 additions and 2 deletions

View File

@@ -52,3 +52,23 @@ def request_data_email(group, request) -> str: # pylint: disable=unused-argumen
email = str(uuid4())
return email
def request_post_email_or_username(group, request) -> str: # pylint: disable=unused-argument
"""
Return the the email or email_or_username post param if it exists, otherwise return a
random id.
If the request doesn't have an email or email_or_username post body param, treat it as
a unique key. This will probably mean that it will not get rate limited.
This ratelimit key function is meant to be used with the user_authn/views/login.py::login_user
function. To rate-limit any first party auth. For 3rd party auth, there is separate rate limiting
currently in place so we don't do any rate limiting for that case here.
"""
email_or_username = request.POST.get('email_or_username') or request.POST.get('email')
if not email_or_username:
email_or_username = str(uuid4())
return email_or_username

View File

@@ -46,3 +46,32 @@ class TestRateLimiting(TestCase):
"""
XForwardedForMiddleware().process_request(self.request)
assert ratelimit.real_ip(None, self.request) == '7.8.9.0'
def test_request_post_email(self):
"""
Tests post email param.
"""
expected_email = 'test@example.com'
self.request.POST = {'email': expected_email}
assert ratelimit.request_post_email(None, self.request) == expected_email
def test_request_data_email(self):
"""
Tests data email param.
"""
expected_email = 'test@example.com'
self.request.data = {'email': expected_email}
assert ratelimit.request_data_email(None, self.request) == expected_email
@ddt.data(
('email', 'test@example.com'),
('email_or_username', 'testUsername8967'),
('email_or_username', 'testUsername@example.com')
)
@ddt.unpack
def test_request_post_email_or_username(self, param_name, expected_username_or_email):
"""
Tests post email_or_username param.
"""
self.request.POST = {param_name: expected_username_or_email}
assert ratelimit.request_post_email_or_username(None, self.request) == expected_username_or_email