Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add marker interface to disable automatic field insertion in forms #10

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ Changelog
----------------

- Test on GitHub Actions instead of Travis. [maurits]

- Add marker interface to disable automatic field insertion in forms.
[cekk]

2.0 (2021-01-27)
----------------
Expand Down
8 changes: 8 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,14 @@ As an aside, if you have such a setup, you should make sure the
script directly. And he can bypass the honeypot checks by using a
``GET`` request.

If you don't need honeypot automatic field creation in some forms,
you only need to provide ``IHoneypotDisabledForm`` interface to the current request::

from collective.honeypot.interfaces import IHoneypotDisabledForm
from zope.interface import alsoProvides

alsoProvides(request, IHoneypotDisabledForm)


z3c.form
========
Expand Down
9 changes: 8 additions & 1 deletion collective/honeypot/auto.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from collective.honeypot import config
from collective.honeypot.interfaces import IHoneypotDisabledForm
from lxml import etree
from lxml import html
from plone.transformchain.interfaces import ITransform
Expand Down Expand Up @@ -41,7 +42,11 @@ def parseTree(self, result, encoding):
return None

contentEncoding = self.request.response.getHeader("Content-Encoding")
if contentEncoding and contentEncoding in ("zip", "deflate", "compress",):
if contentEncoding and contentEncoding in (
"zip",
"deflate",
"compress",
):
return None

if isinstance(result, list) and len(result) == 1:
Expand Down Expand Up @@ -79,6 +84,8 @@ def transform(self, result, encoding):
result = self.parseTree(result, encoding)
if result is None:
return None
if IHoneypotDisabledForm.providedBy(self.request):
return result
root = result.tree.getroot()

for form in root.cssselect("form"):
Expand Down
9 changes: 7 additions & 2 deletions collective/honeypot/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@


class IHoneypot(Interface):
"""Honeypot text field.
"""
"""Honeypot text field."""

# Keep field title empty so visitors do not see it.
honeypot = schema.TextLine(title=u"", required=False)


class IHoneypotDisabledForm(Interface):
"""
Marker interface to disable automatic field insertion in some views
"""
48 changes: 48 additions & 0 deletions collective/honeypot/tests/test_auto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from collective.honeypot.auto import ProtectHoneyTransform
from collective.honeypot.testing import HONEYPOT_FUNCTIONAL_TESTING
from collective.honeypot.interfaces import IHoneypotDisabledForm
from zope.interface import alsoProvides, noLongerProvides

import unittest


class HoneypotTransformTestCase(unittest.TestCase):
layer = HONEYPOT_FUNCTIONAL_TESTING

def setUp(self):
self.portal = self.layer["portal"]
self.request = self.layer["request"]
self.request.response.setHeader("Content-Type", "text/html")
self.request.REQUEST_METHOD = "POST"

def tearDown(self):
noLongerProvides(self.request, IHoneypotDisabledForm)

def test_transform_add_field_in_form(self):
transform = ProtectHoneyTransform(self.portal, self.request)
result = transform.transform(
[
(
"<html>\n<body>"
'<form action="http://nohost/myaction" method="POST">'
"</form></body>\n</html>"
)
],
"utf-8",
)
self.assertTrue(b'name="protected_1"' in result.serialize())

def test_transform_do_not_add_field_in_form_if_interface_provided(self):
alsoProvides(self.request, IHoneypotDisabledForm)
transform = ProtectHoneyTransform(self.portal, self.request)
result = transform.transform(
[
(
"<html>\n<body>"
'<form action="http://nohost/myaction" method="POST">'
"</form></body>\n</html>"
)
],
"utf-8",
)
self.assertFalse(b'name="protected_1"' in result.serialize())
13 changes: 13 additions & 0 deletions requirements-60.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Keep these the same as in base.cfg please.
pip==22.2.2
setuptools==65.3.0
zc.buildout>=3.0.0rc3
wheel==0.37.1

# Windows specific down here (has to be installed here, fails in buildout)
# Dependency of zope.sendmail:
pywin32 ; platform_system == 'Windows'
# SSL Certs on Windows, because Python is missing them otherwise:
certifi ; platform_system == 'Windows'
# Dependency of collective.recipe.omelette:
ntfsutils ; platform_system == 'Windows' and python_version < '3.0'
5 changes: 5 additions & 0 deletions test-6.0.x.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,8 @@ extends =
https://raw.githubusercontent.com/collective/buildout.plonetest/master/test-6.0.x.cfg
https://raw.githubusercontent.com/collective/buildout.plonetest/master/qa.cfg
base.cfg

[versions]
zc.buildout = >=3.0.0rc3
pip = 22.2.2
setuptools = 65.3.0
3 changes: 2 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ setenv =
version_file=test-5.2.x.cfg
plone60: version_file=test-6.0.x.cfg
deps =
-rrequirements.txt
plone60: -rrequirements-60.txt
!plone60: -rrequirements.txt