Projet

Général

Profil

0001-add-a-honeypot-middleware-50108.patch

Benjamin Dauvergne, 14 janvier 2021 10:32

Télécharger (4,06 ko)

Voir les différences:

Subject: [PATCH] add a honeypot middleware (#50108)

Forms must be instrumented by adding a 'robotcheck' input, then
a request.is_robot boolean signals if the request is possibly from a
spam robot.
 src/authentic2/middleware.py                       |  9 +++++++++
 src/authentic2/settings.py                         |  1 +
 .../login_password_registration_form.html          |  1 +
 src/authentic2/views.py                            |  2 ++
 tests/test_registration.py                         | 14 ++++++++++++++
 5 files changed, 27 insertions(+)
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
    def middleware(request):
234
        request.is_robot = 'robotcheck' in request.POST
235
        if request.is_robot:
236
            messages.warning(request, _('We think you are robot, so we did nothing. If you are not a robot, please contact your administrator.'))
237
        return get_response(request)
238
    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>Robot Check ?</span></label>
7 8
  <button class="submit-button">{% trans 'Submit' %}</button>
8 9
</form>
9 10
{% 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.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 len(response.pyquery('li.warning'))
822
-