Skip to content
Snippets Groups Projects
Commit d901b1d3 authored by Stephen Sanchez's avatar Stephen Sanchez
Browse files

Allow services to ignore user throttling.

parent c8825652
No related merge requests found
......@@ -12,6 +12,8 @@ from rest_framework import status
from django.conf import settings
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
from course_modes.models import CourseMode
from util.models import RateLimitConfiguration
from util.testing import UrlResetMixin
from enrollment import api
from enrollment.errors import CourseEnrollmentError
......@@ -37,6 +39,11 @@ class EnrollmentTest(ModuleStoreTestCase, APITestCase):
def setUp(self):
""" Create a course and user, then log in. """
super(EnrollmentTest, self).setUp()
rate_limit_config = RateLimitConfiguration.current()
rate_limit_config.enabled = False
rate_limit_config.save()
self.course = CourseFactory.create()
self.user = UserFactory.create(username=self.USERNAME, email=self.EMAIL, password=self.PASSWORD)
self.other_user = UserFactory.create()
......@@ -276,6 +283,35 @@ class EnrollmentTest(ModuleStoreTestCase, APITestCase):
self.assertEqual(resp.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn("No course ", resp.content)
def test_enrollment_throttle_for_user(self):
"""Make sure a user requests do not exceed the maximum number of requests"""
rate_limit_config = RateLimitConfiguration.current()
rate_limit_config.enabled = True
rate_limit_config.save()
CourseModeFactory.create(
course_id=self.course.id,
mode_slug=CourseMode.HONOR,
mode_display_name=CourseMode.HONOR,
)
for attempt in range(0, 50):
expected_status = status.HTTP_429_TOO_MANY_REQUESTS if attempt >= 40 else status.HTTP_200_OK
self._create_enrollment(expected_status=expected_status)
def test_enrollment_throttle_for_service(self):
"""Make sure a service can call the enrollment API as many times as needed. """
rate_limit_config = RateLimitConfiguration.current()
rate_limit_config.enabled = True
rate_limit_config.save()
CourseModeFactory.create(
course_id=self.course.id,
mode_slug=CourseMode.HONOR,
mode_display_name=CourseMode.HONOR,
)
for attempt in range(0, 50):
self._create_enrollment(as_server=True)
def _create_enrollment(self, course_id=None, username=None, expected_status=status.HTTP_200_OK, email_opt_in=None, as_server=False):
"""Enroll in the course and verify the URL we are sent to. """
course_id = unicode(self.course.id) if course_id is None else course_id
......
......@@ -24,12 +24,6 @@ from enrollment.errors import (
)
class EnrollmentUserThrottle(UserRateThrottle):
"""Limit the number of requests users can make to the enrollment API."""
# TODO Limit significantly after performance testing. # pylint: disable=fixme
rate = '50/second'
class ApiKeyPermissionMixIn(object):
"""
This mixin is used to provide a convenience function for doing individual permission checks
......@@ -49,6 +43,14 @@ class ApiKeyPermissionMixIn(object):
return ApiKeyHeaderPermission().has_permission(request, self)
class EnrollmentUserThrottle(UserRateThrottle, ApiKeyPermissionMixIn):
"""Limit the number of requests users can make to the enrollment API."""
rate = '40/minute'
def allow_request(self, request, view):
return self.has_api_key_permissions(request) or super(EnrollmentUserThrottle, self).allow_request(request, view)
@can_disable_rate_limit
class EnrollmentView(APIView, ApiKeyPermissionMixIn):
"""
......
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