0001-use-honeypot-field-to-detect-robots-on-registration-.patch
src/authentic2/forms/honeypot.py | ||
---|---|---|
1 |
# authentic2 - versatile identity manager |
|
2 |
# Copyright (C) 2010-2019 Entr'ouvert |
|
3 |
# |
|
4 |
# This program is free software: you can redistribute it and/or modify it |
|
5 |
# under the terms of the GNU Affero General Public License as published |
|
6 |
# by the Free Software Foundation, either version 3 of the License, or |
|
7 |
# (at your option) any later version. |
|
8 |
# |
|
9 |
# This program is distributed in the hope that it will be useful, |
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
# GNU Affero General Public License for more details. |
|
13 |
# |
|
14 |
# You should have received a copy of the GNU Affero General Public License |
|
15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
16 | ||
17 | ||
18 |
from django.core.exceptions import ValidationError |
|
19 |
from django.forms import Form, CheckboxInput, BooleanField |
|
20 |
from django.utils.html import mark_safe |
|
21 |
from django.utils.translation import gettext as _ |
|
22 | ||
23 | ||
24 |
class HoneypotInput(CheckboxInput): |
|
25 |
template_name = 'authentic2/honeypot_input.html' |
|
26 | ||
27 | ||
28 |
class HoneypotForm(Form): |
|
29 |
robotcheck = BooleanField(widget=HoneypotInput, required=False) |
|
30 | ||
31 |
def clean(self): |
|
32 |
if self.cleaned_data.get('robotcheck'): |
|
33 |
raise ValidationError( |
|
34 |
mark_safe( |
|
35 |
_('<b>Your registration request is refused.</b> Indeed your browser checked \ |
|
36 |
an hidden anti-robot checkbox on the registration form. A browser extension may produce \ |
|
37 |
this behaviour, in this case disable the extension and try agin.'))) |
|
38 |
return super().clean() |
src/authentic2/forms/registration.py | ||
---|---|---|
28 | 28 | |
29 | 29 |
from .. import app_settings, models |
30 | 30 |
from . import profile as profile_forms |
31 |
from .honeypot import HoneypotForm |
|
31 | 32 |
from .fields import ValidatedEmailField |
32 | 33 | |
33 | 34 |
User = get_user_model() |
34 | 35 | |
35 | 36 | |
36 |
class RegistrationForm(Form): |
|
37 |
class RegistrationForm(HoneypotForm):
|
|
37 | 38 |
error_css_class = 'form-field-error' |
38 | 39 |
required_css_class = 'form-field-required' |
39 | 40 |
src/authentic2/templates/authentic2/honeypot_input.html | ||
---|---|---|
1 |
{% load i18n %}<label style="display: none"><input type="{{ widget.type }}" name="{{ widget.name }}"><span>{% trans "Robot detection, do not check !" %}</span></label> |
tests/test_registration.py | ||
---|---|---|
819 | 819 |
assert user.attributes.preferred_color == 'bleu' |
820 | 820 |
assert user.email == 'john.doe2@example.com' |
821 | 821 |
assert user.email_verified is True |
822 | ||
823 | ||
824 |
def test_honeypot(app, db, settings, mailoutbox): |
|
825 |
settings.DEFAULT_FROM_EMAIL = 'show only addr <noreply@example.net>' |
|
826 | ||
827 |
response = app.get(utils.make_url('registration_register')) |
|
828 |
response = app.post(utils.make_url('registration_register'), params={ |
|
829 |
'email': 'testbot@entrouvert.com', |
|
830 |
'csrfmiddlewaretoken': response.context['csrf_token'], |
|
831 |
'robotcheck': 'a', |
|
832 |
}) |
|
833 |
assert len(mailoutbox) == 0 |
|
834 |
assert 'Your registration request is refused' in response |
|
822 |
- |