From ff608ee205953f6bae4f590e9e882c9d3cac3b9e Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Mon, 25 Mar 2024 11:31:28 +0100 Subject: [PATCH 01/18] =?UTF-8?q?Customize=20INameChooser=20adapter=20to?= =?UTF-8?q?=20check=20also=20alias=20ids=20and=20disallow=20t=E2=80=A6=20(?= =?UTF-8?q?#101)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Customize INameChooser adapter to check also alias ids and disallow to create contents that could override aliases * black and isort * zpretty --- CHANGES.rst | 5 +- src/redturtle/volto/adapters/configure.zcml | 11 + src/redturtle/volto/adapters/namechooser.py | 41 ++++ src/redturtle/volto/interfaces.py | 13 ++ .../locales/it/LC_MESSAGES/redturtle.volto.po | 33 ++- .../volto/locales/redturtle.volto.pot | 33 ++- .../volto/profiles/default/metadata.xml | 2 +- .../tests/test_namechooser_customization.py | 205 ++++++++++++++++++ src/redturtle/volto/upgrades.zcml | 8 + 9 files changed, 331 insertions(+), 20 deletions(-) create mode 100644 src/redturtle/volto/adapters/namechooser.py create mode 100644 src/redturtle/volto/tests/test_namechooser_customization.py diff --git a/CHANGES.rst b/CHANGES.rst index 5b013fee..901da6e0 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,10 @@ Changelog 5.4.9 (unreleased) ------------------ -- Nothing changed yet. +- Customize INameChooser adapter to check also alias ids and disallow to create contents that could override aliases. + [cekk] +- Add flag in controlpanel to enable/disable INameChooser customization. + [cekk] 5.4.8 (2024-03-19) diff --git a/src/redturtle/volto/adapters/configure.zcml b/src/redturtle/volto/adapters/configure.zcml index ec239441..5b1cd0cf 100644 --- a/src/redturtle/volto/adapters/configure.zcml +++ b/src/redturtle/volto/adapters/configure.zcml @@ -55,4 +55,15 @@ zcml:condition="not-have plone-60" /> + + + diff --git a/src/redturtle/volto/adapters/namechooser.py b/src/redturtle/volto/adapters/namechooser.py new file mode 100644 index 00000000..f400ee9e --- /dev/null +++ b/src/redturtle/volto/adapters/namechooser.py @@ -0,0 +1,41 @@ +from Acquisition import aq_inner +from plone import api +from plone.app.content.namechooser import ( + NormalizingNameChooser as BaseNormalizingNameChooser, +) +from plone.app.redirector.interfaces import IRedirectionStorage +from redturtle.volto import _ +from redturtle.volto.interfaces import IRedTurtleVoltoSettings +from zExceptions import BadRequest +from zope.component import getUtility + + +class NormalizingNameChooser(BaseNormalizingNameChooser): + def chooseName(self, name, obj): + """ + Additional check: the id should not be in redirection tool. + """ + id = super().chooseName(name=name, obj=obj) + try: + if not api.portal.get_registry_record( + "check_aliases_in_namechooser", + interface=IRedTurtleVoltoSettings, + default=False, + ): + return id + except KeyError: + return id + parent = aq_inner(self.context) + storage = getUtility(IRedirectionStorage) + path = "/".join(parent.getPhysicalPath()) + "/" + id + if storage.get(path): + portal_path = "/".join(api.portal.get().getPhysicalPath()) + fixed_path = path.replace(portal_path, "") + msg = _( + "name_chooser_alias_error", + default='The id "${id}" is invalid because there is already an alias for that path. ' + 'Search "${fixed_path}" in aliases management to manage it.', + mapping={"id": id, "fixed_path": fixed_path}, + ) + raise BadRequest(api.portal.translate(msg)) + return id diff --git a/src/redturtle/volto/interfaces.py b/src/redturtle/volto/interfaces.py index e495492a..29ec4cf6 100644 --- a/src/redturtle/volto/interfaces.py +++ b/src/redturtle/volto/interfaces.py @@ -27,3 +27,16 @@ class IRedTurtleVoltoSettings(Interface): default=False, required=False, ) + + check_aliases_in_namechooser = Bool( + title=_( + "check_aliases_in_namechooser_label", + default="Disallow ids used in aliases", + ), + description=_( + "check_aliases_in_namechooser_help", + default="If enabled, users can't create contents with ids that are already used as aliases.", + ), + default=False, + required=False, + ) diff --git a/src/redturtle/volto/locales/it/LC_MESSAGES/redturtle.volto.po b/src/redturtle/volto/locales/it/LC_MESSAGES/redturtle.volto.po index f6683a22..1d4f8503 100644 --- a/src/redturtle/volto/locales/it/LC_MESSAGES/redturtle.volto.po +++ b/src/redturtle/volto/locales/it/LC_MESSAGES/redturtle.volto.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2023-03-16 14:54+0000\n" +"POT-Creation-Date: 2024-03-21 13:53+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -14,7 +14,7 @@ msgstr "" "Preferred-Encodings: utf-8 latin1\n" "Domain: DOMAIN\n" -#: redturtle/volto/configure.zcml:28 +#: redturtle/volto/configure.zcml:29 msgid "Installs the redturtle.volto add-on." msgstr "" @@ -27,11 +27,11 @@ msgstr "" msgid "RedTurtle Volto Settings" msgstr "Impostazioni RedTurtle Volto" -#: redturtle/volto/configure.zcml:28 +#: redturtle/volto/configure.zcml:29 msgid "RedTurtle: Volto" msgstr "" -#: redturtle/volto/configure.zcml:37 +#: redturtle/volto/configure.zcml:38 msgid "RedTurtle: Volto (uninstall)" msgstr "" @@ -43,31 +43,46 @@ msgstr "Seleziona False per mostrare solo gli elementi non omessi dalla navigazi msgid "Show elements excluded from navigation" msgstr "Elementi omessi dalla navigazione" -#: redturtle/volto/configure.zcml:37 +#: redturtle/volto/configure.zcml:38 msgid "Uninstalls the redturtle.volto add-on." msgstr "" +#. Default: "If enabled, users can't create contents with ids that are already used as aliases." +#: redturtle/volto/interfaces.py:36 +msgid "check_aliases_in_namechooser_help" +msgstr "Se attivato, alla creazione o rinomina di un contenuto, verrà eseguito anche un controllo su eventuali alias presenti (quelli visibili in Gestione URL), ed eventualmente viene impedita la creazione con quell'id." + +#. Default: "Disallow ids used in aliases" +#: redturtle/volto/interfaces.py:32 +msgid "check_aliases_in_namechooser_label" +msgstr "Controllo degli id anche sugli alias" + #. Default: "If enabled, a custom ranking for SearchableText searches will be used." -#: redturtle/volto/interfaces.py:24 +#: redturtle/volto/interfaces.py:23 msgid "enable_advanced_query_ranking_help" msgstr "Se abilitato, verrà utilizzato un ranking custom per la ricerca testuale." #. Default: "Enable AdvancedQuery ranking" -#: redturtle/volto/interfaces.py:20 +#: redturtle/volto/interfaces.py:19 msgid "enable_advanced_query_ranking_label" msgstr "Abilita ranking custom con AdvancedQuery" +#. Default: "The id \"${id}\" is invalid because there is already an alias for that path. Search \"${fixed_path}\" in aliases management to manage it." +#: redturtle/volto/adapters/namechooser.py:35 +msgid "name_chooser_alias_error" +msgstr "L'id \"${id}\" non è valido perché già utilizzato per un alias. Puoi verificarlo ed eventualmente cancellarlo, cercando \"${fixed_path}\" nella Gestione URL." + #. Default: "Insert an external link directly into the field,or select an internal link clicking on the icon." #: redturtle/volto/types/adapters.py:25 msgid "remoteUrl_restapi_label" msgstr "Inserisci un link esterno direttamente nel campo, oppure seleziona un collegamento ad un contenuto del sito cliccando sull'icona accanto." #. Default: "Volto Parent URL: Content url without \"/api\"." -#: redturtle/volto/adapters/stringinterp.py:31 +#: redturtle/volto/adapters/stringinterp.py:35 msgid "stringinterp_volto_parent_url" msgstr "" #. Default: "Volto URL: Content url without \"/api\"." -#: redturtle/volto/adapters/stringinterp.py:13 +#: redturtle/volto/adapters/stringinterp.py:18 msgid "stringinterp_volto_url" msgstr "Volto URL: URL del contenuto Plone senza \"/api\"." diff --git a/src/redturtle/volto/locales/redturtle.volto.pot b/src/redturtle/volto/locales/redturtle.volto.pot index a940d56c..324ae062 100644 --- a/src/redturtle/volto/locales/redturtle.volto.pot +++ b/src/redturtle/volto/locales/redturtle.volto.pot @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2023-03-16 14:54+0000\n" +"POT-Creation-Date: 2024-03-21 13:53+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,7 +17,7 @@ msgstr "" "Preferred-Encodings: utf-8 latin1\n" "Domain: redturtle.volto\n" -#: redturtle/volto/configure.zcml:28 +#: redturtle/volto/configure.zcml:29 msgid "Installs the redturtle.volto add-on." msgstr "" @@ -30,11 +30,11 @@ msgstr "" msgid "RedTurtle Volto Settings" msgstr "" -#: redturtle/volto/configure.zcml:28 +#: redturtle/volto/configure.zcml:29 msgid "RedTurtle: Volto" msgstr "" -#: redturtle/volto/configure.zcml:37 +#: redturtle/volto/configure.zcml:38 msgid "RedTurtle: Volto (uninstall)" msgstr "" @@ -46,31 +46,46 @@ msgstr "" msgid "Show elements excluded from navigation" msgstr "" -#: redturtle/volto/configure.zcml:37 +#: redturtle/volto/configure.zcml:38 msgid "Uninstalls the redturtle.volto add-on." msgstr "" +#. Default: "If enabled, users can't create contents with ids that are already used as aliases." +#: redturtle/volto/interfaces.py:36 +msgid "check_aliases_in_namechooser_help" +msgstr "" + +#. Default: "Disallow ids used in aliases" +#: redturtle/volto/interfaces.py:32 +msgid "check_aliases_in_namechooser_label" +msgstr "" + #. Default: "If enabled, a custom ranking for SearchableText searches will be used." -#: redturtle/volto/interfaces.py:24 +#: redturtle/volto/interfaces.py:23 msgid "enable_advanced_query_ranking_help" msgstr "" #. Default: "Enable AdvancedQuery ranking" -#: redturtle/volto/interfaces.py:20 +#: redturtle/volto/interfaces.py:19 msgid "enable_advanced_query_ranking_label" msgstr "" +#. Default: "The id \"${id}\" is invalid because there is already an alias for that path. Search \"${fixed_path}\" in aliases management to manage it." +#: redturtle/volto/adapters/namechooser.py:35 +msgid "name_chooser_alias_error" +msgstr "" + #. Default: "Insert an external link directly into the field,or select an internal link clicking on the icon." #: redturtle/volto/types/adapters.py:25 msgid "remoteUrl_restapi_label" msgstr "" #. Default: "Volto Parent URL: Content url without \"/api\"." -#: redturtle/volto/adapters/stringinterp.py:31 +#: redturtle/volto/adapters/stringinterp.py:35 msgid "stringinterp_volto_parent_url" msgstr "" #. Default: "Volto URL: Content url without \"/api\"." -#: redturtle/volto/adapters/stringinterp.py:13 +#: redturtle/volto/adapters/stringinterp.py:18 msgid "stringinterp_volto_url" msgstr "" diff --git a/src/redturtle/volto/profiles/default/metadata.xml b/src/redturtle/volto/profiles/default/metadata.xml index f40d93d8..62f5e34b 100644 --- a/src/redturtle/volto/profiles/default/metadata.xml +++ b/src/redturtle/volto/profiles/default/metadata.xml @@ -1,6 +1,6 @@ - 4303 + 4304 profile-plone.volto:default profile-plone.app.caching:with-caching-proxy diff --git a/src/redturtle/volto/tests/test_namechooser_customization.py b/src/redturtle/volto/tests/test_namechooser_customization.py new file mode 100644 index 00000000..790fa0df --- /dev/null +++ b/src/redturtle/volto/tests/test_namechooser_customization.py @@ -0,0 +1,205 @@ +# -*- coding: utf-8 -*- +"""Setup tests for this package.""" +from plone import api +from plone.app.testing import setRoles +from plone.app.testing import TEST_USER_ID +from redturtle.volto.interfaces import IRedTurtleVoltoSettings +from redturtle.volto.testing import REDTURTLE_VOLTO_INTEGRATION_TESTING +from zExceptions import BadRequest +from zope.container.interfaces import INameChooser + +import unittest + + +class FakeObject: + """""" + + def __of__(self, xxx): + pass + + +class TestNameChooserDisabled(unittest.TestCase): + """ """ + + layer = REDTURTLE_VOLTO_INTEGRATION_TESTING + + def setUp(self): + self.app = self.layer["app"] + self.portal = self.layer["portal"] + self.portal_url = self.portal.absolute_url() + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + + foo = api.content.create( + container=self.portal, + type="Document", + title="Foo", + ) + + self.bar = api.content.create( + container=self.portal, + type="Document", + title="Bar", + ) + + api.content.rename(obj=foo, new_id="xxx") + + def test_by_default_customization_is_disabled_on_site_root(self): + """Test that we cannot choose an already created alias""" + fake_obj = FakeObject() + chooser = INameChooser(self.portal) + + # can set an unused id + self.assertEqual("unused-id", chooser.chooseName("unused id", fake_obj)) + + # default behavior when trying to use an already-created id + self.assertEqual("bar-1", chooser.chooseName("bar", fake_obj)) + + # do not raise exception if the name is an alias + self.assertEqual("foo", chooser.chooseName("foo", fake_obj)) + + def test_by_default_customization_is_disabled_on_site_folderish_container(self): + """Test that we cannot choose an already created alias""" + container = api.content.create( + container=self.portal, + type="Document", + title="container", + ) + + child = api.content.create( + container=container, + type="Document", + title="aaa", + ) + api.content.create( + container=container, + type="Document", + title="bbb", + ) + + api.content.rename(obj=child, new_id="xxx") + + fake_obj = FakeObject() + chooser = INameChooser(container) + + # can set an unused id + self.assertEqual("unused-id", chooser.chooseName("unused id", fake_obj)) + + # default behavior when trying to use an already-created id + self.assertEqual("bbb-1", chooser.chooseName("bbb", fake_obj)) + + # do not raise exception if the name is an alias + self.assertEqual("aaa", chooser.chooseName("aaa", fake_obj)) + + +class TestNameChooserEnabled(unittest.TestCase): + """ """ + + layer = REDTURTLE_VOLTO_INTEGRATION_TESTING + + def setUp(self): + self.app = self.layer["app"] + self.portal = self.layer["portal"] + self.portal_url = self.portal.absolute_url() + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + + foo = api.content.create( + container=self.portal, + type="Document", + title="Foo", + ) + + self.bar = api.content.create( + container=self.portal, + type="Document", + title="Bar", + ) + + api.content.rename(obj=foo, new_id="xxx") + + # enable it + api.portal.set_registry_record( + "check_aliases_in_namechooser", True, interface=IRedTurtleVoltoSettings + ) + + def test_name_chooser_raise_badrequest_on_site_root(self): + """Test that we cannot choose an already created alias""" + fake_obj = FakeObject() + chooser = INameChooser(self.portal) + + # can set an unused id + self.assertEqual("unused-id", chooser.chooseName("unused id", fake_obj)) + + # default behavior when trying to use an already-created id + self.assertEqual("bar-1", chooser.chooseName("bar", fake_obj)) + + # raise exception if the name is an alias + with self.assertRaises(BadRequest) as cm: + chooser.chooseName("foo", fake_obj) + + self.assertEqual( + 'The id "foo" is invalid because there is already an alias for that path. Search "/foo" in aliases management to manage it.', + str(cm.exception), + ) + + def test_if_enabled_name_chooser_raise_badrequest_on_folderish_container(self): + """Test that we cannot choose an already created alias""" + + container = api.content.create( + container=self.portal, + type="Document", + title="container", + ) + + child = api.content.create( + container=container, + type="Document", + title="aaa", + ) + api.content.create( + container=container, + type="Document", + title="bbb", + ) + + api.content.rename(obj=child, new_id="xxx") + + fake_obj = FakeObject() + chooser = INameChooser(container) + + # can set an unused id + self.assertEqual("unused-id", chooser.chooseName("unused id", fake_obj)) + + # can set an alias is used in another path + self.assertEqual("foo", chooser.chooseName("foo", fake_obj)) + + # default behavior when trying to use an already-created id in this context + self.assertEqual("bbb-1", chooser.chooseName("bbb", fake_obj)) + + # raise exception if the name is an alias + with self.assertRaises(BadRequest) as cm: + chooser.chooseName("aaa", fake_obj) + + self.assertEqual( + 'The id "aaa" is invalid because there is already an alias for that path. Search "/container/aaa" in aliases management to manage it.', + str(cm.exception), + ) + + def test_api_rename_raise_exception_if_name_is_alias(self): + """Test that we cannot choose an already created alias""" + + item = api.content.create( + container=self.portal, + type="Document", + title="item", + ) + with self.assertRaises(BadRequest) as cm: + api.content.rename(obj=item, new_id="foo", safe_id=True) + + self.assertEqual( + 'The id "foo" is invalid because there is already an alias for that path. Search "/foo" in aliases management to manage it.', + str(cm.exception), + ) + + # without safe_id=True, InameChooser will not be called + res = api.content.rename(obj=item, new_id="foo") + self.assertEqual(res.getId(), "foo") diff --git a/src/redturtle/volto/upgrades.zcml b/src/redturtle/volto/upgrades.zcml index ff5d3b20..8b574dae 100644 --- a/src/redturtle/volto/upgrades.zcml +++ b/src/redturtle/volto/upgrades.zcml @@ -216,4 +216,12 @@ handler=".upgrades.to_4303" /> + From 9e090d3f67bb6bebc5c354b0e766920474343cf8 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Thu, 28 Mar 2024 15:02:32 +0100 Subject: [PATCH 02/18] change cookie plugin: collective.volto.cookieconsent => collective.volto.gdprcookie --- CHANGES.rst | 5 ++++- setup.py | 3 ++- src/redturtle/volto/profiles/default/metadata.xml | 4 ++-- src/redturtle/volto/upgrades.py | 9 +++++++++ src/redturtle/volto/upgrades.zcml | 8 ++++++++ 5 files changed, 25 insertions(+), 4 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 901da6e0..9ffb81fc 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -8,7 +8,10 @@ Changelog [cekk] - Add flag in controlpanel to enable/disable INameChooser customization. [cekk] - +- Uninstall collective.volto.cookieconsent (deprecated). Will be removed from dependencies in next releases. + [cekk] +- Add dependency to collective.volto.gdprcookie and install it by default. + [cekk] 5.4.8 (2024-03-19) ------------------ diff --git a/setup.py b/setup.py index b2c68538..505eaa27 100644 --- a/setup.py +++ b/setup.py @@ -54,7 +54,8 @@ python_requires=">=3.7", install_requires=[ "setuptools", - "collective.volto.cookieconsent", + "collective.volto.cookieconsent", # this will be uninstalled and removed soon. + "collective.volto.gdprcookie", "collective.monkeypatcher", "collective.purgebyid", "kitconcept.seo>=2.0.0", diff --git a/src/redturtle/volto/profiles/default/metadata.xml b/src/redturtle/volto/profiles/default/metadata.xml index 62f5e34b..a10e361f 100644 --- a/src/redturtle/volto/profiles/default/metadata.xml +++ b/src/redturtle/volto/profiles/default/metadata.xml @@ -1,10 +1,10 @@ - 4304 + 4305 profile-plone.volto:default profile-plone.app.caching:with-caching-proxy - profile-collective.volto.cookieconsent:default + profile-collective.volto.gdprcookie:default profile-kitconcept.seo:default diff --git a/src/redturtle/volto/upgrades.py b/src/redturtle/volto/upgrades.py index ff45e9d1..73fa8093 100644 --- a/src/redturtle/volto/upgrades.py +++ b/src/redturtle/volto/upgrades.py @@ -8,6 +8,7 @@ from redturtle.volto.setuphandlers import remove_custom_googlebot from uuid import uuid4 from zope.schema import getFields +from plone.base.utils import get_installer import json import logging @@ -494,3 +495,11 @@ def to_4303(context): for brain in brains: event = brain.getObject() event.reindexObject(idxs=["start", "end"]) + + +def to_4305(context): + portal = api.portal.get() + installer = get_installer(portal, portal.REQUEST) + installer.uninstall_product(product_id="collective.volto.cookieconsent") + if not installer.is_product_installed("collective.volto.gdprcookie"): + installer.install_(product_id="collective.volto.gdprcookie") diff --git a/src/redturtle/volto/upgrades.zcml b/src/redturtle/volto/upgrades.zcml index 8b574dae..1014d94c 100644 --- a/src/redturtle/volto/upgrades.zcml +++ b/src/redturtle/volto/upgrades.zcml @@ -224,4 +224,12 @@ destination="4304" handler=".upgrades.update_registry" /> + From c30afc74dd7fdf69269a5cb72c9cbe7aef121f21 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Thu, 28 Mar 2024 15:04:22 +0100 Subject: [PATCH 03/18] code cleanup --- src/redturtle/volto/upgrades.py | 2 +- src/redturtle/volto/upgrades.zcml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/redturtle/volto/upgrades.py b/src/redturtle/volto/upgrades.py index 73fa8093..8c091fab 100644 --- a/src/redturtle/volto/upgrades.py +++ b/src/redturtle/volto/upgrades.py @@ -3,12 +3,12 @@ from copy import deepcopy from plone import api from plone.app.upgrade.utils import installOrReinstallProduct +from plone.base.utils import get_installer from plone.dexterity.utils import iterSchemata from plone.restapi.behaviors import IBlocks from redturtle.volto.setuphandlers import remove_custom_googlebot from uuid import uuid4 from zope.schema import getFields -from plone.base.utils import get_installer import json import logging diff --git a/src/redturtle/volto/upgrades.zcml b/src/redturtle/volto/upgrades.zcml index 1014d94c..8e8b91ec 100644 --- a/src/redturtle/volto/upgrades.zcml +++ b/src/redturtle/volto/upgrades.zcml @@ -224,7 +224,7 @@ destination="4304" handler=".upgrades.update_registry" /> - Date: Thu, 28 Mar 2024 15:12:58 +0100 Subject: [PATCH 04/18] fix tests --- src/redturtle/volto/testing.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/redturtle/volto/testing.py b/src/redturtle/volto/testing.py index 81d9eb91..b1a227fb 100644 --- a/src/redturtle/volto/testing.py +++ b/src/redturtle/volto/testing.py @@ -8,7 +8,7 @@ from plone.restapi.testing import PloneRestApiDXLayer from plone.testing import z2 -import collective.volto.cookieconsent +import collective.volto.gdprcookie import kitconcept.seo import plone.app.caching import plone.restapi @@ -23,7 +23,7 @@ def setUpZope(self, app, configurationContext): # Load any other ZCML that is required for your tests. # The z3c.autoinclude feature is disabled in the Plone fixture base # layer. - self.loadZCML(package=collective.volto.cookieconsent) + self.loadZCML(package=collective.volto.gdprcookie) self.loadZCML(package=plone.restapi) self.loadZCML(package=redturtle.volto) self.loadZCML(package=plone.volto) @@ -66,7 +66,7 @@ class RedturtleVoltoRestApiLayer(PloneRestApiDXLayer): def setUpZope(self, app, configurationContext): super(RedturtleVoltoRestApiLayer, self).setUpZope(app, configurationContext) - self.loadZCML(package=collective.volto.cookieconsent) + self.loadZCML(package=collective.volto.gdprcookie) self.loadZCML(package=plone.restapi) self.loadZCML(package=plone.volto) self.loadZCML(package=redturtle.volto) From 845fe10cc8dc251081700ef0c853fdc3f589227a Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Thu, 28 Mar 2024 15:19:41 +0100 Subject: [PATCH 05/18] fix plone52 compat --- src/redturtle/volto/upgrades.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/redturtle/volto/upgrades.py b/src/redturtle/volto/upgrades.py index 8c091fab..796ab3c0 100644 --- a/src/redturtle/volto/upgrades.py +++ b/src/redturtle/volto/upgrades.py @@ -3,13 +3,18 @@ from copy import deepcopy from plone import api from plone.app.upgrade.utils import installOrReinstallProduct -from plone.base.utils import get_installer from plone.dexterity.utils import iterSchemata from plone.restapi.behaviors import IBlocks from redturtle.volto.setuphandlers import remove_custom_googlebot from uuid import uuid4 from zope.schema import getFields + +try: + from plone.base.utils import get_installer +except Exception: + from Products.CMFPlone.utils import get_installer + import json import logging From 03eee64364014a8ee7a8d9ea39fb14ee0f6a894a Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Thu, 28 Mar 2024 16:02:57 +0100 Subject: [PATCH 06/18] fix list of skipped fields in serializer/deserializer --- CHANGES.rst | 2 ++ src/redturtle/volto/restapi/deserializer/blocks.py | 10 ++++++++-- src/redturtle/volto/restapi/serializer/blocks.py | 10 ++++++++-- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 901da6e0..aa2f0b95 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -8,6 +8,8 @@ Changelog [cekk] - Add flag in controlpanel to enable/disable INameChooser customization. [cekk] +- Exclude bg_color from transformed fields in deserializer. + [cekk] 5.4.8 (2024-03-19) diff --git a/src/redturtle/volto/restapi/deserializer/blocks.py b/src/redturtle/volto/restapi/deserializer/blocks.py index da3d4a90..78e6610c 100644 --- a/src/redturtle/volto/restapi/deserializer/blocks.py +++ b/src/redturtle/volto/restapi/deserializer/blocks.py @@ -9,8 +9,14 @@ from zope.interface import implementer -EXCLUDE_KEYS = ["@type", "token", "value", "@id", "query"] -EXCLUDE_TYPES = ["title", "listing", "calendar", "searchEvents", "form"] +EXCLUDE_KEYS = ["@type", "token", "value", "@id", "query", "bg_color"] +EXCLUDE_TYPES = [ + "title", + "listing", + "calendar", + "searchEvents", + "form", +] class GenericResolveUIDDeserializer(object): diff --git a/src/redturtle/volto/restapi/serializer/blocks.py b/src/redturtle/volto/restapi/serializer/blocks.py index c026526f..f65eb180 100644 --- a/src/redturtle/volto/restapi/serializer/blocks.py +++ b/src/redturtle/volto/restapi/serializer/blocks.py @@ -13,8 +13,14 @@ from zope.interface import implementer -EXCLUDE_KEYS = ["@type"] -EXCLUDE_TYPES = ["title", "listing", "form"] +EXCLUDE_KEYS = ["@type", "token", "value", "@id", "query", "bg_color"] +EXCLUDE_TYPES = [ + "title", + "listing", + "calendar", + "searchEvents", + "form", +] class GenericResolveUIDSerializer(object): From 9e5a091b438cb734aae50ddcd7f5d27910e6dac3 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Mon, 8 Apr 2024 13:14:41 +0200 Subject: [PATCH 07/18] Limit event occurrences to 1000. --- CHANGES.rst | 2 ++ src/redturtle/volto/monkey.py | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index 901da6e0..29cc87d9 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,8 @@ Changelog 5.4.9 (unreleased) ------------------ +- Limit event occurrences to 1000. + [mamico] - Customize INameChooser adapter to check also alias ids and disallow to create contents that could override aliases. [cekk] - Add flag in controlpanel to enable/disable INameChooser customization. diff --git a/src/redturtle/volto/monkey.py b/src/redturtle/volto/monkey.py index 609aa18b..30d6f120 100644 --- a/src/redturtle/volto/monkey.py +++ b/src/redturtle/volto/monkey.py @@ -14,9 +14,13 @@ from zope.globalrequest import getRequest import datetime +import logging import os +logger = logging.getLogger(__name__) + + def occurrences(self, range_start=None, range_end=None): """Return all occurrences of an event, possibly within a start and end limit. @@ -94,7 +98,15 @@ def get_obj(start): id=str(start.date()), start=start, end=start + duration ).__of__(self.context) + limit = 100 for start in starts: + if limit < 0: + logger.warning( + "Too many occurrences, for %s stopping at 100", + self.context.absolute_url(), + ) + raise StopIteration + limit -= 1 yield get_obj(start) From 281b95d1f7a21cd5b5a344d82606ad055aadaba9 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Mon, 8 Apr 2024 13:16:30 +0200 Subject: [PATCH 08/18] 1000 --- src/redturtle/volto/monkey.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/redturtle/volto/monkey.py b/src/redturtle/volto/monkey.py index 30d6f120..868ef354 100644 --- a/src/redturtle/volto/monkey.py +++ b/src/redturtle/volto/monkey.py @@ -98,11 +98,11 @@ def get_obj(start): id=str(start.date()), start=start, end=start + duration ).__of__(self.context) - limit = 100 + limit = 1000 for start in starts: if limit < 0: logger.warning( - "Too many occurrences, for %s stopping at 100", + "Too many occurrences, for %s stopping at 1000", self.context.absolute_url(), ) raise StopIteration From 693ab669a98f36b978994dcc7d80be6503b918cd Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Mon, 8 Apr 2024 13:16:58 +0200 Subject: [PATCH 09/18] typo --- src/redturtle/volto/monkey.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/redturtle/volto/monkey.py b/src/redturtle/volto/monkey.py index 868ef354..a5c6dd67 100644 --- a/src/redturtle/volto/monkey.py +++ b/src/redturtle/volto/monkey.py @@ -102,7 +102,7 @@ def get_obj(start): for start in starts: if limit < 0: logger.warning( - "Too many occurrences, for %s stopping at 1000", + "Too many occurrences for %s, stopping at 1000", self.context.absolute_url(), ) raise StopIteration From af8491686fc566b09552c79683a496da1a9fcc67 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Mon, 8 Apr 2024 13:18:07 +0200 Subject: [PATCH 10/18] 100 --- CHANGES.rst | 2 +- src/redturtle/volto/monkey.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 29cc87d9..95062ad0 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,7 @@ Changelog 5.4.9 (unreleased) ------------------ -- Limit event occurrences to 1000. +- Limit event occurrences to 100. [mamico] - Customize INameChooser adapter to check also alias ids and disallow to create contents that could override aliases. [cekk] diff --git a/src/redturtle/volto/monkey.py b/src/redturtle/volto/monkey.py index a5c6dd67..5278cb39 100644 --- a/src/redturtle/volto/monkey.py +++ b/src/redturtle/volto/monkey.py @@ -98,11 +98,11 @@ def get_obj(start): id=str(start.date()), start=start, end=start + duration ).__of__(self.context) - limit = 1000 + limit = 100 for start in starts: if limit < 0: logger.warning( - "Too many occurrences for %s, stopping at 1000", + "Too many occurrences for %s, stopping at 100", self.context.absolute_url(), ) raise StopIteration From 89b1d016312d1b0784acda477b0c405e7ce0fed2 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Wed, 10 Apr 2024 17:12:44 +0200 Subject: [PATCH 11/18] fix typo --- src/redturtle/volto/upgrades.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/redturtle/volto/upgrades.py b/src/redturtle/volto/upgrades.py index 796ab3c0..cc0db688 100644 --- a/src/redturtle/volto/upgrades.py +++ b/src/redturtle/volto/upgrades.py @@ -507,4 +507,4 @@ def to_4305(context): installer = get_installer(portal, portal.REQUEST) installer.uninstall_product(product_id="collective.volto.cookieconsent") if not installer.is_product_installed("collective.volto.gdprcookie"): - installer.install_(product_id="collective.volto.gdprcookie") + installer.install_product(product_id="collective.volto.gdprcookie") From c725e3c9d3cd4578ae3eaacb40cb724dc2763588 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 22 Apr 2024 15:35:51 +0200 Subject: [PATCH 12/18] Preparing release 5.4.9 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index de5035bb..3eb9e556 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -5.4.9 (unreleased) +5.4.9 (2024-04-22) ------------------ - Limit event occurrences to 100. diff --git a/setup.py b/setup.py index 505eaa27..69cad6ae 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="redturtle.volto", - version="5.4.9.dev0", + version="5.4.9", description="Helper package to setup a RedTurtle's Plone site ready to work with Volto.", long_description=long_description, # Get more from https://pypi.org/classifiers/ From 8011256d98c52bb972df6fa0ab52c9b9e657e5bb Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 22 Apr 2024 15:36:18 +0200 Subject: [PATCH 13/18] Back to development: 5.4.10 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 3eb9e556..137bdcab 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +5.4.10 (unreleased) +------------------- + +- Nothing changed yet. + + 5.4.9 (2024-04-22) ------------------ diff --git a/setup.py b/setup.py index 69cad6ae..88cfe773 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="redturtle.volto", - version="5.4.9", + version="5.4.10.dev0", description="Helper package to setup a RedTurtle's Plone site ready to work with Volto.", long_description=long_description, # Get more from https://pypi.org/classifiers/ From e5665a5cfaddb7f4462478580643f4b4e6ce091e Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Tue, 7 May 2024 00:00:04 +0200 Subject: [PATCH 14/18] Override copymove for aliases (#103) * Customize also and endpoints to raise BadRequest if that action will override some aliases. * add test * add test * zpretty * fix tests * Update src/redturtle/volto/restapi/services/copymove/copymove.py * Update src/redturtle/volto/restapi/services/copymove/copymove.py * self.context is the destintaion != parent that is the parent of the source --------- Co-authored-by: Mauro Amico --- .gitignore | 1 + CHANGES.rst | 2 + src/redturtle/volto/adapters/namechooser.py | 50 +++++++------ .../locales/it/LC_MESSAGES/redturtle.volto.po | 8 +-- .../volto/locales/redturtle.volto.pot | 6 +- .../volto/restapi/services/configure.zcml | 1 + .../restapi/services/copymove/__init__.py | 0 .../restapi/services/copymove/configure.zcml | 25 +++++++ .../restapi/services/copymove/copymove.py | 21 ++++++ .../tests/test_copymove_customization.py | 72 +++++++++++++++++++ .../tests/test_namechooser_customization.py | 6 +- 11 files changed, 160 insertions(+), 32 deletions(-) create mode 100644 src/redturtle/volto/restapi/services/copymove/__init__.py create mode 100644 src/redturtle/volto/restapi/services/copymove/configure.zcml create mode 100644 src/redturtle/volto/restapi/services/copymove/copymove.py create mode 100644 src/redturtle/volto/tests/test_copymove_customization.py diff --git a/.gitignore b/.gitignore index e33788dd..1e7140e1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +__pycache__ .DS_Store pyvenv.cfg .coverage diff --git a/CHANGES.rst b/CHANGES.rst index 137bdcab..b0e04708 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -14,6 +14,8 @@ Changelog [mamico] - Customize INameChooser adapter to check also alias ids and disallow to create contents that could override aliases. [cekk] +- Customize also `copy` and `move` endpoints to raise BadRequest if that action will override some aliases. + [cekk] - Add flag in controlpanel to enable/disable INameChooser customization. [cekk] - Exclude bg_color from transformed fields in deserializer. diff --git a/src/redturtle/volto/adapters/namechooser.py b/src/redturtle/volto/adapters/namechooser.py index f400ee9e..fdf3f965 100644 --- a/src/redturtle/volto/adapters/namechooser.py +++ b/src/redturtle/volto/adapters/namechooser.py @@ -10,32 +10,38 @@ from zope.component import getUtility +def check_alias(context, id): + context = aq_inner(context) + try: + if not api.portal.get_registry_record( + "check_aliases_in_namechooser", + interface=IRedTurtleVoltoSettings, + default=False, + ): + return + except KeyError: + return + storage = getUtility(IRedirectionStorage) + path = "/".join(context.getPhysicalPath()) + "/" + id + if storage.get(path): + portal_path = "/".join(api.portal.get().getPhysicalPath()) + fixed_path = path.replace(portal_path, "") + msg = _( + "name_chooser_alias_error", + default='The id "${id}" is invalid because there is already an alias for that path. ' + 'Change its id or ask site administrators to remove "${fixed_path}" in aliases management.', + mapping={"id": id, "fixed_path": fixed_path}, + ) + raise BadRequest(api.portal.translate(msg)) + + class NormalizingNameChooser(BaseNormalizingNameChooser): def chooseName(self, name, obj): """ Additional check: the id should not be in redirection tool. """ id = super().chooseName(name=name, obj=obj) - try: - if not api.portal.get_registry_record( - "check_aliases_in_namechooser", - interface=IRedTurtleVoltoSettings, - default=False, - ): - return id - except KeyError: - return id - parent = aq_inner(self.context) - storage = getUtility(IRedirectionStorage) - path = "/".join(parent.getPhysicalPath()) + "/" + id - if storage.get(path): - portal_path = "/".join(api.portal.get().getPhysicalPath()) - fixed_path = path.replace(portal_path, "") - msg = _( - "name_chooser_alias_error", - default='The id "${id}" is invalid because there is already an alias for that path. ' - 'Search "${fixed_path}" in aliases management to manage it.', - mapping={"id": id, "fixed_path": fixed_path}, - ) - raise BadRequest(api.portal.translate(msg)) + + # this raise BadRequest if there is an override with aliases + check_alias(context=self.context, id=id) return id diff --git a/src/redturtle/volto/locales/it/LC_MESSAGES/redturtle.volto.po b/src/redturtle/volto/locales/it/LC_MESSAGES/redturtle.volto.po index 1d4f8503..32f7ed60 100644 --- a/src/redturtle/volto/locales/it/LC_MESSAGES/redturtle.volto.po +++ b/src/redturtle/volto/locales/it/LC_MESSAGES/redturtle.volto.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2024-03-21 13:53+0000\n" +"POT-Creation-Date: 2024-03-28 10:20+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -67,10 +67,10 @@ msgstr "Se abilitato, verrà utilizzato un ranking custom per la ricerca testual msgid "enable_advanced_query_ranking_label" msgstr "Abilita ranking custom con AdvancedQuery" -#. Default: "The id \"${id}\" is invalid because there is already an alias for that path. Search \"${fixed_path}\" in aliases management to manage it." -#: redturtle/volto/adapters/namechooser.py:35 +#. Default: "The id \"${id}\" is invalid because there is already an alias for that path. Change its id or ask site administrators to remove \"${fixed_path}\" in aliases management." +#: redturtle/volto/adapters/namechooser.py:29 msgid "name_chooser_alias_error" -msgstr "L'id \"${id}\" non è valido perché già utilizzato per un alias. Puoi verificarlo ed eventualmente cancellarlo, cercando \"${fixed_path}\" nella Gestione URL." +msgstr "L'id \"${id}\" non è valido perché già utilizzato per un alias. Modifca l'id oppure rivolgiti agli amministratori per cancellare l'alias esistente: \"${fixed_path}\"." #. Default: "Insert an external link directly into the field,or select an internal link clicking on the icon." #: redturtle/volto/types/adapters.py:25 diff --git a/src/redturtle/volto/locales/redturtle.volto.pot b/src/redturtle/volto/locales/redturtle.volto.pot index 324ae062..a33cfec1 100644 --- a/src/redturtle/volto/locales/redturtle.volto.pot +++ b/src/redturtle/volto/locales/redturtle.volto.pot @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2024-03-21 13:53+0000\n" +"POT-Creation-Date: 2024-03-28 12:42+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -70,8 +70,8 @@ msgstr "" msgid "enable_advanced_query_ranking_label" msgstr "" -#. Default: "The id \"${id}\" is invalid because there is already an alias for that path. Search \"${fixed_path}\" in aliases management to manage it." -#: redturtle/volto/adapters/namechooser.py:35 +#. Default: "The id \"${id}\" is invalid because there is already an alias for that path. Change its id or ask site administrators to remove \"${fixed_path}\" in aliases management." +#: redturtle/volto/adapters/namechooser.py:29 msgid "name_chooser_alias_error" msgstr "" diff --git a/src/redturtle/volto/restapi/services/configure.zcml b/src/redturtle/volto/restapi/services/configure.zcml index ae6e12a8..25e3acbf 100644 --- a/src/redturtle/volto/restapi/services/configure.zcml +++ b/src/redturtle/volto/restapi/services/configure.zcml @@ -3,6 +3,7 @@ xmlns:zcml="http://namespaces.zope.org/zcml" > + diff --git a/src/redturtle/volto/restapi/services/copymove/__init__.py b/src/redturtle/volto/restapi/services/copymove/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/redturtle/volto/restapi/services/copymove/configure.zcml b/src/redturtle/volto/restapi/services/copymove/configure.zcml new file mode 100644 index 00000000..8a44f77d --- /dev/null +++ b/src/redturtle/volto/restapi/services/copymove/configure.zcml @@ -0,0 +1,25 @@ + + + + + + + diff --git a/src/redturtle/volto/restapi/services/copymove/copymove.py b/src/redturtle/volto/restapi/services/copymove/copymove.py new file mode 100644 index 00000000..fa63dcf6 --- /dev/null +++ b/src/redturtle/volto/restapi/services/copymove/copymove.py @@ -0,0 +1,21 @@ +from plone.restapi.services.copymove.copymove import Copy as BaseCopy +from plone.restapi.services.copymove.copymove import Move as BaseMove +from redturtle.volto.adapters.namechooser import check_alias + + +class Copy(BaseCopy): + """Copies existing content objects.""" + + def clipboard(self, parent, ids): + for id in ids: + check_alias(context=self.context, id=id) + return super().clipboard(parent, ids) + + +class Move(BaseMove): + """Moves existing content objects.""" + + def clipboard(self, parent, ids): + for id in ids: + check_alias(context=self.context, id=id) + return super().clipboard(parent, ids) diff --git a/src/redturtle/volto/tests/test_copymove_customization.py b/src/redturtle/volto/tests/test_copymove_customization.py new file mode 100644 index 00000000..faaa5d5d --- /dev/null +++ b/src/redturtle/volto/tests/test_copymove_customization.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- +from plone import api +from plone.app.testing import setRoles +from plone.app.testing import SITE_OWNER_NAME +from plone.app.testing import SITE_OWNER_PASSWORD +from plone.app.testing import TEST_USER_ID +from plone.restapi.testing import RelativeSession +from redturtle.volto.interfaces import IRedTurtleVoltoSettings +from redturtle.volto.testing import REDTURTLE_VOLTO_API_FUNCTIONAL_TESTING + +import transaction +import unittest + + +class TestCopyMoveCustomization(unittest.TestCase): + layer = REDTURTLE_VOLTO_API_FUNCTIONAL_TESTING + + def setUp(self): + self.app = self.layer["app"] + self.portal = self.layer["portal"] + self.portal_url = self.portal.absolute_url() + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + + self.api_session = RelativeSession(self.portal_url) + self.api_session.headers.update({"Accept": "application/json"}) + self.api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD) + + foo = api.content.create( + container=self.portal, + type="Document", + title="Foo", + ) + api.content.rename(obj=foo, new_id="xxx") + + self.bar = api.content.create( + container=self.portal, + type="Document", + title="Bar", + ) + api.content.create( + container=self.bar, + type="Document", + title="foo", + ) + + # enable it + api.portal.set_registry_record( + "check_aliases_in_namechooser", True, interface=IRedTurtleVoltoSettings + ) + + transaction.commit() + + def tearDown(self): + self.api_session.close() + + def test_move_raise_error_if_id_is_a_valid_alias(self): + response = self.api_session.post("/@move", json={"source": ["/bar/foo"]}) + + self.assertEqual(response.status_code, 400) + self.assertEqual( + response.json()["message"], + 'The id "foo" is invalid because there is already an alias for that path. Change its id or ask site administrators to remove "/foo" in aliases management.', + ) + + def test_copy_raise_error_if_id_is_a_valid_alias(self): + response = self.api_session.post("/@copy", json={"source": ["/bar/foo"]}) + + self.assertEqual(response.status_code, 400) + self.assertEqual( + response.json()["message"], + 'The id "foo" is invalid because there is already an alias for that path. Change its id or ask site administrators to remove "/foo" in aliases management.', + ) diff --git a/src/redturtle/volto/tests/test_namechooser_customization.py b/src/redturtle/volto/tests/test_namechooser_customization.py index 790fa0df..1f5a628a 100644 --- a/src/redturtle/volto/tests/test_namechooser_customization.py +++ b/src/redturtle/volto/tests/test_namechooser_customization.py @@ -137,7 +137,7 @@ def test_name_chooser_raise_badrequest_on_site_root(self): chooser.chooseName("foo", fake_obj) self.assertEqual( - 'The id "foo" is invalid because there is already an alias for that path. Search "/foo" in aliases management to manage it.', + 'The id "foo" is invalid because there is already an alias for that path. Change its id or ask site administrators to remove "/foo" in aliases management.', str(cm.exception), ) @@ -180,7 +180,7 @@ def test_if_enabled_name_chooser_raise_badrequest_on_folderish_container(self): chooser.chooseName("aaa", fake_obj) self.assertEqual( - 'The id "aaa" is invalid because there is already an alias for that path. Search "/container/aaa" in aliases management to manage it.', + 'The id "aaa" is invalid because there is already an alias for that path. Change its id or ask site administrators to remove "/container/aaa" in aliases management.', str(cm.exception), ) @@ -196,7 +196,7 @@ def test_api_rename_raise_exception_if_name_is_alias(self): api.content.rename(obj=item, new_id="foo", safe_id=True) self.assertEqual( - 'The id "foo" is invalid because there is already an alias for that path. Search "/foo" in aliases management to manage it.', + 'The id "foo" is invalid because there is already an alias for that path. Change its id or ask site administrators to remove "/foo" in aliases management.', str(cm.exception), ) From 3b5232f6a5186a0ead8b98ebb9febf0ed7b7a4ed Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 12 Jun 2024 15:41:39 +0200 Subject: [PATCH 15/18] Fix limit occurrences to 100 (#109) --- CHANGES.rst | 3 ++- src/redturtle/volto/monkey.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index b0e04708..e7221ef7 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,8 @@ Changelog 5.4.10 (unreleased) ------------------- -- Nothing changed yet. +- Fixed limit event occurrences to 100. + [eikichi18] 5.4.9 (2024-04-22) diff --git a/src/redturtle/volto/monkey.py b/src/redturtle/volto/monkey.py index 5278cb39..180888ed 100644 --- a/src/redturtle/volto/monkey.py +++ b/src/redturtle/volto/monkey.py @@ -105,7 +105,7 @@ def get_obj(start): "Too many occurrences for %s, stopping at 100", self.context.absolute_url(), ) - raise StopIteration + return limit -= 1 yield get_obj(start) From bcdf147a938a7f800cbb9e1299f9440e53dca870 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Mon, 24 Jun 2024 09:51:21 +0200 Subject: [PATCH 16/18] fix: missing deps --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 88cfe773..c2648a3f 100644 --- a/setup.py +++ b/setup.py @@ -62,6 +62,7 @@ "plone.volto>=4.0.0", "plone.restapi>=9.6.0", "Products.PortalTransforms>=3.2.0", + "z3c.jbot", ], extras_require={ "advancedquery": [ From 497271ace4a8309fb7b8f6f4f7b118028d28bfd9 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Mon, 24 Jun 2024 12:28:52 +0200 Subject: [PATCH 17/18] fix tests --- .github/workflows/black.yml | 13 ++++--------- .github/workflows/flake8.yml | 13 ++++--------- .github/workflows/isort.yaml | 2 +- .github/workflows/pyroma.yml | 13 ++++--------- buildout.cfg | 3 +++ src/redturtle/volto/tests/test_advancedsearch.py | 1 + test_plone52.cfg | 3 ++- test_plone60.cfg | 3 ++- 8 files changed, 21 insertions(+), 30 deletions(-) diff --git a/.github/workflows/black.yml b/.github/workflows/black.yml index 9b23c028..9d8d08f4 100644 --- a/.github/workflows/black.yml +++ b/.github/workflows/black.yml @@ -6,30 +6,25 @@ jobs: strategy: fail-fast: false matrix: - python-version: [3.8] + python-version: [3.11] steps: - # git checkout - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - # python setup - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v1 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - # python cache - - uses: actions/cache@v1 + - uses: actions/cache@v4 with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} restore-keys: | ${{ runner.os }}-pip- - # install black - name: install black run: pip install black - # run black - name: run black run: black src/ --check --diff diff --git a/.github/workflows/flake8.yml b/.github/workflows/flake8.yml index 97c7dfa4..8300d45f 100644 --- a/.github/workflows/flake8.yml +++ b/.github/workflows/flake8.yml @@ -6,30 +6,25 @@ jobs: strategy: fail-fast: false matrix: - python-version: [3.8] + python-version: [3.11] steps: - # git checkout - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - # python setup - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v1 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - # python cache - - uses: actions/cache@v1 + - uses: actions/cache@v4 with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} restore-keys: | ${{ runner.os }}-pip- - # install flake8 - name: install flake8 run: pip install flake8 - # run black - name: run flake8 run: flake8 src/ setup.py diff --git a/.github/workflows/isort.yaml b/.github/workflows/isort.yaml index 039aeb05..050b2a4c 100644 --- a/.github/workflows/isort.yaml +++ b/.github/workflows/isort.yaml @@ -6,5 +6,5 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: isort/isort-action@v1 diff --git a/.github/workflows/pyroma.yml b/.github/workflows/pyroma.yml index bbad3c28..038fdd83 100644 --- a/.github/workflows/pyroma.yml +++ b/.github/workflows/pyroma.yml @@ -6,30 +6,25 @@ jobs: strategy: fail-fast: false matrix: - python-version: [3.8] + python-version: [3.11] steps: - # git checkout - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - # python setup - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v1 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - # python cache - - uses: actions/cache@v1 + - uses: actions/cache@v4 with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} restore-keys: | ${{ runner.os }}-pip- - # install pyroma - name: install pyroma run: pip install pyroma - # run pyroma - name: run pyroma run: pyroma -n 10 -d . diff --git a/buildout.cfg b/buildout.cfg index d7db0388..6bd3272b 100644 --- a/buildout.cfg +++ b/buildout.cfg @@ -3,3 +3,6 @@ # use this extend one of the buildout configuration: extends = test_plone60.cfg + +[versions] +plone.restapi = 9.7.0 diff --git a/src/redturtle/volto/tests/test_advancedsearch.py b/src/redturtle/volto/tests/test_advancedsearch.py index abf58c55..5dfbde2a 100644 --- a/src/redturtle/volto/tests/test_advancedsearch.py +++ b/src/redturtle/volto/tests/test_advancedsearch.py @@ -111,6 +111,7 @@ def test_search_bar(self): response = self.api_session.get("/@search", params={"SearchableText": "bar"}) self.assertEqual(response.status_code, 200) result = response.json() + import pdb; pdb.set_trace() self.assertEqual(result["items_total"], 3) self.assertEqual( ["d1", "e1", "f1"], [item["@id"].split("/")[-1] for item in result["items"]] diff --git a/test_plone52.cfg b/test_plone52.cfg index 146d479c..0cc701d9 100644 --- a/test_plone52.cfg +++ b/test_plone52.cfg @@ -14,7 +14,8 @@ plone.app.versioningbehavior = 1.4.6 plone.app.vocabularies = 4.3.0 plone.patternslib = 1.1.1 plone.rest = 2.0.0 -plone.restapi = >=9.6.0 +# plone.restapi >= 9.6.1 don't put subjects into SearchableText (to investigate) +plone.restapi = 9.6.0 plone.volto = 4.0.0 pycountry = 19.8.18 collective.purgebyid = 1.1.1 diff --git a/test_plone60.cfg b/test_plone60.cfg index 241cc1e3..d4b58c6c 100644 --- a/test_plone60.cfg +++ b/test_plone60.cfg @@ -17,4 +17,5 @@ plone.recipe.codeanalysis = 3.0.1 pycodestyle = 2.10.0 pyflakes = 3.0.1 plone.stringinterp = 2.0.0 -plone.restapi = >=9.6.0 +# plone.restapi >= 9.6.1 don't put subjects into SearchableText (to investigate) +plone.restapi = 9.6.0 From 867e4b83f39bba28374961263850856c48c1d6fc Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Mon, 24 Jun 2024 12:29:13 +0200 Subject: [PATCH 18/18] fix tests --- src/redturtle/volto/tests/test_advancedsearch.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/redturtle/volto/tests/test_advancedsearch.py b/src/redturtle/volto/tests/test_advancedsearch.py index 5dfbde2a..abf58c55 100644 --- a/src/redturtle/volto/tests/test_advancedsearch.py +++ b/src/redturtle/volto/tests/test_advancedsearch.py @@ -111,7 +111,6 @@ def test_search_bar(self): response = self.api_session.get("/@search", params={"SearchableText": "bar"}) self.assertEqual(response.status_code, 200) result = response.json() - import pdb; pdb.set_trace() self.assertEqual(result["items_total"], 3) self.assertEqual( ["d1", "e1", "f1"], [item["@id"].split("/")[-1] for item in result["items"]]