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:
 | 
			
		||||
 | 
			
		||||
- *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)
 | 
			
		||||
 | 
			
		||||
@ -125,7 +125,7 @@ class DiscussionSettingsControlPanel(controlpanel.ControlPanelFormWrapper):
 | 
			
		||||
            output.append('globally_enabled')
 | 
			
		||||
 | 
			
		||||
        # 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' not in workflow_chain
 | 
			
		||||
        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)
 | 
			
		||||
        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' in workflow_chain
 | 
			
		||||
        if one_state_workflow_enabled or comment_review_workflow_enabled:
 | 
			
		||||
@ -199,7 +199,7 @@ def notify_configuration_changed(event):
 | 
			
		||||
            else:
 | 
			
		||||
                # Disable moderation workflow
 | 
			
		||||
                wftool.setChainForPortalTypes(('Discussion Item',),
 | 
			
		||||
                                              'one_state_workflow')
 | 
			
		||||
                                              'comment_one_state_workflow')
 | 
			
		||||
 | 
			
		||||
    if IConfigurationChangedEvent.providedBy(event):
 | 
			
		||||
        # Types control panel setting changed
 | 
			
		||||
@ -209,7 +209,7 @@ def notify_configuration_changed(event):
 | 
			
		||||
            workflow_chain = wftool.getChainForPortalType('Discussion Item')
 | 
			
		||||
            if workflow_chain:
 | 
			
		||||
                workflow = workflow_chain[0]
 | 
			
		||||
                if workflow == 'one_state_workflow':
 | 
			
		||||
                if workflow == 'comment_one_state_workflow':
 | 
			
		||||
                    settings.moderation_enabled = False
 | 
			
		||||
                elif workflow == 'comment_review_workflow':
 | 
			
		||||
                    settings.moderation_enabled = True
 | 
			
		||||
 | 
			
		||||
@ -40,26 +40,7 @@
 | 
			
		||||
        provides="Products.GenericSetup.interfaces.EXTENSION"
 | 
			
		||||
        for="Products.CMFPlone.interfaces.IPloneSiteRoot"
 | 
			
		||||
        />
 | 
			
		||||
 | 
			
		||||
    <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"
 | 
			
		||||
    />
 | 
			
		||||
    <!-- For upgrade steps see upgrades.zcml. -->
 | 
			
		||||
 | 
			
		||||
    <!-- Comments -->
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
<metadata>
 | 
			
		||||
 <version>102</version>
 | 
			
		||||
 <version>1000</version>
 | 
			
		||||
 <dependencies>
 | 
			
		||||
  <dependency>profile-plone.app.registry:default</dependency>
 | 
			
		||||
 </dependencies>
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,10 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<object name="portal_workflow" meta_type="Plone Workflow Tool">
 | 
			
		||||
  <object name="comment_review_workflow" meta_type="Workflow"/>
 | 
			
		||||
  <object name="comment_one_state_workflow" meta_type="Workflow"/>
 | 
			
		||||
  <bindings>
 | 
			
		||||
    <type type_id="Discussion Item">
 | 
			
		||||
      <bound-workflow workflow_id="one_state_workflow" />
 | 
			
		||||
      <bound-workflow workflow_id="comment_one_state_workflow" />
 | 
			
		||||
    </type>
 | 
			
		||||
  </bindings>
 | 
			
		||||
</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="">
 | 
			
		||||
    Visible to everyone, non-editable.
 | 
			
		||||
  </description>
 | 
			
		||||
  <permission-map name="Access contents information" acquired="False">
 | 
			
		||||
   <permission-role>Anonymous</permission-role>
 | 
			
		||||
  <permission-map name="Access contents information" acquired="True">
 | 
			
		||||
  </permission-map>
 | 
			
		||||
  <permission-map name="Modify portal content" acquired="False">
 | 
			
		||||
   <permission-role>Manager</permission-role>
 | 
			
		||||
  </permission-map>
 | 
			
		||||
  <permission-map name="View" acquired="False">
 | 
			
		||||
   <permission-role>Anonymous</permission-role>
 | 
			
		||||
  <permission-map name="View" acquired="True">
 | 
			
		||||
  </permission-map>
 | 
			
		||||
  <permission-map name="Reply to item" acquired="True">
 | 
			
		||||
  </permission-map>
 | 
			
		||||
 | 
			
		||||
@ -59,6 +59,10 @@ class ConversationCatalogTest(unittest.TestCase):
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        self.portal = self.layer['portal']
 | 
			
		||||
        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')
 | 
			
		||||
        conversation = IConversation(self.portal.doc1)
 | 
			
		||||
        comment1 = createObject('plone.Comment')
 | 
			
		||||
 | 
			
		||||
@ -27,6 +27,9 @@ class CommentTest(unittest.TestCase):
 | 
			
		||||
        self.portal = self.layer['portal']
 | 
			
		||||
        self.request = self.layer['request']
 | 
			
		||||
 | 
			
		||||
        workflow = self.portal.portal_workflow
 | 
			
		||||
        workflow.doActionFor(self.portal.doc1, 'publish')
 | 
			
		||||
 | 
			
		||||
        setRoles(self.portal, TEST_USER_ID, ['Manager'])
 | 
			
		||||
        self.catalog = getToolByName(self.portal, 'portal_catalog')
 | 
			
		||||
        self.document_brain = self.catalog.searchResults(
 | 
			
		||||
@ -351,6 +354,9 @@ class RepliesTest(unittest.TestCase):
 | 
			
		||||
        self.portal = self.layer['portal']
 | 
			
		||||
        setRoles(self.portal, TEST_USER_ID, ['Manager'])
 | 
			
		||||
 | 
			
		||||
        workflow = self.portal.portal_workflow
 | 
			
		||||
        workflow.doActionFor(self.portal.doc1, 'publish')
 | 
			
		||||
 | 
			
		||||
    def test_add_comment(self):
 | 
			
		||||
        # Add comments to a CommentReplies adapter
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -458,7 +458,7 @@ class TestCommentsViewlet(unittest.TestCase):
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        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.memberdata = self.portal.portal_memberdata
 | 
			
		||||
 | 
			
		||||
@ -163,9 +163,9 @@ class ConfigurationChangedSubscriberTest(unittest.TestCase):
 | 
			
		||||
           the 'comment_moderation' setting in the discussion control panel
 | 
			
		||||
           changes.
 | 
			
		||||
        """
 | 
			
		||||
        # By default the one_state_workflow without moderation is enabled
 | 
			
		||||
        # By default the comment_one_state_workflow without moderation is enabled
 | 
			
		||||
        self.assertEqual(
 | 
			
		||||
            ('one_state_workflow',),
 | 
			
		||||
            ('comment_one_state_workflow',),
 | 
			
		||||
            self.portal.portal_workflow.getChainForPortalType(
 | 
			
		||||
                'Discussion Item'
 | 
			
		||||
            )
 | 
			
		||||
@ -185,7 +185,7 @@ class ConfigurationChangedSubscriberTest(unittest.TestCase):
 | 
			
		||||
        # And back
 | 
			
		||||
        self.settings.moderation_enabled = False
 | 
			
		||||
        self.assertEqual(
 | 
			
		||||
            ('one_state_workflow',),
 | 
			
		||||
            ('comment_one_state_workflow',),
 | 
			
		||||
            self.portal.portal_workflow.getChainForPortalType(
 | 
			
		||||
                'Discussion Item'
 | 
			
		||||
            )
 | 
			
		||||
@ -211,7 +211,7 @@ class ConfigurationChangedSubscriberTest(unittest.TestCase):
 | 
			
		||||
        # Enable the 'comment_review_workflow' with moderation enabled
 | 
			
		||||
        self.portal.portal_workflow.setChainForPortalTypes(
 | 
			
		||||
            ('Discussion Item',),
 | 
			
		||||
            ('one_state_workflow',)
 | 
			
		||||
            ('comment_one_state_workflow',)
 | 
			
		||||
        )
 | 
			
		||||
        self.settings.moderation_enabled = True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -50,6 +50,9 @@ class ConversationTest(unittest.TestCase):
 | 
			
		||||
        settings = registry.forInterface(IDiscussionSettings)
 | 
			
		||||
        settings.globally_enabled = True
 | 
			
		||||
 | 
			
		||||
        workflow = self.portal.portal_workflow
 | 
			
		||||
        workflow.doActionFor(self.portal.doc1, 'publish')
 | 
			
		||||
 | 
			
		||||
    def test_add_comment(self):
 | 
			
		||||
        # Create a conversation. In this case we doesn't assign it to an
 | 
			
		||||
        # object, as we just want to check the Conversation object API.
 | 
			
		||||
@ -744,6 +747,9 @@ class RepliesTest(unittest.TestCase):
 | 
			
		||||
        self.portal = self.layer['portal']
 | 
			
		||||
        setRoles(self.portal, TEST_USER_ID, ['Manager'])
 | 
			
		||||
 | 
			
		||||
        workflow = self.portal.portal_workflow
 | 
			
		||||
        workflow.doActionFor(self.portal.doc1, 'publish')
 | 
			
		||||
 | 
			
		||||
    def test_add_comment(self):
 | 
			
		||||
        # Add comments to a ConversationReplies adapter
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -35,6 +35,9 @@ class ConversationIndexersTest(unittest.TestCase):
 | 
			
		||||
        self.portal = self.layer['portal']
 | 
			
		||||
        setRoles(self.portal, TEST_USER_ID, ['Manager'])
 | 
			
		||||
 | 
			
		||||
        workflow = self.portal.portal_workflow
 | 
			
		||||
        workflow.doActionFor(self.portal.doc1, 'publish')
 | 
			
		||||
 | 
			
		||||
        # Create a conversation.
 | 
			
		||||
        conversation = IConversation(self.portal.doc1)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -46,9 +46,9 @@ class ModerationViewTest(unittest.TestCase):
 | 
			
		||||
        # If workflow is not set, enabled must return False
 | 
			
		||||
        self.wf_tool.setChainForPortalTypes(('Discussion Item',), ())
 | 
			
		||||
        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',),
 | 
			
		||||
                                            ('one_state_workflow,'))
 | 
			
		||||
                                            ('comment_one_state_workflow,'))
 | 
			
		||||
        self.assertEqual(self.view.moderation_enabled(), False)
 | 
			
		||||
        # The comment_review_workflow does have a 'pending' state
 | 
			
		||||
        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 setRoles
 | 
			
		||||
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.utils import _checkPermission as checkPerm
 | 
			
		||||
from zope.component import createObject
 | 
			
		||||
@ -35,7 +36,7 @@ class WorkflowSetupTest(unittest.TestCase):
 | 
			
		||||
    def test_workflows_installed(self):
 | 
			
		||||
        """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.assertTrue('comment_review_workflow' in
 | 
			
		||||
                        self.portal.portal_workflow.objectIds())
 | 
			
		||||
@ -44,7 +45,7 @@ class WorkflowSetupTest(unittest.TestCase):
 | 
			
		||||
        """Make sure one_state_workflow is the default workflow.
 | 
			
		||||
        """
 | 
			
		||||
        self.assertEqual(
 | 
			
		||||
            ('one_state_workflow',),
 | 
			
		||||
            ('comment_one_state_workflow',),
 | 
			
		||||
            self.portal.portal_workflow.getChainForPortalType(
 | 
			
		||||
                'Discussion Item'
 | 
			
		||||
            )
 | 
			
		||||
@ -102,7 +103,7 @@ class PermissionsSetupTest(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
 | 
			
		||||
@ -114,8 +115,6 @@ class CommentOneStateWorkflowTest(unittest.TestCase):
 | 
			
		||||
        self.folder = self.portal['test-folder']
 | 
			
		||||
        self.catalog = self.portal.portal_catalog
 | 
			
		||||
        self.workflow = self.portal.portal_workflow
 | 
			
		||||
        self.workflow.setChainForPortalTypes(['Document'],
 | 
			
		||||
                                             'one_state_workflow')
 | 
			
		||||
        self.folder.invokeFactory('Document', 'doc1')
 | 
			
		||||
        self.doc = self.folder.doc1
 | 
			
		||||
 | 
			
		||||
@ -137,10 +136,10 @@ class CommentOneStateWorkflowTest(unittest.TestCase):
 | 
			
		||||
        self.portal.acl_users._doAddUser('reader', 'secret', ['Reader'], [])
 | 
			
		||||
 | 
			
		||||
    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'),
 | 
			
		||||
                         'published')
 | 
			
		||||
                         'private')
 | 
			
		||||
 | 
			
		||||
    def test_view_comments(self):
 | 
			
		||||
        """Make sure published comments can be viewed by everyone.
 | 
			
		||||
@ -149,6 +148,10 @@ class CommentOneStateWorkflowTest(unittest.TestCase):
 | 
			
		||||
        # self.login(default_user)
 | 
			
		||||
        # self.assertTrue(checkPerm(View, self.doc))
 | 
			
		||||
        # Member is allowed
 | 
			
		||||
        login(self.portal, TEST_USER_NAME)
 | 
			
		||||
        workflow = self.portal.portal_workflow
 | 
			
		||||
        workflow.doActionFor(self.doc, 'publish')
 | 
			
		||||
 | 
			
		||||
        login(self.portal, 'member')
 | 
			
		||||
        self.assertTrue(checkPerm(View, self.comment))
 | 
			
		||||
        # Reviewer is allowed
 | 
			
		||||
@ -164,6 +167,30 @@ class CommentOneStateWorkflowTest(unittest.TestCase):
 | 
			
		||||
        login(self.portal, 'reader')
 | 
			
		||||
        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):
 | 
			
		||||
    """Test the comment_review_workflow that ships with plone.app.discussion.
 | 
			
		||||
@ -269,3 +296,35 @@ class CommentReviewWorkflowTest(unittest.TestCase):
 | 
			
		||||
                '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 -*-
 | 
			
		||||
from plone.app.discussion.interfaces import IDiscussionSettings
 | 
			
		||||
from plone.registry.interfaces import IRegistry
 | 
			
		||||
from Products.CMFCore.utils import getToolByName
 | 
			
		||||
from zope.component import getUtility
 | 
			
		||||
 | 
			
		||||
import logging
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
default_profile = 'profile-plone.app.discussion:default'
 | 
			
		||||
logger = logging.getLogger('plone.app.discussion')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def update_registry(context):
 | 
			
		||||
@ -14,3 +18,46 @@ def update_registry(context):
 | 
			
		||||
 | 
			
		||||
def update_rolemap(context):
 | 
			
		||||
    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"
 | 
			
		||||
      />
 | 
			
		||||
 | 
			
		||||
  <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>
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user