Skip to content
Snippets Groups Projects
Commit 74bc970e authored by Waheed Ahmed's avatar Waheed Ahmed
Browse files

Rate limit logistration endpoints.

PROD-1506
parent 2d2015f4
Branches
Tags
No related merge requests found
......@@ -7,6 +7,7 @@ import logging
import six
from django.conf import settings
from django.contrib import messages
from django.http import HttpResponseForbidden
from django.shortcuts import redirect
from django.urls import reverse
from django.utils.translation import ugettext as _
......@@ -34,6 +35,7 @@ from student.helpers import get_next_url_for_login_page
from third_party_auth import pipeline
from third_party_auth.decorators import xframe_allow_whitelisted
from util.password_policy_validators import DEFAULT_MAX_PASSWORD_LENGTH
from util.request_rate_limiter import BadRequestRateLimiter
log = logging.getLogger(__name__)
......@@ -135,6 +137,12 @@ def login_and_registration_form(request, initial_mode="login"):
initial_mode (string): Either "login" or "register".
"""
limiter = BadRequestRateLimiter()
if limiter.is_rate_limit_exceeded(request):
log.warning("Rate limit exceeded in login and registration with initial mode [%s]", initial_mode)
return HttpResponseForbidden("Rate limit exceeded")
# Determine the URL to redirect to following login/registration/third_party_auth
redirect_to = get_next_url_for_login_page(request)
......@@ -230,6 +238,8 @@ def login_and_registration_form(request, initial_mode="login"):
response = render_to_response('student_account/login_and_register.html', context)
handle_enterprise_cookies_for_logistration(request, response, context)
limiter.tick_request_counter(request)
return response
......
# -*- coding: utf-8 -*-
""" Tests for Logistration views. """
from datetime import datetime, timedelta
from http.cookies import SimpleCookie
import ddt
......@@ -17,6 +17,8 @@ from django.test.client import RequestFactory
from django.test.utils import override_settings
from django.urls import reverse
from django.utils.translation import ugettext as _
from freezegun import freeze_time
from pytz import UTC
from six.moves.urllib.parse import urlencode # pylint: disable=import-error
from course_modes.models import CourseMode
......@@ -71,6 +73,25 @@ class LoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMixin, ModuleSto
expected_data = u'"initial_mode": "{mode}"'.format(mode=initial_mode)
self.assertContains(response, expected_data)
def test_login_and_registration_form_ratelimited(self):
"""
Test that login enpoint allow only 30 requests for every 5 minutes.
"""
login_url = reverse('signin_user')
for i in range(30):
response = self.client.get(login_url)
self.assertEqual(response.status_code, 200)
# then the rate limiter should kick in and give a HttpForbidden response
response = self.client.get(login_url)
self.assertEqual(response.status_code, 403)
# now reset the time to 6 mins from now in future in order to unblock
reset_time = datetime.now(UTC) + timedelta(seconds=361)
with freeze_time(reset_time):
response = self.client.get(login_url)
self.assertEqual(response.status_code, 200)
@ddt.data("signin_user", "register_user")
def test_login_and_registration_form_already_authenticated(self, url_name):
# call the account registration api that sets the login cookies
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment