Skip to content

Commit

Permalink
Add rate limit to password reset view
Browse files Browse the repository at this point in the history
  • Loading branch information
quantum5 committed Jul 24, 2021
1 parent 0d89582 commit e86c114
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 2 deletions.
3 changes: 3 additions & 0 deletions dmoj/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@
}
DMOJ_API_PAGE_SIZE = 1000

DMOJ_PASSWORD_RESET_LIMIT_WINDOW = 3600
DMOJ_PASSWORD_RESET_LIMIT_COUNT = 10

MARKDOWN_STYLES = {}
MARKDOWN_DEFAULT_STYLE = {}

Expand Down
2 changes: 1 addition & 1 deletion dmoj/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
url(r'^password/change/done/$', auth_views.PasswordChangeDoneView.as_view(
template_name='registration/password_change_done.html',
), name='password_change_done'),
url(r'^password/reset/$', auth_views.PasswordResetView.as_view(
url(r'^password/reset/$', user.CustomPasswordResetView.as_view(
template_name='registration/password_reset.html',
html_email_template_name='registration/password_reset_email.html',
email_template_name='registration/password_reset_email.txt',
Expand Down
12 changes: 11 additions & 1 deletion judge/views/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import Permission
from django.contrib.auth.views import LoginView, PasswordChangeView, redirect_to_login
from django.contrib.auth.views import LoginView, PasswordChangeView, PasswordResetView, redirect_to_login
from django.contrib.contenttypes.models import ContentType
from django.core.cache import cache
from django.core.exceptions import PermissionDenied, ValidationError
Expand Down Expand Up @@ -505,3 +505,13 @@ class UserLogoutView(TitleMixin, TemplateView):
def post(self, request, *args, **kwargs):
auth_logout(request)
return HttpResponseRedirect(request.get_full_path())


class CustomPasswordResetView(PasswordResetView):
def post(self, request, *args, **kwargs):
key = f'pwreset!{request.META["REMOTE_ADDR"]}'
cache.add(key, 0, timeout=settings.DMOJ_PASSWORD_RESET_LIMIT_WINDOW)
if cache.incr(key) > settings.DMOJ_PASSWORD_RESET_LIMIT_COUNT:
return HttpResponse('You sent in too many password reset requests. Please try again later.',
content_type='text/plain', status=429)
return super().post(request, *args, **kwargs)

0 comments on commit e86c114

Please sign in to comment.