diff --git a/apps/users/forms.py b/apps/users/forms.py index f6c02ff23..f777e0dd7 100644 --- a/apps/users/forms.py +++ b/apps/users/forms.py @@ -15,6 +15,14 @@ class UserLoginForm(AuthenticationForm): label=_('Password'), widget=forms.PasswordInput, max_length=128, strip=False ) + + +class UserLoginCaptchaForm(AuthenticationForm): + username = forms.CharField(label=_('Username'), max_length=100) + password = forms.CharField( + label=_('Password'), widget=forms.PasswordInput, + max_length=128, strip=False + ) captcha = CaptchaField() diff --git a/apps/users/templates/users/login.html b/apps/users/templates/users/login.html index 13276f6fe..7dd3f5d0a 100644 --- a/apps/users/templates/users/login.html +++ b/apps/users/templates/users/login.html @@ -53,7 +53,7 @@ {% endif %} {% endif %}
- +
diff --git a/apps/users/views/login.py b/apps/users/views/login.py index bb7f58874..7e3d50c8a 100644 --- a/apps/users/views/login.py +++ b/apps/users/views/login.py @@ -2,6 +2,7 @@ from __future__ import unicode_literals import os +from django.core.cache import cache from django.shortcuts import render from django.contrib.auth import login as auth_login, logout as auth_logout from django.contrib.auth.mixins import LoginRequiredMixin @@ -43,7 +44,9 @@ __all__ = [ class UserLoginView(FormView): template_name = 'users/login.html' form_class = forms.UserLoginForm + form_class_captcha = forms.UserLoginCaptchaForm redirect_field_name = 'next' + key_prefix = "_LOGIN_INVALID_{}" def get(self, request, *args, **kwargs): if request.user.is_staff: @@ -58,6 +61,21 @@ class UserLoginView(FormView): set_tmp_user_to_cache(self.request, form.get_user()) return redirect(self.get_success_url()) + def form_invalid(self, form): + ip = get_login_ip(self.request) + cache.set(self.key_prefix.format(ip), 1, 3600) + old_form = form + form = self.form_class_captcha(data=form.data) + form._errors = old_form.errors + return super().form_invalid(form) + + def get_form_class(self): + ip = get_login_ip(self.request) + if cache.get(self.key_prefix.format(ip)): + return self.form_class_captcha + else: + return self.form_class + def get_success_url(self): user = get_user_or_tmp_user(self.request)