use honeypot field to detect robots on registration form (#50108)
This commit is contained in:
parent
ab66385315
commit
961403a666
|
@ -0,0 +1,33 @@
|
|||
# authentic2 - versatile identity manager
|
||||
# Copyright (C) 2010-2019 Entr'ouvert
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Affero General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.forms import Form, CheckboxInput, BooleanField
|
||||
from django.utils.html import mark_safe
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
|
||||
class HoneypotInput(CheckboxInput):
|
||||
template_name = 'authentic2/honeypot_input.html'
|
||||
is_hidden = True
|
||||
|
||||
|
||||
class HoneypotForm(Form):
|
||||
robotcheck = BooleanField(widget=HoneypotInput, required=False)
|
||||
|
||||
def is_robot(self):
|
||||
return hasattr(self, 'cleaned_data') and self.cleaned_data.get('robotcheck')
|
|
@ -19,7 +19,6 @@ import re
|
|||
from django.contrib.auth import get_user_model
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.utils.translation import ugettext_lazy as _, ugettext
|
||||
from django.forms import Form
|
||||
|
||||
from django.contrib.auth.models import BaseUserManager, Group
|
||||
|
||||
|
@ -28,12 +27,13 @@ from authentic2.a2_rbac.models import OrganizationalUnit
|
|||
|
||||
from .. import app_settings, models
|
||||
from . import profile as profile_forms
|
||||
from .honeypot import HoneypotForm
|
||||
from .fields import ValidatedEmailField
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
class RegistrationForm(Form):
|
||||
class RegistrationForm(HoneypotForm):
|
||||
error_css_class = 'form-field-error'
|
||||
required_css_class = 'form-field-required'
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
{% load i18n %}<label style="display: none"><input type="{{ widget.type }}" name="{{ widget.name }}"><span>{% trans "Robot detection, do not check !" %}</span></label>
|
|
@ -6,8 +6,10 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if 'robot' in request.GET %}
|
||||
<p>{% blocktrans %}<strong>Your registration request has been refused.</strong> Indeed your browser checked a hidden anti-robot checkbox on the registration form. A browser extension may produce this behaviour, in this case disable such extensions and try again.{% endblocktrans %}</p>
|
||||
{% else %}
|
||||
{% block instructions %}
|
||||
<p><strong>
|
||||
{% blocktrans with email=request.session.registered_email %}
|
||||
An email was sent to {{ email }}.
|
||||
{% endblocktrans %}
|
||||
|
@ -33,6 +35,7 @@
|
|||
{% endblocktrans %}
|
||||
</p>
|
||||
{% endblock %}
|
||||
{% endif %}
|
||||
{% block back %}
|
||||
<p><a href="{{ next_url }}">{% trans "Back" %}</a></p>
|
||||
{% endblock %}
|
||||
|
|
|
@ -829,6 +829,12 @@ class BaseRegistrationView(FormView):
|
|||
return super(BaseRegistrationView, self).dispatch(request, *args, **kwargs)
|
||||
|
||||
def form_valid(self, form):
|
||||
if form.is_robot():
|
||||
return utils.redirect(self.request, 'registration_complete',
|
||||
params={
|
||||
REDIRECT_FIELD_NAME: self.next_url,
|
||||
'robot': 'on',
|
||||
})
|
||||
email = form.cleaned_data.pop('email')
|
||||
|
||||
# if an email has already been sent, warn once before allowing resend
|
||||
|
|
|
@ -819,3 +819,17 @@ def test_registration_email_not_verified_required_and_unrequired_attributes(app,
|
|||
assert user.attributes.preferred_color == 'bleu'
|
||||
assert user.email == 'john.doe2@example.com'
|
||||
assert user.email_verified is True
|
||||
|
||||
|
||||
def test_honeypot(app, db, settings, mailoutbox):
|
||||
settings.DEFAULT_FROM_EMAIL = 'show only addr <noreply@example.net>'
|
||||
|
||||
response = app.get(utils.make_url('registration_register'))
|
||||
response = app.post(utils.make_url('registration_register'), params={
|
||||
'email': 'testbot@entrouvert.com',
|
||||
'csrfmiddlewaretoken': response.context['csrf_token'],
|
||||
'robotcheck': 'a',
|
||||
})
|
||||
response = response.follow()
|
||||
assert len(mailoutbox) == 0
|
||||
assert 'Your registration request has been refused' in response
|
||||
|
|
Loading…
Reference in New Issue