Commit 29cb2ee2 authored by Birin Sanchez's avatar Birin Sanchez
Browse files

Changes in recovery email:


* Prompt for {SITE_NAME} address.
* Add CAPTCHA to make enumerating through usernames difficult.
* Do not reveal recovery email in response page.
Signed-off-by: Birin Sanchez's avatarBirin Sanchez <birin.sanchez@puri.sm>
parent 4670b51c
Pipeline #12891 passed with stage
in 40 seconds
from django import forms
from django.conf import settings
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.forms import PasswordChangeForm \
as BasePasswordChangeForm
from django.contrib.auth import authenticate
from password_reset.forms import PasswordRecoveryForm as BasePasswordRecoveryForm
from password_reset.forms import PasswordRecoveryForm \
as BasePasswordRecoveryForm
from .models import User
from captcha.fields import CaptchaField
class PasswordRecoveryForm(BasePasswordRecoveryForm):
def _validate_domain(self, value):
(user, domain) = value.split('@')
if domain != settings.SITE_DOMAIN:
raise ValidationError(
_('Only @{} addresses are allowed'.format(
settings.SITE_DOMAIN)),
params={'value': value},
)
def __init__(self, *args, **kwargs):
super(PasswordRecoveryForm, self).__init__(*args, **kwargs)
self.fields['username_or_email'] = forms.CharField(
label = _('Enter your recovery email')
self.fields['username_or_email'] = forms.EmailField(
label=_('Enter your {} address'.format(settings.SITE_TITLE)),
validators=[self._validate_domain],
)
# Override clean_username_or_email to search for username even
# when we are expecting email address in the form filed.
def clean_username_or_email(self):
email = self.cleaned_data['username_or_email']
username = email.split('@')[0]
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
raise forms.ValidationError(_('That account is invalid or was not'
' found.'),
code='not_found')
self.cleaned_data['user'] = user
return username
class CaptchaPasswordRecoveryForm(PasswordRecoveryForm):
captcha = CaptchaField(
label=_('Please solve this math problem'),
help_text=_('Prove you are not a robot. Solve this addition,'
' subtraction or multiplication problem.'),
)
class PasswordChangeForm(BasePasswordChangeForm):
......
......@@ -2,11 +2,11 @@
{% load i18n %}
{% block title %}{% trans "New password set" %}{% endblock %}
{% block header %}{% trans "New password set" %}{% endblock %}
{% block byline %}{% trans "You can now use your new password to login now" %}{% endblock %}
{% block byline %}{% endblock %}
{% block login_status%}{% endblock %}
{% block content %}
<div style="padding: 40px;">
<p>{% trans "Your password has successfully been reset. You can use it right now on the login page." %}</p>
<p>{% trans "Your password has successfully been reset. You can use it now on the login page." %}</p>
</div>
{% endblock %}
......@@ -2,15 +2,15 @@
{% load i18n %}
{% block title %}{% trans "Account recovery email sent" %}{% endblock %}
{% block header %}{% trans "Recovery email sent" %}{% endblock %}
{% block byline %}{% trans "An email was sent to your registered recovery email address" %}{% endblock %}
{% block byline %}{% endblock %}
{% block login_status%}{% endblock %}
{% block content %}
<div style="padding: 40px;">
<p>
{% blocktrans with ago=timestamp|timesince %}An email was sent to <strong>{{ email }}</strong>.{% endblocktrans %}
{% blocktrans with ago=timestamp|timesince %}An email was sent to your recovery email address.{% endblocktrans %}
</p>
<p>Use the link in it to set your new password.</p>
<p>Follow the email instructions to set your new password.</p>
</div>
{% endblock %}
......@@ -8,7 +8,7 @@ from django.http import Http404, FileResponse
from password_reset.views import Recover
from .serializers import UserSerializer
from .forms import PasswordRecoveryForm, PasswordChangeForm, \
from .forms import CaptchaPasswordRecoveryForm, PasswordChangeForm, \
ProfileConfigureForm
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.views import PasswordChangeView \
......@@ -37,7 +37,8 @@ class UserDetail(APIView):
class Recovery(Recover):
form_class = PasswordRecoveryForm
form_class = CaptchaPasswordRecoveryForm
search_fields = ['username']
class PasswordChangeDone(BasePasswordChangeDoneView):
......
Supports Markdown
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