Merge pull request #115 from plone/apply-hotfix-20161129-master
Apply hotfix 20161129 [master]
This commit is contained in:
commit
31e7fab26c
@ -14,7 +14,8 @@ New features:
|
|||||||
|
|
||||||
Bug fixes:
|
Bug fixes:
|
||||||
|
|
||||||
- *add item here*
|
- Make comment on private content not publicly available in search results.
|
||||||
|
Part of PloneHotfix20161129. [vangheem, maurits]
|
||||||
|
|
||||||
|
|
||||||
2.4.19 (2017-01-02)
|
2.4.19 (2017-01-02)
|
||||||
|
@ -125,7 +125,7 @@ class DiscussionSettingsControlPanel(controlpanel.ControlPanelFormWrapper):
|
|||||||
output.append('globally_enabled')
|
output.append('globally_enabled')
|
||||||
|
|
||||||
# Comment moderation
|
# Comment moderation
|
||||||
one_state_worklow_disabled = 'one_state_workflow' not in workflow_chain
|
one_state_worklow_disabled = 'comment_one_state_workflow' not in workflow_chain
|
||||||
comment_review_workflow_disabled = \
|
comment_review_workflow_disabled = \
|
||||||
'comment_review_workflow' not in workflow_chain
|
'comment_review_workflow' not in workflow_chain
|
||||||
if one_state_worklow_disabled and comment_review_workflow_disabled:
|
if one_state_worklow_disabled and comment_review_workflow_disabled:
|
||||||
@ -174,7 +174,7 @@ class DiscussionSettingsControlPanel(controlpanel.ControlPanelFormWrapper):
|
|||||||
"""
|
"""
|
||||||
wftool = getToolByName(self.context, 'portal_workflow', None)
|
wftool = getToolByName(self.context, 'portal_workflow', None)
|
||||||
workflow_chain = wftool.getChainForPortalType('Discussion Item')
|
workflow_chain = wftool.getChainForPortalType('Discussion Item')
|
||||||
one_state_workflow_enabled = 'one_state_workflow' in workflow_chain
|
one_state_workflow_enabled = 'comment_one_state_workflow' in workflow_chain
|
||||||
comment_review_workflow_enabled = \
|
comment_review_workflow_enabled = \
|
||||||
'comment_review_workflow' in workflow_chain
|
'comment_review_workflow' in workflow_chain
|
||||||
if one_state_workflow_enabled or comment_review_workflow_enabled:
|
if one_state_workflow_enabled or comment_review_workflow_enabled:
|
||||||
@ -199,7 +199,7 @@ def notify_configuration_changed(event):
|
|||||||
else:
|
else:
|
||||||
# Disable moderation workflow
|
# Disable moderation workflow
|
||||||
wftool.setChainForPortalTypes(('Discussion Item',),
|
wftool.setChainForPortalTypes(('Discussion Item',),
|
||||||
'one_state_workflow')
|
'comment_one_state_workflow')
|
||||||
|
|
||||||
if IConfigurationChangedEvent.providedBy(event):
|
if IConfigurationChangedEvent.providedBy(event):
|
||||||
# Types control panel setting changed
|
# Types control panel setting changed
|
||||||
@ -209,7 +209,7 @@ def notify_configuration_changed(event):
|
|||||||
workflow_chain = wftool.getChainForPortalType('Discussion Item')
|
workflow_chain = wftool.getChainForPortalType('Discussion Item')
|
||||||
if workflow_chain:
|
if workflow_chain:
|
||||||
workflow = workflow_chain[0]
|
workflow = workflow_chain[0]
|
||||||
if workflow == 'one_state_workflow':
|
if workflow == 'comment_one_state_workflow':
|
||||||
settings.moderation_enabled = False
|
settings.moderation_enabled = False
|
||||||
elif workflow == 'comment_review_workflow':
|
elif workflow == 'comment_review_workflow':
|
||||||
settings.moderation_enabled = True
|
settings.moderation_enabled = True
|
||||||
|
@ -40,26 +40,7 @@
|
|||||||
provides="Products.GenericSetup.interfaces.EXTENSION"
|
provides="Products.GenericSetup.interfaces.EXTENSION"
|
||||||
for="Products.CMFPlone.interfaces.IPloneSiteRoot"
|
for="Products.CMFPlone.interfaces.IPloneSiteRoot"
|
||||||
/>
|
/>
|
||||||
|
<!-- For upgrade steps see upgrades.zcml. -->
|
||||||
<genericsetup:upgradeStep
|
|
||||||
title="edit comments and delete own comments"
|
|
||||||
description="reload registry config to enable new fields edit_comment_enabled and delete_own_comment_enabled"
|
|
||||||
source="100"
|
|
||||||
destination="101"
|
|
||||||
handler=".upgrades.update_registry"
|
|
||||||
sortkey="1"
|
|
||||||
profile="plone.app.discussion:default"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<genericsetup:upgradeStep
|
|
||||||
title="delete comments and delete own comments"
|
|
||||||
description="reload rolemap config to enable new permissions 'Delete comments' and 'Delete own comments'"
|
|
||||||
source="101"
|
|
||||||
destination="102"
|
|
||||||
handler=".upgrades.update_rolemap"
|
|
||||||
sortkey="1"
|
|
||||||
profile="plone.app.discussion:default"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- Comments -->
|
<!-- Comments -->
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<metadata>
|
<metadata>
|
||||||
<version>102</version>
|
<version>1000</version>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>profile-plone.app.registry:default</dependency>
|
<dependency>profile-plone.app.registry:default</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<object name="portal_workflow" meta_type="Plone Workflow Tool">
|
<object name="portal_workflow" meta_type="Plone Workflow Tool">
|
||||||
<object name="comment_review_workflow" meta_type="Workflow"/>
|
<object name="comment_review_workflow" meta_type="Workflow"/>
|
||||||
|
<object name="comment_one_state_workflow" meta_type="Workflow"/>
|
||||||
<bindings>
|
<bindings>
|
||||||
<type type_id="Discussion Item">
|
<type type_id="Discussion Item">
|
||||||
<bound-workflow workflow_id="one_state_workflow" />
|
<bound-workflow workflow_id="comment_one_state_workflow" />
|
||||||
</type>
|
</type>
|
||||||
</bindings>
|
</bindings>
|
||||||
</object>
|
</object>
|
||||||
|
@ -0,0 +1,80 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<dc-workflow workflow_id="comment_one_state_workflow" title="Single State Workflow" description="- Essentially a workflow with no transitions, but has a Published state, so portlets and applications that expect that state will continue to work." state_variable="review_state" initial_state="published" manager_bypass="False" >
|
||||||
|
<permission>Access contents information</permission>
|
||||||
|
<permission>Change portal events</permission>
|
||||||
|
<permission>Modify portal content</permission>
|
||||||
|
<permission>View</permission>
|
||||||
|
<state state_id="published" title="Published" >
|
||||||
|
<description>Visible to everyone, editable by the owner.</description>
|
||||||
|
|
||||||
|
<permission-map name="Access contents information" acquired="False">
|
||||||
|
<permission-role>Anonymous</permission-role>
|
||||||
|
</permission-map>
|
||||||
|
<permission-map name="Change portal events" acquired="False">
|
||||||
|
<permission-role>Manager</permission-role>
|
||||||
|
<permission-role>Owner</permission-role>
|
||||||
|
<permission-role>Editor</permission-role>
|
||||||
|
<permission-role>Site Administrator</permission-role>
|
||||||
|
</permission-map>
|
||||||
|
<permission-map name="Modify portal content" acquired="False">
|
||||||
|
<permission-role>Manager</permission-role>
|
||||||
|
<permission-role>Owner</permission-role>
|
||||||
|
<permission-role>Editor</permission-role>
|
||||||
|
<permission-role>Site Administrator</permission-role>
|
||||||
|
</permission-map>
|
||||||
|
<permission-map name="View" acquired="True">
|
||||||
|
</permission-map>
|
||||||
|
|
||||||
|
|
||||||
|
</state>
|
||||||
|
|
||||||
|
|
||||||
|
<variable variable_id="action" for_catalog="False" for_status="True" update_always="True" >
|
||||||
|
<description>Previous transition</description>
|
||||||
|
<default>
|
||||||
|
|
||||||
|
<expression>transition/getId|nothing</expression>
|
||||||
|
</default>
|
||||||
|
<guard >
|
||||||
|
</guard>
|
||||||
|
</variable>
|
||||||
|
<variable variable_id="actor" for_catalog="False" for_status="True" update_always="True" >
|
||||||
|
<description>The ID of the user who performed the previous transition</description>
|
||||||
|
<default>
|
||||||
|
|
||||||
|
<expression>user/getId</expression>
|
||||||
|
</default>
|
||||||
|
<guard >
|
||||||
|
</guard>
|
||||||
|
</variable>
|
||||||
|
<variable variable_id="comments" for_catalog="False" for_status="True" update_always="True" >
|
||||||
|
<description>Comment about the last transition</description>
|
||||||
|
<default>
|
||||||
|
|
||||||
|
<expression>python:state_change.kwargs.get('comment', '')</expression>
|
||||||
|
</default>
|
||||||
|
<guard >
|
||||||
|
</guard>
|
||||||
|
</variable>
|
||||||
|
<variable variable_id="review_history" for_catalog="False" for_status="False" update_always="False" >
|
||||||
|
<description>Provides access to workflow history</description>
|
||||||
|
<default>
|
||||||
|
|
||||||
|
<expression>state_change/getHistory</expression>
|
||||||
|
</default>
|
||||||
|
<guard >
|
||||||
|
<guard-permission>Request review</guard-permission>
|
||||||
|
<guard-permission>Review portal content</guard-permission>
|
||||||
|
</guard>
|
||||||
|
</variable>
|
||||||
|
<variable variable_id="time" for_catalog="False" for_status="True" update_always="True" >
|
||||||
|
<description>When the previous transition was performed</description>
|
||||||
|
<default>
|
||||||
|
|
||||||
|
<expression>state_change/getDateTime</expression>
|
||||||
|
</default>
|
||||||
|
<guard >
|
||||||
|
</guard>
|
||||||
|
</variable>
|
||||||
|
|
||||||
|
</dc-workflow>
|
@ -41,14 +41,12 @@
|
|||||||
<description i18n:translate="">
|
<description i18n:translate="">
|
||||||
Visible to everyone, non-editable.
|
Visible to everyone, non-editable.
|
||||||
</description>
|
</description>
|
||||||
<permission-map name="Access contents information" acquired="False">
|
<permission-map name="Access contents information" acquired="True">
|
||||||
<permission-role>Anonymous</permission-role>
|
|
||||||
</permission-map>
|
</permission-map>
|
||||||
<permission-map name="Modify portal content" acquired="False">
|
<permission-map name="Modify portal content" acquired="False">
|
||||||
<permission-role>Manager</permission-role>
|
<permission-role>Manager</permission-role>
|
||||||
</permission-map>
|
</permission-map>
|
||||||
<permission-map name="View" acquired="False">
|
<permission-map name="View" acquired="True">
|
||||||
<permission-role>Anonymous</permission-role>
|
|
||||||
</permission-map>
|
</permission-map>
|
||||||
<permission-map name="Reply to item" acquired="True">
|
<permission-map name="Reply to item" acquired="True">
|
||||||
</permission-map>
|
</permission-map>
|
||||||
|
@ -59,6 +59,10 @@ class ConversationCatalogTest(unittest.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.portal = self.layer['portal']
|
self.portal = self.layer['portal']
|
||||||
setRoles(self.portal, TEST_USER_ID, ['Manager'])
|
setRoles(self.portal, TEST_USER_ID, ['Manager'])
|
||||||
|
|
||||||
|
workflow = self.portal.portal_workflow
|
||||||
|
workflow.doActionFor(self.portal.doc1, 'publish')
|
||||||
|
|
||||||
self.catalog = getToolByName(self.portal, 'portal_catalog')
|
self.catalog = getToolByName(self.portal, 'portal_catalog')
|
||||||
conversation = IConversation(self.portal.doc1)
|
conversation = IConversation(self.portal.doc1)
|
||||||
comment1 = createObject('plone.Comment')
|
comment1 = createObject('plone.Comment')
|
||||||
|
@ -27,6 +27,9 @@ class CommentTest(unittest.TestCase):
|
|||||||
self.portal = self.layer['portal']
|
self.portal = self.layer['portal']
|
||||||
self.request = self.layer['request']
|
self.request = self.layer['request']
|
||||||
|
|
||||||
|
workflow = self.portal.portal_workflow
|
||||||
|
workflow.doActionFor(self.portal.doc1, 'publish')
|
||||||
|
|
||||||
setRoles(self.portal, TEST_USER_ID, ['Manager'])
|
setRoles(self.portal, TEST_USER_ID, ['Manager'])
|
||||||
self.catalog = getToolByName(self.portal, 'portal_catalog')
|
self.catalog = getToolByName(self.portal, 'portal_catalog')
|
||||||
self.document_brain = self.catalog.searchResults(
|
self.document_brain = self.catalog.searchResults(
|
||||||
@ -351,6 +354,9 @@ class RepliesTest(unittest.TestCase):
|
|||||||
self.portal = self.layer['portal']
|
self.portal = self.layer['portal']
|
||||||
setRoles(self.portal, TEST_USER_ID, ['Manager'])
|
setRoles(self.portal, TEST_USER_ID, ['Manager'])
|
||||||
|
|
||||||
|
workflow = self.portal.portal_workflow
|
||||||
|
workflow.doActionFor(self.portal.doc1, 'publish')
|
||||||
|
|
||||||
def test_add_comment(self):
|
def test_add_comment(self):
|
||||||
# Add comments to a CommentReplies adapter
|
# Add comments to a CommentReplies adapter
|
||||||
|
|
||||||
|
@ -458,7 +458,7 @@ class TestCommentsViewlet(unittest.TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.workflowTool = getToolByName(self.portal, 'portal_workflow')
|
self.workflowTool = getToolByName(self.portal, 'portal_workflow')
|
||||||
self.workflowTool.setDefaultChain('one_state_workflow')
|
self.workflowTool.setDefaultChain('comment_one_state_workflow')
|
||||||
|
|
||||||
self.membershipTool = getToolByName(self.folder, 'portal_membership')
|
self.membershipTool = getToolByName(self.folder, 'portal_membership')
|
||||||
self.memberdata = self.portal.portal_memberdata
|
self.memberdata = self.portal.portal_memberdata
|
||||||
|
@ -163,9 +163,9 @@ class ConfigurationChangedSubscriberTest(unittest.TestCase):
|
|||||||
the 'comment_moderation' setting in the discussion control panel
|
the 'comment_moderation' setting in the discussion control panel
|
||||||
changes.
|
changes.
|
||||||
"""
|
"""
|
||||||
# By default the one_state_workflow without moderation is enabled
|
# By default the comment_one_state_workflow without moderation is enabled
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
('one_state_workflow',),
|
('comment_one_state_workflow',),
|
||||||
self.portal.portal_workflow.getChainForPortalType(
|
self.portal.portal_workflow.getChainForPortalType(
|
||||||
'Discussion Item'
|
'Discussion Item'
|
||||||
)
|
)
|
||||||
@ -185,7 +185,7 @@ class ConfigurationChangedSubscriberTest(unittest.TestCase):
|
|||||||
# And back
|
# And back
|
||||||
self.settings.moderation_enabled = False
|
self.settings.moderation_enabled = False
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
('one_state_workflow',),
|
('comment_one_state_workflow',),
|
||||||
self.portal.portal_workflow.getChainForPortalType(
|
self.portal.portal_workflow.getChainForPortalType(
|
||||||
'Discussion Item'
|
'Discussion Item'
|
||||||
)
|
)
|
||||||
@ -211,7 +211,7 @@ class ConfigurationChangedSubscriberTest(unittest.TestCase):
|
|||||||
# Enable the 'comment_review_workflow' with moderation enabled
|
# Enable the 'comment_review_workflow' with moderation enabled
|
||||||
self.portal.portal_workflow.setChainForPortalTypes(
|
self.portal.portal_workflow.setChainForPortalTypes(
|
||||||
('Discussion Item',),
|
('Discussion Item',),
|
||||||
('one_state_workflow',)
|
('comment_one_state_workflow',)
|
||||||
)
|
)
|
||||||
self.settings.moderation_enabled = True
|
self.settings.moderation_enabled = True
|
||||||
|
|
||||||
|
@ -50,6 +50,9 @@ class ConversationTest(unittest.TestCase):
|
|||||||
settings = registry.forInterface(IDiscussionSettings)
|
settings = registry.forInterface(IDiscussionSettings)
|
||||||
settings.globally_enabled = True
|
settings.globally_enabled = True
|
||||||
|
|
||||||
|
workflow = self.portal.portal_workflow
|
||||||
|
workflow.doActionFor(self.portal.doc1, 'publish')
|
||||||
|
|
||||||
def test_add_comment(self):
|
def test_add_comment(self):
|
||||||
# Create a conversation. In this case we doesn't assign it to an
|
# Create a conversation. In this case we doesn't assign it to an
|
||||||
# object, as we just want to check the Conversation object API.
|
# object, as we just want to check the Conversation object API.
|
||||||
@ -744,6 +747,9 @@ class RepliesTest(unittest.TestCase):
|
|||||||
self.portal = self.layer['portal']
|
self.portal = self.layer['portal']
|
||||||
setRoles(self.portal, TEST_USER_ID, ['Manager'])
|
setRoles(self.portal, TEST_USER_ID, ['Manager'])
|
||||||
|
|
||||||
|
workflow = self.portal.portal_workflow
|
||||||
|
workflow.doActionFor(self.portal.doc1, 'publish')
|
||||||
|
|
||||||
def test_add_comment(self):
|
def test_add_comment(self):
|
||||||
# Add comments to a ConversationReplies adapter
|
# Add comments to a ConversationReplies adapter
|
||||||
|
|
||||||
|
@ -35,6 +35,9 @@ class ConversationIndexersTest(unittest.TestCase):
|
|||||||
self.portal = self.layer['portal']
|
self.portal = self.layer['portal']
|
||||||
setRoles(self.portal, TEST_USER_ID, ['Manager'])
|
setRoles(self.portal, TEST_USER_ID, ['Manager'])
|
||||||
|
|
||||||
|
workflow = self.portal.portal_workflow
|
||||||
|
workflow.doActionFor(self.portal.doc1, 'publish')
|
||||||
|
|
||||||
# Create a conversation.
|
# Create a conversation.
|
||||||
conversation = IConversation(self.portal.doc1)
|
conversation = IConversation(self.portal.doc1)
|
||||||
|
|
||||||
|
@ -46,9 +46,9 @@ class ModerationViewTest(unittest.TestCase):
|
|||||||
# If workflow is not set, enabled must return False
|
# If workflow is not set, enabled must return False
|
||||||
self.wf_tool.setChainForPortalTypes(('Discussion Item',), ())
|
self.wf_tool.setChainForPortalTypes(('Discussion Item',), ())
|
||||||
self.assertEqual(self.view.moderation_enabled(), False)
|
self.assertEqual(self.view.moderation_enabled(), False)
|
||||||
# The one_state_workflow does not have a 'pending' state
|
# The comment_one_state_workflow does not have a 'pending' state
|
||||||
self.wf_tool.setChainForPortalTypes(('Discussion Item',),
|
self.wf_tool.setChainForPortalTypes(('Discussion Item',),
|
||||||
('one_state_workflow,'))
|
('comment_one_state_workflow,'))
|
||||||
self.assertEqual(self.view.moderation_enabled(), False)
|
self.assertEqual(self.view.moderation_enabled(), False)
|
||||||
# The comment_review_workflow does have a 'pending' state
|
# The comment_review_workflow does have a 'pending' state
|
||||||
self.wf_tool.setChainForPortalTypes(('Discussion Item',),
|
self.wf_tool.setChainForPortalTypes(('Discussion Item',),
|
||||||
|
@ -9,6 +9,7 @@ from plone.app.testing import login
|
|||||||
from plone.app.testing import logout
|
from plone.app.testing import logout
|
||||||
from plone.app.testing import setRoles
|
from plone.app.testing import setRoles
|
||||||
from plone.app.testing import TEST_USER_ID
|
from plone.app.testing import TEST_USER_ID
|
||||||
|
from plone.app.testing import TEST_USER_NAME
|
||||||
from Products.CMFCore.permissions import View
|
from Products.CMFCore.permissions import View
|
||||||
from Products.CMFCore.utils import _checkPermission as checkPerm
|
from Products.CMFCore.utils import _checkPermission as checkPerm
|
||||||
from zope.component import createObject
|
from zope.component import createObject
|
||||||
@ -35,7 +36,7 @@ class WorkflowSetupTest(unittest.TestCase):
|
|||||||
def test_workflows_installed(self):
|
def test_workflows_installed(self):
|
||||||
"""Make sure both comment workflows have been installed properly.
|
"""Make sure both comment workflows have been installed properly.
|
||||||
"""
|
"""
|
||||||
self.assertTrue('one_state_workflow' in
|
self.assertTrue('comment_one_state_workflow' in
|
||||||
self.portal.portal_workflow.objectIds())
|
self.portal.portal_workflow.objectIds())
|
||||||
self.assertTrue('comment_review_workflow' in
|
self.assertTrue('comment_review_workflow' in
|
||||||
self.portal.portal_workflow.objectIds())
|
self.portal.portal_workflow.objectIds())
|
||||||
@ -44,7 +45,7 @@ class WorkflowSetupTest(unittest.TestCase):
|
|||||||
"""Make sure one_state_workflow is the default workflow.
|
"""Make sure one_state_workflow is the default workflow.
|
||||||
"""
|
"""
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
('one_state_workflow',),
|
('comment_one_state_workflow',),
|
||||||
self.portal.portal_workflow.getChainForPortalType(
|
self.portal.portal_workflow.getChainForPortalType(
|
||||||
'Discussion Item'
|
'Discussion Item'
|
||||||
)
|
)
|
||||||
@ -102,7 +103,7 @@ class PermissionsSetupTest(unittest.TestCase):
|
|||||||
|
|
||||||
|
|
||||||
class CommentOneStateWorkflowTest(unittest.TestCase):
|
class CommentOneStateWorkflowTest(unittest.TestCase):
|
||||||
"""Test the one_state_workflow that ships with plone.app.discussion.
|
"""Test the comment_one_state_workflow that ships with plone.app.discussion.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING
|
layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING
|
||||||
@ -114,8 +115,6 @@ class CommentOneStateWorkflowTest(unittest.TestCase):
|
|||||||
self.folder = self.portal['test-folder']
|
self.folder = self.portal['test-folder']
|
||||||
self.catalog = self.portal.portal_catalog
|
self.catalog = self.portal.portal_catalog
|
||||||
self.workflow = self.portal.portal_workflow
|
self.workflow = self.portal.portal_workflow
|
||||||
self.workflow.setChainForPortalTypes(['Document'],
|
|
||||||
'one_state_workflow')
|
|
||||||
self.folder.invokeFactory('Document', 'doc1')
|
self.folder.invokeFactory('Document', 'doc1')
|
||||||
self.doc = self.folder.doc1
|
self.doc = self.folder.doc1
|
||||||
|
|
||||||
@ -137,10 +136,10 @@ class CommentOneStateWorkflowTest(unittest.TestCase):
|
|||||||
self.portal.acl_users._doAddUser('reader', 'secret', ['Reader'], [])
|
self.portal.acl_users._doAddUser('reader', 'secret', ['Reader'], [])
|
||||||
|
|
||||||
def test_initial_workflow_state(self):
|
def test_initial_workflow_state(self):
|
||||||
"""Make sure the initial workflow state of a comment is 'published'.
|
"""Make sure the initial workflow state of a comment is 'private'.
|
||||||
"""
|
"""
|
||||||
self.assertEqual(self.workflow.getInfoFor(self.doc, 'review_state'),
|
self.assertEqual(self.workflow.getInfoFor(self.doc, 'review_state'),
|
||||||
'published')
|
'private')
|
||||||
|
|
||||||
def test_view_comments(self):
|
def test_view_comments(self):
|
||||||
"""Make sure published comments can be viewed by everyone.
|
"""Make sure published comments can be viewed by everyone.
|
||||||
@ -149,6 +148,10 @@ class CommentOneStateWorkflowTest(unittest.TestCase):
|
|||||||
# self.login(default_user)
|
# self.login(default_user)
|
||||||
# self.assertTrue(checkPerm(View, self.doc))
|
# self.assertTrue(checkPerm(View, self.doc))
|
||||||
# Member is allowed
|
# Member is allowed
|
||||||
|
login(self.portal, TEST_USER_NAME)
|
||||||
|
workflow = self.portal.portal_workflow
|
||||||
|
workflow.doActionFor(self.doc, 'publish')
|
||||||
|
|
||||||
login(self.portal, 'member')
|
login(self.portal, 'member')
|
||||||
self.assertTrue(checkPerm(View, self.comment))
|
self.assertTrue(checkPerm(View, self.comment))
|
||||||
# Reviewer is allowed
|
# Reviewer is allowed
|
||||||
@ -164,6 +167,30 @@ class CommentOneStateWorkflowTest(unittest.TestCase):
|
|||||||
login(self.portal, 'reader')
|
login(self.portal, 'reader')
|
||||||
self.assertTrue(checkPerm(View, self.comment))
|
self.assertTrue(checkPerm(View, self.comment))
|
||||||
|
|
||||||
|
def test_comment_on_private_content_not_visible_to_world(self):
|
||||||
|
logout()
|
||||||
|
self.assertFalse(checkPerm(View, self.comment))
|
||||||
|
|
||||||
|
def test_migration(self):
|
||||||
|
from plone.app.discussion.upgrades import upgrade_comment_workflows
|
||||||
|
# Fake permission according to earlier one_comment_workflow.
|
||||||
|
self.comment._View_Permission = ('Anonymous',)
|
||||||
|
# Anonymous can see the comment.
|
||||||
|
logout()
|
||||||
|
self.assertTrue(checkPerm(View, self.comment))
|
||||||
|
# Run the upgrade.
|
||||||
|
login(self.portal, TEST_USER_NAME)
|
||||||
|
upgrade_comment_workflows(self.portal.portal_setup)
|
||||||
|
# The workflow chain is still what we want.
|
||||||
|
self.assertEqual(
|
||||||
|
self.portal.portal_workflow.getChainFor('Discussion Item'),
|
||||||
|
('comment_one_state_workflow',))
|
||||||
|
# A Manager can still see the comment.
|
||||||
|
self.assertTrue(checkPerm(View, self.comment))
|
||||||
|
# Anonymous cannot see the comment.
|
||||||
|
logout()
|
||||||
|
self.assertFalse(checkPerm(View, self.comment))
|
||||||
|
|
||||||
|
|
||||||
class CommentReviewWorkflowTest(unittest.TestCase):
|
class CommentReviewWorkflowTest(unittest.TestCase):
|
||||||
"""Test the comment_review_workflow that ships with plone.app.discussion.
|
"""Test the comment_review_workflow that ships with plone.app.discussion.
|
||||||
@ -269,3 +296,35 @@ class CommentReviewWorkflowTest(unittest.TestCase):
|
|||||||
'review_state'
|
'review_state'
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_publish_comment_on_private_content_not_visible_to_world(self):
|
||||||
|
logout()
|
||||||
|
self.assertFalse(checkPerm(View, self.comment))
|
||||||
|
|
||||||
|
# publish comment and check again
|
||||||
|
login(self.portal, TEST_USER_NAME)
|
||||||
|
workflow = self.portal.portal_workflow
|
||||||
|
workflow.doActionFor(self.comment, 'publish')
|
||||||
|
|
||||||
|
logout()
|
||||||
|
self.assertFalse(checkPerm(View, self.comment))
|
||||||
|
|
||||||
|
def test_migration(self):
|
||||||
|
from plone.app.discussion.upgrades import upgrade_comment_workflows
|
||||||
|
# Fake permission according to earlier comment_review_workflow.
|
||||||
|
self.comment._View_Permission = ('Anonymous',)
|
||||||
|
# Anonymous can see the comment.
|
||||||
|
logout()
|
||||||
|
self.assertTrue(checkPerm(View, self.comment))
|
||||||
|
# Run the upgrade.
|
||||||
|
login(self.portal, TEST_USER_NAME)
|
||||||
|
upgrade_comment_workflows(self.portal.portal_setup)
|
||||||
|
# The workflow chain is still what we want.
|
||||||
|
self.assertEqual(
|
||||||
|
self.portal.portal_workflow.getChainFor('Discussion Item'),
|
||||||
|
('comment_review_workflow',))
|
||||||
|
# A Manager can still see the comment.
|
||||||
|
self.assertTrue(checkPerm(View, self.comment))
|
||||||
|
# Anonymous cannot see the comment.
|
||||||
|
logout()
|
||||||
|
self.assertFalse(checkPerm(View, self.comment))
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from plone.app.discussion.interfaces import IDiscussionSettings
|
from plone.app.discussion.interfaces import IDiscussionSettings
|
||||||
from plone.registry.interfaces import IRegistry
|
from plone.registry.interfaces import IRegistry
|
||||||
|
from Products.CMFCore.utils import getToolByName
|
||||||
from zope.component import getUtility
|
from zope.component import getUtility
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
default_profile = 'profile-plone.app.discussion:default'
|
default_profile = 'profile-plone.app.discussion:default'
|
||||||
|
logger = logging.getLogger('plone.app.discussion')
|
||||||
|
|
||||||
|
|
||||||
def update_registry(context):
|
def update_registry(context):
|
||||||
@ -14,3 +18,46 @@ def update_registry(context):
|
|||||||
|
|
||||||
def update_rolemap(context):
|
def update_rolemap(context):
|
||||||
context.runImportStepFromProfile(default_profile, 'rolemap')
|
context.runImportStepFromProfile(default_profile, 'rolemap')
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade_comment_workflows(context):
|
||||||
|
# If the current comment workflow is the one_state_workflow, running our
|
||||||
|
# import step will change it to comment_one_state_workflow. This is good.
|
||||||
|
# If it was anything else, we should restore this. So get the original
|
||||||
|
# chain.
|
||||||
|
portal_type = 'Discussion Item'
|
||||||
|
wf_tool = getToolByName(context, 'portal_workflow')
|
||||||
|
orig_chain = list(wf_tool.getChainFor(portal_type))
|
||||||
|
|
||||||
|
# Run the workflow step. This sets the chain to
|
||||||
|
# comment_one_state_workflow.
|
||||||
|
context.runImportStepFromProfile(default_profile, 'workflow')
|
||||||
|
|
||||||
|
# Restore original workflow chain if needed.
|
||||||
|
old_workflow = 'one_state_workflow'
|
||||||
|
if old_workflow not in orig_chain:
|
||||||
|
# Restore the chain. Probably comment_review_workflow.
|
||||||
|
wf_tool.setChainForPortalTypes([portal_type], orig_chain)
|
||||||
|
elif len(orig_chain) > 1:
|
||||||
|
# This is strange, but I guess it could happen.
|
||||||
|
if old_workflow in orig_chain:
|
||||||
|
# Replace with new one.
|
||||||
|
idx = orig_chain.index(old_workflow)
|
||||||
|
orig_chain[idx] = 'comment_one_state_workflow'
|
||||||
|
# Restore the chain.
|
||||||
|
wf_tool.setChainForPortalTypes([portal_type], orig_chain)
|
||||||
|
new_chain = list(wf_tool.getChainFor(portal_type))
|
||||||
|
workflows = [wf_tool.getWorkflowById(wf_id)
|
||||||
|
for wf_id in new_chain]
|
||||||
|
|
||||||
|
# Now go over the comments, update their role mappings, and reindex the
|
||||||
|
# allowedRolesAndUsers index.
|
||||||
|
catalog = getToolByName(context, 'portal_catalog')
|
||||||
|
for brain in catalog.unrestrictedSearchResults(portal_type=portal_type):
|
||||||
|
try:
|
||||||
|
comment = brain.getObject()
|
||||||
|
for wf in workflows:
|
||||||
|
wf.updateRoleMappingsFor(comment)
|
||||||
|
comment.reindexObjectSecurity()
|
||||||
|
except (AttributeError, KeyError):
|
||||||
|
logger.info('Could not reindex comment %s' % brain.getURL())
|
||||||
|
@ -11,4 +11,44 @@
|
|||||||
handler=".upgrades.update_registry"
|
handler=".upgrades.update_registry"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<genericsetup:upgradeStep
|
||||||
|
title="edit comments and delete own comments"
|
||||||
|
description="reload registry config to enable new fields edit_comment_enabled and delete_own_comment_enabled"
|
||||||
|
source="100"
|
||||||
|
destination="101"
|
||||||
|
handler=".upgrades.update_registry"
|
||||||
|
sortkey="1"
|
||||||
|
profile="plone.app.discussion:default"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<genericsetup:upgradeStep
|
||||||
|
title="delete comments and delete own comments"
|
||||||
|
description="reload rolemap config to enable new permissions 'Delete comments' and 'Delete own comments'"
|
||||||
|
source="101"
|
||||||
|
destination="102"
|
||||||
|
handler=".upgrades.update_rolemap"
|
||||||
|
sortkey="1"
|
||||||
|
profile="plone.app.discussion:default"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<genericsetup:upgradeSteps
|
||||||
|
source="102"
|
||||||
|
destination="1000"
|
||||||
|
profile="plone.app.discussion:default">
|
||||||
|
<!-- Apply the update rolemap step again, to avoid missing it when
|
||||||
|
updating from plone.app.discussion 2.2.x. When originally
|
||||||
|
adding this step in the 2.3.x release, we should have made a
|
||||||
|
bigger metadata revision increase to leave some room for new
|
||||||
|
upgrade steps in 2.2.x. -->
|
||||||
|
<genericsetup:upgradeStep
|
||||||
|
title="delete comments and delete own comments"
|
||||||
|
description="reload rolemap config to enable new permissions 'Delete comments' and 'Delete own comments'"
|
||||||
|
handler=".upgrades.update_rolemap"
|
||||||
|
/>
|
||||||
|
<genericsetup:upgradeStep
|
||||||
|
title="Update plone.app.discussion workflows"
|
||||||
|
handler=".upgrades.upgrade_comment_workflows"
|
||||||
|
/>
|
||||||
|
</genericsetup:upgradeSteps>
|
||||||
|
|
||||||
</configure>
|
</configure>
|
||||||
|
Loading…
Reference in New Issue
Block a user