Merge pull request #16951 from edx/ahsan/LEARNER-3393-rate-limited-access-token-view
Rate limited /oauth2/access_token/
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
# pylint: disable=missing-docstring
|
||||
import mock
|
||||
from django.core.cache import cache
|
||||
from django.test.utils import override_settings
|
||||
# Will also run default tests for IDTokens and UserInfo
|
||||
@@ -134,6 +135,13 @@ class IDTokenTest(BaseTestMixin, IDTokenTestCase):
|
||||
_scopes, claims = self.get_id_token_values('openid profile permissions')
|
||||
self.assertTrue(claims['administrator'])
|
||||
|
||||
def test_rate_limit_token(self):
|
||||
with mock.patch('openedx.core.djangoapps.oauth_dispatch.views.AccessTokenView.ratelimit_rate', '1/m'):
|
||||
response = self.get_access_token_response('openid profile permissions')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.get_access_token_response('openid profile permissions')
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
|
||||
class UserInfoTest(BaseTestMixin, UserInfoTestCase):
|
||||
def setUp(self):
|
||||
|
||||
@@ -3465,3 +3465,7 @@ EDX_PLATFORM_REVISION = 'unknown'
|
||||
# Once a user has watched this percentage of a video, mark it as complete:
|
||||
# (0.0 = 0%, 1.0 = 100%)
|
||||
COMPLETION_VIDEO_COMPLETE_PERCENTAGE = 0.95
|
||||
|
||||
############### Settings for Django Rate limit #####################
|
||||
RATELIMIT_ENABLE = True
|
||||
RATELIMIT_RATE = '30/m'
|
||||
|
||||
@@ -17,6 +17,8 @@ from edx_oauth2_provider import views as dop_views # django-oauth2-provider vie
|
||||
from jwkest.jwk import RSAKey
|
||||
from oauth2_provider import models as dot_models # django-oauth-toolkit
|
||||
from oauth2_provider import views as dot_views
|
||||
from ratelimit import ALL
|
||||
from ratelimit.mixins import RatelimitMixin
|
||||
|
||||
from openedx.core.djangoapps.auth_exchange import views as auth_exchange_views
|
||||
from openedx.core.lib.token_utils import JwtBuilder
|
||||
@@ -83,12 +85,16 @@ class _DispatchingView(View):
|
||||
return request.POST.get('client_id')
|
||||
|
||||
|
||||
class AccessTokenView(_DispatchingView):
|
||||
class AccessTokenView(RatelimitMixin, _DispatchingView):
|
||||
"""
|
||||
Handle access token requests.
|
||||
"""
|
||||
dot_view = dot_views.TokenView
|
||||
dop_view = dop_views.AccessTokenView
|
||||
ratelimit_key = 'openedx.core.djangoapps.util.ratelimit.real_ip'
|
||||
ratelimit_rate = settings.RATELIMIT_RATE
|
||||
ratelimit_block = True
|
||||
ratelimit_method = ALL
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
response = super(AccessTokenView, self).dispatch(request, *args, **kwargs)
|
||||
|
||||
5
openedx/core/djangoapps/util/ratelimit.py
Normal file
5
openedx/core/djangoapps/util/ratelimit.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from ipware.ip import get_ip
|
||||
|
||||
|
||||
def real_ip(group, request):
|
||||
return get_ip(request)
|
||||
@@ -29,6 +29,7 @@ django-mptt>=0.8.6,<0.9
|
||||
django-oauth-toolkit==0.12.0
|
||||
django-pipeline-forgiving==1.0.0
|
||||
django-pyfs==2.0
|
||||
django-ratelimit==1.1.0
|
||||
django-sekizai>=0.10
|
||||
django-ses==0.8.4
|
||||
django-simple-history==1.9.0
|
||||
|
||||
Reference in New Issue
Block a user