0001-add-a-honeypot-middleware-50108.patch
src/authentic2/middleware.py | ||
---|---|---|
227 | 227 | |
228 | 228 |
return get_response(request) |
229 | 229 |
return middleware |
230 | ||
231 | ||
232 |
def honeypot_middleware(get_response): |
|
233 |
# The following HTML code must be added to forms for the middleware to work : |
|
234 |
# <label style="display: none"><input type="checkbox" name="robotcheck" value="robotcheck"><span>{% trans "Robot detection, do not check !" %}</span></label> |
|
235 | ||
236 |
def middleware(request): |
|
237 |
if request.POST: |
|
238 |
if 'robotcheck' in request.POST: |
|
239 |
request.session['is_robot'] = True |
|
240 |
elif 'is_robot' in request.session: # prevent persistance |
|
241 |
del request.session['is_robot'] |
|
242 |
return get_response(request) |
|
243 |
return middleware |
src/authentic2/settings.py | ||
---|---|---|
102 | 102 |
'django.contrib.auth.middleware.AuthenticationMiddleware', |
103 | 103 |
'django.contrib.messages.middleware.MessageMiddleware', |
104 | 104 |
'authentic2.middleware.journal_middleware', |
105 |
'authentic2.middleware.honeypot_middleware', |
|
105 | 106 |
) |
106 | 107 | |
107 | 108 |
DATABASES['default']['ATOMIC_REQUESTS'] = True |
src/authentic2/templates/authentic2/login_password_registration_form.html | ||
---|---|---|
4 | 4 |
<form enctype="multipart/form-data" method="post" class="pk-mark-optional-fields"> |
5 | 5 |
{% csrf_token %} |
6 | 6 |
{{ form|with_template }} |
7 |
<label style="display: none"><input type="checkbox" name="robotcheck" value="robotcheck"><span>{% trans "Robot detection, do not check !" %}</span></label> |
|
7 | 8 |
<button class="submit-button">{% trans 'Submit' %}</button> |
8 | 9 |
</form> |
9 | 10 |
{% endblock %} |
src/authentic2/templates/registration/registration_complete.html | ||
---|---|---|
6 | 6 |
{% endblock %} |
7 | 7 | |
8 | 8 |
{% block content %} |
9 |
{% if request.session.is_robot %} |
|
10 |
{% block robot-detected %} |
|
11 |
<p>{% blocktrans %}<b>Your registration request is refused.</b> Indeed your browser checked an hidden anti-robot checkbox on the registration form. A browser extension may produce this behaviour, in this case disable the extension and try agin.{% endblocktrans %}</p> |
|
12 |
{% endblock %} |
|
13 |
{% else %} |
|
9 | 14 |
{% block instructions %} |
10 | 15 |
<p><strong> |
11 | 16 |
{% blocktrans with email=request.session.registered_email %} |
... | ... | |
36 | 41 |
{% block back %} |
37 | 42 |
<p><a href="{{ next_url }}">{% trans "Back" %}</a></p> |
38 | 43 |
{% endblock %} |
44 |
{% endif %} |
|
39 | 45 |
{% endblock %} |
src/authentic2/views.py | ||
---|---|---|
829 | 829 |
return super(BaseRegistrationView, self).dispatch(request, *args, **kwargs) |
830 | 830 | |
831 | 831 |
def form_valid(self, form): |
832 |
if self.request.session.get('is_robot'): |
|
833 |
return utils.redirect(self.request, 'registration_complete', params={REDIRECT_FIELD_NAME: self.next_url}) |
|
832 | 834 |
email = form.cleaned_data.pop('email') |
833 | 835 | |
834 | 836 |
# if an email has already been sent, warn once before allowing resend |
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 |
response = response.follow() |
|
834 |
assert len(mailoutbox) == 0 |
|
835 |
assert 'Your registration request is refused' in response |
|
822 |
- |