Skip to content

Commit

Permalink
[fc] Repository: plone.locking
Browse files Browse the repository at this point in the history
Branch: refs/heads/master
Date: 2021-10-08T16:51:24+02:00
Author: Érico Andrei (ericof) <ericof@gmail.com>
Commit: plone/plone.locking@780f9b6

Register a fallback @@plone_lock_info view to allow objects without plone.locking behavior to be edited.

Files changed:
A news/3331.fix
A plone/locking/tests/test_views.py
M plone/locking/browser/locking.py
M plone/locking/configure.zcml
Repository: plone.locking

Branch: refs/heads/master
Date: 2021-10-08T23:33:43+02:00
Author: Maurits van Rees (mauritsvanrees) <m.van.rees@zestsoftware.nl>
Commit: plone/plone.locking@16f1321

Merge pull request #18 from plone/issue-3331-removing-lock-behavior

Add fallback plone_lock_info view

Files changed:
A news/3331.fix
A plone/locking/tests/test_views.py
M plone/locking/browser/locking.py
M plone/locking/configure.zcml
  • Loading branch information
mauritsvanrees committed Oct 8, 2021
1 parent 9bf7451 commit 2fb25fb
Showing 1 changed file with 22 additions and 34 deletions.
56 changes: 22 additions & 34 deletions last_commit.txt
Original file line number Diff line number Diff line change
@@ -1,50 +1,38 @@
Repository: plone.app.multilingual
Repository: plone.locking


Branch: refs/heads/5.6.x
Date: 2021-10-08T02:19:42+02:00
Author: mamico (mamico) <mauro.amico@gmail.com>
Commit: https://github.com/plone/plone.app.multilingual/commit/a143e2c953f6eeb0fe01f1e0b8db09d6e016f101
Branch: refs/heads/master
Date: 2021-10-08T16:51:24+02:00
Author: Érico Andrei (ericof) <ericof@gmail.com>
Commit: https://github.com/plone/plone.locking/commit/780f9b69316bf90891fd4ab8fc850f9d98969744

Disable CSRF protection during the setting of TG attribute. #375 backport
Register a fallback @@plone_lock_info view to allow objects without plone.locking behavior to be edited.

Files changed:
M src/plone/app/multilingual/manager.py
M src/plone/app/multilingual/subscriber.py
A news/3331.fix
A plone/locking/tests/test_views.py
M plone/locking/browser/locking.py
M plone/locking/configure.zcml

b"diff --git a/src/plone/app/multilingual/manager.py b/src/plone/app/multilingual/manager.py\nindex 8981e66b..0a3a2f21 100644\n--- a/src/plone/app/multilingual/manager.py\n+++ b/src/plone/app/multilingual/manager.py\n@@ -12,12 +12,15 @@\n from plone.app.multilingual.interfaces import NOTG\n from plone.app.multilingual.itg import addAttributeTG\n from plone.app.uuid.utils import uuidToObject\n+from plone.protect.interfaces import IDisableCSRFProtection\n from plone.uuid.handlers import addAttributeUUID\n from plone.uuid.interfaces import IUUID\n from Products.CMFCore.utils import getToolByName\n from Products.CMFPlone.interfaces import ILanguage\n from zope.component.hooks import getSite\n from zope.event import notify\n+from zope.globalrequest import getRequest\n+from zope.interface import alsoProvides\n from zope.interface import implementer\n \n \n@@ -43,7 +46,7 @@ def get_id(self, context):\n # We must ensure that this case can't happen, any object translatable\n # will have an UUID (in any case we can be at the portal factory!)\n except KeyError:\n- context._v_safe_write = True\n+ alsoProvides(getRequest(), IDisableCSRFProtection)\n addAttributeUUID(context, None)\n context.reindexObject(idxs=['UID'])\n context_id = IUUID(context)\n@@ -57,8 +60,9 @@ def get_tg(self, context):\n try:\n context_id = ITG(context)\n # We must ensure that this case can't happen, any object translatable\n- # will have an UUID (in any case we can be at the portal factory!)\n+ # will have an TG (in any case we can be at the portal factory!)\n except TypeError:\n+ alsoProvides(getRequest(), IDisableCSRFProtection)\n addAttributeTG(context, None)\n context.reindexObject(idxs=['TranslationGroup'])\n context_id = ITG(context)\ndiff --git a/src/plone/app/multilingual/subscriber.py b/src/plone/app/multilingual/subscriber.py\nindex 6069fb7b..42816ad6 100644\n--- a/src/plone/app/multilingual/subscriber.py\n+++ b/src/plone/app/multilingual/subscriber.py\n@@ -5,9 +5,11 @@\n from plone.app.multilingual.interfaces import ILanguageIndependentFolder\n from plone.app.multilingual.interfaces import IMutableTG\n from plone.app.multilingual.interfaces import IPloneAppMultilingualInstalled\n+from plone.app.multilingual.interfaces import ITG\n from plone.app.multilingual.interfaces import ITranslatable\n from plone.app.multilingual.interfaces import ITranslationManager\n from plone.app.multilingual.interfaces import LANGUAGE_INDEPENDENT\n+from plone.app.multilingual.itg import addAttributeTG\n from plone.dexterity.interfaces import IDexterityContent\n from plone.uuid.interfaces import IUUID\n from Products.CMFCore.interfaces import IFolderish\n@@ -116,6 +118,9 @@ def set_recursive_language(ob, language):\n \n elif ILanguage(ob).get_language() != language:\n ILanguage(ob).set_language(language)\n+ if ITG(ob, None) is None:\n+ addAttributeTG(ob, None)\n+ ob.reindexObject(idxs=['TranslationGroup'])\n ITranslationManager(ob).update()\n reindex_object(ob)\n \n"
b'diff --git a/news/3331.fix b/news/3331.fix\nnew file mode 100644\nindex 0000000..9efab5b\n--- /dev/null\n+++ b/news/3331.fix\n@@ -0,0 +1,2 @@\n+Register a fallback @@plone_lock_info view to allow objects without plone.locking behavior to be edited.\n+[ericof]\n\\ No newline at end of file\ndiff --git a/plone/locking/browser/locking.py b/plone/locking/browser/locking.py\nindex 7f4145e..6453bdc 100644\n--- a/plone/locking/browser/locking.py\n+++ b/plone/locking/browser/locking.py\n@@ -161,3 +161,23 @@ def _getNiceTimeDifference(self, baseTime):\n else:\n dateString = _(u"$d days and $h hours", mapping={\'d\': days, \'h\': hours})\n return dateString\n+\n+\n+class LockingInformationFallback(BrowserView):\n+ """Fallback view for Lock information.\n+\n+ This view exists to return sensible defaults if a content type does\n+ not have the plone.locking behavior active.\n+ """\n+\n+ def is_locked(self):\n+ return False\n+\n+ def is_locked_for_current_user(self):\n+ return False\n+\n+ def lock_is_stealable(self):\n+ return False\n+\n+ def lock_info(self):\n+ return None\ndiff --git a/plone/locking/configure.zcml b/plone/locking/configure.zcml\nindex c4890e2..9c8ed2c 100644\n--- a/plone/locking/configure.zcml\n+++ b/plone/locking/configure.zcml\n@@ -22,4 +22,12 @@\n allowed_attributes="is_locked is_locked_for_current_user lock_is_stealable lock_info"\n />\n \n+ <browser:page\n+ for="*"\n+ name="plone_lock_info"\n+ class=".browser.locking.LockingInformationFallback"\n+ permission="zope2.View"\n+ allowed_attributes="is_locked is_locked_for_current_user lock_is_stealable lock_info"\n+ />\n+\n </configure>\ndiff --git a/plone/locking/tests/test_views.py b/plone/locking/tests/test_views.py\nnew file mode 100644\nindex 0000000..412c3b0\n--- /dev/null\n+++ b/plone/locking/tests/test_views.py\n@@ -0,0 +1,44 @@\n+# -*- coding: utf-8 -*-\n+from plone.app.testing import setRoles\n+from plone.app.testing import TEST_USER_ID\n+from plone.locking.browser.locking import LockingInformation\n+from plone.locking.browser.locking import LockingInformationFallback\n+from plone.locking.testing import PLONE_LOCKING_INTEGRATION_TESTING\n+from plone.dexterity.interfaces import IDexterityFTI\n+from zope.component import queryUtility\n+\n+import unittest\n+\n+\n+class TestLockInfoViewWithoutLocking(unittest.TestCase):\n+\n+ layer = PLONE_LOCKING_INTEGRATION_TESTING\n+\n+ view = "@@plone_lock_info"\n+\n+ def setUp(self):\n+ self.app = self.layer["app"]\n+ self.portal = self.layer["portal"]\n+\n+ setRoles(self.portal, TEST_USER_ID, ["Manager", "Site Administrator"])\n+\n+ self.portal.invokeFactory("News Item", id="news1", title="News Item 1")\n+ self.news = self.portal["news1"]\n+\n+ # Remove plone.locking from Document content type\n+ fti = queryUtility(IDexterityFTI, name="Document")\n+ behavior_list = [a for a in fti.behaviors if a != "plone.locking"]\n+ fti.behaviors = tuple(behavior_list)\n+\n+ self.portal.invokeFactory("Document", id="doc1", title="Document 1")\n+ self.doc = self.portal["doc1"]\n+\n+ def test_browser_view_available_for_content_with_locking_behavior(self):\n+ content = self.news\n+ view = content.restrictedTraverse(self.view)\n+ self.assertIsInstance(view, LockingInformation)\n+\n+ def test_browser_view_available_for_content_without_locking_behavior(self):\n+ content = self.doc\n+ view = content.restrictedTraverse(self.view)\n+ self.assertIsInstance(view, LockingInformationFallback)\n'

Repository: plone.app.multilingual
Repository: plone.locking


Branch: refs/heads/5.6.x
Date: 2021-10-08T02:22:37+02:00
Author: mamico (mamico) <mauro.amico@gmail.com>
Commit: https://github.com/plone/plone.app.multilingual/commit/0aff30fe47fb95da3a0f2a56c35051494db33f25

changelog

Files changed:
A news/393.bugfix

b'diff --git a/news/393.bugfix b/news/393.bugfix\nnew file mode 100644\nindex 00000000..ebfb25ba\n--- /dev/null\n+++ b/news/393.bugfix\n@@ -0,0 +1 @@\n+Disable CSRF protection during the setting of TG attribute. #375 backport [mamico]\n'

Repository: plone.app.multilingual


Branch: refs/heads/5.6.x
Date: 2021-10-08T08:53:07+02:00
Branch: refs/heads/master
Date: 2021-10-08T23:33:43+02:00
Author: Maurits van Rees (mauritsvanrees) <m.van.rees@zestsoftware.nl>
Commit: https://github.com/plone/plone.app.multilingual/commit/ebd2a9903119745de905f6ff47f0dad8ff57fd13
Commit: https://github.com/plone/plone.locking/commit/16f132198012601b9b433f346c0a81b19a26be5e

Merge pull request #393 from plone/mamico/safewrite-5.6
Merge pull request #18 from plone/issue-3331-removing-lock-behavior

Disable CSRF protection during the setting of TG attribute. #375 backport
Add fallback plone_lock_info view

Files changed:
A news/393.bugfix
M src/plone/app/multilingual/manager.py
M src/plone/app/multilingual/subscriber.py
A news/3331.fix
A plone/locking/tests/test_views.py
M plone/locking/browser/locking.py
M plone/locking/configure.zcml

b"diff --git a/news/393.bugfix b/news/393.bugfix\nnew file mode 100644\nindex 00000000..ebfb25ba\n--- /dev/null\n+++ b/news/393.bugfix\n@@ -0,0 +1 @@\n+Disable CSRF protection during the setting of TG attribute. #375 backport [mamico]\ndiff --git a/src/plone/app/multilingual/manager.py b/src/plone/app/multilingual/manager.py\nindex 8981e66b..0a3a2f21 100644\n--- a/src/plone/app/multilingual/manager.py\n+++ b/src/plone/app/multilingual/manager.py\n@@ -12,12 +12,15 @@\n from plone.app.multilingual.interfaces import NOTG\n from plone.app.multilingual.itg import addAttributeTG\n from plone.app.uuid.utils import uuidToObject\n+from plone.protect.interfaces import IDisableCSRFProtection\n from plone.uuid.handlers import addAttributeUUID\n from plone.uuid.interfaces import IUUID\n from Products.CMFCore.utils import getToolByName\n from Products.CMFPlone.interfaces import ILanguage\n from zope.component.hooks import getSite\n from zope.event import notify\n+from zope.globalrequest import getRequest\n+from zope.interface import alsoProvides\n from zope.interface import implementer\n \n \n@@ -43,7 +46,7 @@ def get_id(self, context):\n # We must ensure that this case can't happen, any object translatable\n # will have an UUID (in any case we can be at the portal factory!)\n except KeyError:\n- context._v_safe_write = True\n+ alsoProvides(getRequest(), IDisableCSRFProtection)\n addAttributeUUID(context, None)\n context.reindexObject(idxs=['UID'])\n context_id = IUUID(context)\n@@ -57,8 +60,9 @@ def get_tg(self, context):\n try:\n context_id = ITG(context)\n # We must ensure that this case can't happen, any object translatable\n- # will have an UUID (in any case we can be at the portal factory!)\n+ # will have an TG (in any case we can be at the portal factory!)\n except TypeError:\n+ alsoProvides(getRequest(), IDisableCSRFProtection)\n addAttributeTG(context, None)\n context.reindexObject(idxs=['TranslationGroup'])\n context_id = ITG(context)\ndiff --git a/src/plone/app/multilingual/subscriber.py b/src/plone/app/multilingual/subscriber.py\nindex 6069fb7b..42816ad6 100644\n--- a/src/plone/app/multilingual/subscriber.py\n+++ b/src/plone/app/multilingual/subscriber.py\n@@ -5,9 +5,11 @@\n from plone.app.multilingual.interfaces import ILanguageIndependentFolder\n from plone.app.multilingual.interfaces import IMutableTG\n from plone.app.multilingual.interfaces import IPloneAppMultilingualInstalled\n+from plone.app.multilingual.interfaces import ITG\n from plone.app.multilingual.interfaces import ITranslatable\n from plone.app.multilingual.interfaces import ITranslationManager\n from plone.app.multilingual.interfaces import LANGUAGE_INDEPENDENT\n+from plone.app.multilingual.itg import addAttributeTG\n from plone.dexterity.interfaces import IDexterityContent\n from plone.uuid.interfaces import IUUID\n from Products.CMFCore.interfaces import IFolderish\n@@ -116,6 +118,9 @@ def set_recursive_language(ob, language):\n \n elif ILanguage(ob).get_language() != language:\n ILanguage(ob).set_language(language)\n+ if ITG(ob, None) is None:\n+ addAttributeTG(ob, None)\n+ ob.reindexObject(idxs=['TranslationGroup'])\n ITranslationManager(ob).update()\n reindex_object(ob)\n \n"
b'diff --git a/news/3331.fix b/news/3331.fix\nnew file mode 100644\nindex 0000000..9efab5b\n--- /dev/null\n+++ b/news/3331.fix\n@@ -0,0 +1,2 @@\n+Register a fallback @@plone_lock_info view to allow objects without plone.locking behavior to be edited.\n+[ericof]\n\\ No newline at end of file\ndiff --git a/plone/locking/browser/locking.py b/plone/locking/browser/locking.py\nindex 7f4145e..6453bdc 100644\n--- a/plone/locking/browser/locking.py\n+++ b/plone/locking/browser/locking.py\n@@ -161,3 +161,23 @@ def _getNiceTimeDifference(self, baseTime):\n else:\n dateString = _(u"$d days and $h hours", mapping={\'d\': days, \'h\': hours})\n return dateString\n+\n+\n+class LockingInformationFallback(BrowserView):\n+ """Fallback view for Lock information.\n+\n+ This view exists to return sensible defaults if a content type does\n+ not have the plone.locking behavior active.\n+ """\n+\n+ def is_locked(self):\n+ return False\n+\n+ def is_locked_for_current_user(self):\n+ return False\n+\n+ def lock_is_stealable(self):\n+ return False\n+\n+ def lock_info(self):\n+ return None\ndiff --git a/plone/locking/configure.zcml b/plone/locking/configure.zcml\nindex c4890e2..9c8ed2c 100644\n--- a/plone/locking/configure.zcml\n+++ b/plone/locking/configure.zcml\n@@ -22,4 +22,12 @@\n allowed_attributes="is_locked is_locked_for_current_user lock_is_stealable lock_info"\n />\n \n+ <browser:page\n+ for="*"\n+ name="plone_lock_info"\n+ class=".browser.locking.LockingInformationFallback"\n+ permission="zope2.View"\n+ allowed_attributes="is_locked is_locked_for_current_user lock_is_stealable lock_info"\n+ />\n+\n </configure>\ndiff --git a/plone/locking/tests/test_views.py b/plone/locking/tests/test_views.py\nnew file mode 100644\nindex 0000000..412c3b0\n--- /dev/null\n+++ b/plone/locking/tests/test_views.py\n@@ -0,0 +1,44 @@\n+# -*- coding: utf-8 -*-\n+from plone.app.testing import setRoles\n+from plone.app.testing import TEST_USER_ID\n+from plone.locking.browser.locking import LockingInformation\n+from plone.locking.browser.locking import LockingInformationFallback\n+from plone.locking.testing import PLONE_LOCKING_INTEGRATION_TESTING\n+from plone.dexterity.interfaces import IDexterityFTI\n+from zope.component import queryUtility\n+\n+import unittest\n+\n+\n+class TestLockInfoViewWithoutLocking(unittest.TestCase):\n+\n+ layer = PLONE_LOCKING_INTEGRATION_TESTING\n+\n+ view = "@@plone_lock_info"\n+\n+ def setUp(self):\n+ self.app = self.layer["app"]\n+ self.portal = self.layer["portal"]\n+\n+ setRoles(self.portal, TEST_USER_ID, ["Manager", "Site Administrator"])\n+\n+ self.portal.invokeFactory("News Item", id="news1", title="News Item 1")\n+ self.news = self.portal["news1"]\n+\n+ # Remove plone.locking from Document content type\n+ fti = queryUtility(IDexterityFTI, name="Document")\n+ behavior_list = [a for a in fti.behaviors if a != "plone.locking"]\n+ fti.behaviors = tuple(behavior_list)\n+\n+ self.portal.invokeFactory("Document", id="doc1", title="Document 1")\n+ self.doc = self.portal["doc1"]\n+\n+ def test_browser_view_available_for_content_with_locking_behavior(self):\n+ content = self.news\n+ view = content.restrictedTraverse(self.view)\n+ self.assertIsInstance(view, LockingInformation)\n+\n+ def test_browser_view_available_for_content_without_locking_behavior(self):\n+ content = self.doc\n+ view = content.restrictedTraverse(self.view)\n+ self.assertIsInstance(view, LockingInformationFallback)\n'

0 comments on commit 2fb25fb

Please sign in to comment.