added Delete comments permission to manage comments deletion
This commit is contained in:
		
							parent
							
								
									6ee480a229
								
							
						
					
					
						commit
						920392d124
					
				@ -25,12 +25,12 @@ Changelog
 | 
			
		||||
 | 
			
		||||
- Fix ownership of comments. [toutpt]
 | 
			
		||||
 | 
			
		||||
- Provide 'delete own comments' as a configurable option
 | 
			
		||||
  [gyst]
 | 
			
		||||
 | 
			
		||||
- Make comments editable.
 | 
			
		||||
  [pjstevns, gyst]
 | 
			
		||||
 | 
			
		||||
- Provide 'Delete comments' permission to handle comments deletion
 | 
			
		||||
  [cekk]
 | 
			
		||||
 | 
			
		||||
2.2.10 (2013-09-24)
 | 
			
		||||
-------------------
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -312,18 +312,9 @@ class CommentsViewlet(ViewletBase):
 | 
			
		||||
        """By default requires 'Review comments'.
 | 
			
		||||
        If 'delete own comments' is enabled, requires 'Edit comments'.
 | 
			
		||||
        """
 | 
			
		||||
        if self.is_delete_own_comment_allowed():
 | 
			
		||||
            permission = 'Edit comments'
 | 
			
		||||
        else:
 | 
			
		||||
            permission = 'Review comments'
 | 
			
		||||
        return getSecurityManager().checkPermission(permission,
 | 
			
		||||
        return getSecurityManager().checkPermission('Delete comments',
 | 
			
		||||
                                                    aq_inner(reply))
 | 
			
		||||
 | 
			
		||||
    def is_delete_own_comment_allowed(self):
 | 
			
		||||
        registry = queryUtility(IRegistry)
 | 
			
		||||
        settings = registry.forInterface(IDiscussionSettings, check=False)
 | 
			
		||||
        return settings.delete_own_comment_enabled
 | 
			
		||||
 | 
			
		||||
    def is_discussion_allowed(self):
 | 
			
		||||
        context = aq_inner(self.context)
 | 
			
		||||
        return context.restrictedTraverse('@@conversation_view').enabled()
 | 
			
		||||
 | 
			
		||||
@ -88,7 +88,7 @@
 | 
			
		||||
        name="moderate-delete-comment"
 | 
			
		||||
        layer="..interfaces.IDiscussionLayer"
 | 
			
		||||
        class=".moderation.DeleteComment"
 | 
			
		||||
        permission="zope2.DeleteObjects"
 | 
			
		||||
        permission="plone.app.discussion.DeleteComments"
 | 
			
		||||
        />
 | 
			
		||||
 | 
			
		||||
    <!-- Publish comment view -->
 | 
			
		||||
 | 
			
		||||
@ -54,8 +54,6 @@ class DiscussionSettingsEditForm(controlpanel.RegistryEditForm):
 | 
			
		||||
            SingleCheckBoxFieldWidget
 | 
			
		||||
        self.fields['edit_comment_enabled'].widgetFactory = \
 | 
			
		||||
            SingleCheckBoxFieldWidget
 | 
			
		||||
        self.fields['delete_own_comment_enabled'].widgetFactory = \
 | 
			
		||||
            SingleCheckBoxFieldWidget
 | 
			
		||||
        self.fields['anonymous_comments'].widgetFactory = \
 | 
			
		||||
            SingleCheckBoxFieldWidget
 | 
			
		||||
        self.fields['show_commenter_image'].widgetFactory = \
 | 
			
		||||
 | 
			
		||||
@ -117,18 +117,9 @@ class DeleteComment(BrowserView):
 | 
			
		||||
        """By default requires 'Review comments'.
 | 
			
		||||
        If 'delete own comments' is enabled, requires 'Edit comments'.
 | 
			
		||||
        """
 | 
			
		||||
        if self.is_delete_own_comment_allowed():
 | 
			
		||||
            permission = 'Edit comments'
 | 
			
		||||
        else:
 | 
			
		||||
            permission = 'Review comments'
 | 
			
		||||
        return getSecurityManager().checkPermission(permission,
 | 
			
		||||
        return getSecurityManager().checkPermission('Delete comments',
 | 
			
		||||
                                                    aq_inner(reply))
 | 
			
		||||
 | 
			
		||||
    def is_delete_own_comment_allowed(self):
 | 
			
		||||
        registry = queryUtility(IRegistry)
 | 
			
		||||
        settings = registry.forInterface(IDiscussionSettings, check=False)
 | 
			
		||||
        return settings.delete_own_comment_enabled
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PublishComment(BrowserView):
 | 
			
		||||
    """Publish a comment.
 | 
			
		||||
 | 
			
		||||
@ -253,17 +253,6 @@ class IDiscussionSettings(Interface):
 | 
			
		||||
        default=False,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    delete_own_comment_enabled = schema.Bool(
 | 
			
		||||
        title=_(u"label_delete_own_comment_enabled",
 | 
			
		||||
                default="Allow users to delete their own comment threads"),
 | 
			
		||||
        description=_(u"help_edit_comment_enabled",
 | 
			
		||||
                      default=u"If selected, users may delete their own "
 | 
			
		||||
                      "comments -> AND the whole reply thread below that "
 | 
			
		||||
                      "comment!"),
 | 
			
		||||
        required=False,
 | 
			
		||||
        default=False,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    text_transform = schema.Choice(
 | 
			
		||||
        title=_(u"label_text_transform",
 | 
			
		||||
                default="Comment text transform"),
 | 
			
		||||
 | 
			
		||||
@ -14,5 +14,9 @@
 | 
			
		||||
        title="Edit comments"
 | 
			
		||||
        />
 | 
			
		||||
 | 
			
		||||
    <permission
 | 
			
		||||
        id="plone.app.discussion.DeleteComments"
 | 
			
		||||
        title="Delete comments"
 | 
			
		||||
        />
 | 
			
		||||
 | 
			
		||||
</configure>
 | 
			
		||||
 | 
			
		||||
@ -3,15 +3,20 @@
 | 
			
		||||
    <permissions>
 | 
			
		||||
        <permission name="Review comments" acquire="True">
 | 
			
		||||
            <role name="Manager"/>
 | 
			
		||||
	    <role name="Site Administrator"/>
 | 
			
		||||
	        <role name="Site Administrator"/>
 | 
			
		||||
            <role name="Reviewer"/>
 | 
			
		||||
        </permission>
 | 
			
		||||
        <permission name="Edit comments" acquire="True">
 | 
			
		||||
            <role name="Manager"/>
 | 
			
		||||
	    <role name="Site Administrator"/>
 | 
			
		||||
	        <role name="Site Administrator"/>
 | 
			
		||||
            <role name="Reviewer"/>
 | 
			
		||||
            <role name="Owner"/>
 | 
			
		||||
        </permission>
 | 
			
		||||
        <permission name="Delete comments" acquire="True">
 | 
			
		||||
            <role name="Manager"/>
 | 
			
		||||
            <role name="Site Administrator"/>
 | 
			
		||||
            <role name="Reviewer"/>
 | 
			
		||||
        </permission>
 | 
			
		||||
        <permission name="Reply to item" acquire="False">
 | 
			
		||||
            <role name="Authenticated"/>
 | 
			
		||||
        </permission>
 | 
			
		||||
 | 
			
		||||
@ -28,6 +28,8 @@ class PloneAppDiscussion(PloneSandboxLayer):
 | 
			
		||||
    USER_WITH_FULLNAME_PASSWORD = 'secret'
 | 
			
		||||
    MANAGER_USER_NAME = 'manager'
 | 
			
		||||
    MANAGER_USER_PASSWORD = 'secret'
 | 
			
		||||
    REVIEWER_NAME = 'reviewer'
 | 
			
		||||
    REVIEWER_PASSWORD = 'secret'
 | 
			
		||||
 | 
			
		||||
    def setUpZope(self, app, configurationContext):
 | 
			
		||||
        # Load ZCML
 | 
			
		||||
@ -60,7 +62,15 @@ class PloneAppDiscussion(PloneSandboxLayer):
 | 
			
		||||
            ['Member'],
 | 
			
		||||
            [],
 | 
			
		||||
        )
 | 
			
		||||
        acl_users.userFolderAddUser(
 | 
			
		||||
            self.REVIEWER_NAME,
 | 
			
		||||
            self.REVIEWER_PASSWORD,
 | 
			
		||||
            ['Member'],
 | 
			
		||||
            [],
 | 
			
		||||
        )
 | 
			
		||||
        mtool = getToolByName(portal, 'portal_membership', None)
 | 
			
		||||
        gtool = getToolByName(portal, 'portal_groups', None)
 | 
			
		||||
        gtool.addPrincipalToGroup(self.REVIEWER_NAME, 'Reviewers')
 | 
			
		||||
        mtool.addMember('jim', 'Jim', ['Member'], [])
 | 
			
		||||
        mtool.getMemberById('jim').setMemberProperties(
 | 
			
		||||
            {"fullname": 'Jim Fult\xc3\xb8rn'})
 | 
			
		||||
 | 
			
		||||
@ -32,6 +32,7 @@ you're not logged in::
 | 
			
		||||
    >>> unprivileged_browser = Browser(app)
 | 
			
		||||
    >>> browser_member = Browser(app)
 | 
			
		||||
    >>> browser_user = Browser(app)
 | 
			
		||||
    >>> browser_reviewer = Browser(app)
 | 
			
		||||
 | 
			
		||||
Make sure we have a test user from the layer and it uses fancy characters:
 | 
			
		||||
 | 
			
		||||
@ -143,7 +144,6 @@ Post a comment as member
 | 
			
		||||
------------------------
 | 
			
		||||
 | 
			
		||||
Login as user 'jim'.
 | 
			
		||||
 | 
			
		||||
    >>> browser_member.open(portal_url + '/login_form')
 | 
			
		||||
    >>> browser_member.getControl(name='__ac_name').value = 'jim'
 | 
			
		||||
    >>> browser_member.getControl(name='__ac_password').value = 'secret'
 | 
			
		||||
@ -320,8 +320,8 @@ But Anon can see the edited comment.
 | 
			
		||||
    True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Deleting existing comments | 'delete own comments' disabled
 | 
			
		||||
-----------------------------------------------------------
 | 
			
		||||
Deleting existing comments | 'Delete comments' permission
 | 
			
		||||
----------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Anonymous cannot delete comments
 | 
			
		||||
 | 
			
		||||
@ -329,7 +329,7 @@ Anonymous cannot delete comments
 | 
			
		||||
    >>> 'form.button.Delete' in unprivileged_browser.contents
 | 
			
		||||
    False
 | 
			
		||||
 | 
			
		||||
A member cannot delete his own comments, unless this is explicitly enabled (see later)
 | 
			
		||||
A member cannot delete his own comments if he can't review or he isn't a Site Administrator
 | 
			
		||||
 | 
			
		||||
    >>> browser_member.open(urldoc1)
 | 
			
		||||
    >>> 'form.button.Delete' in browser_member.contents
 | 
			
		||||
@ -360,7 +360,6 @@ The comment is still there
 | 
			
		||||
    >>> comment_id in unprivileged_browser.contents
 | 
			
		||||
    True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
A Member cannot delete even his own comment by hitting the delete url directly.
 | 
			
		||||
 | 
			
		||||
Extract the member comment id from the admin browser
 | 
			
		||||
@ -387,10 +386,17 @@ The comment is still there
 | 
			
		||||
    >>> 'Comment from Jim' in browser_member.contents
 | 
			
		||||
    True
 | 
			
		||||
 | 
			
		||||
Admin, who hase 'review comments' permission, can delete comments
 | 
			
		||||
Now login as user 'reviewer'
 | 
			
		||||
 | 
			
		||||
    >>> browser.open(urldoc1)
 | 
			
		||||
    >>> form = browser.getForm(name='delete', index=0)
 | 
			
		||||
    >>> browser_reviewer.open(portal_url + '/login_form')
 | 
			
		||||
    >>> browser_reviewer.getControl(name='__ac_name').value = 'reviewer'
 | 
			
		||||
    >>> browser_reviewer.getControl(name='__ac_password').value = 'secret'
 | 
			
		||||
    >>> browser_reviewer.getControl(name='submit').click()
 | 
			
		||||
 | 
			
		||||
Admin and who have 'Delete comments' permission (reviewers for example), can delete comments
 | 
			
		||||
 | 
			
		||||
    >>> browser_reviewer.open(urldoc1)
 | 
			
		||||
    >>> form = browser_reviewer.getForm(name='delete', index=0)
 | 
			
		||||
    >>> '@@moderate-delete-comment' in form.action
 | 
			
		||||
    True
 | 
			
		||||
 | 
			
		||||
@ -406,58 +412,8 @@ We'll just catch that and check the result later.
 | 
			
		||||
 | 
			
		||||
Returning to the document we find the deleted comment is indeed gone
 | 
			
		||||
 | 
			
		||||
    >>> browser.open(urldoc1)
 | 
			
		||||
    >>> comment_id in browser.contents
 | 
			
		||||
    False
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Deleting existing comments | 'delete own comments' ENABLED
 | 
			
		||||
----------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Enable deletion of own comments
 | 
			
		||||
 | 
			
		||||
    >>> from zope.component import queryUtility
 | 
			
		||||
    >>> from plone.registry.interfaces import IRegistry
 | 
			
		||||
    >>> from plone.app.discussion.interfaces import IDiscussionSettings
 | 
			
		||||
    >>> registry = queryUtility(IRegistry)
 | 
			
		||||
    >>> settings = registry.forInterface(IDiscussionSettings)
 | 
			
		||||
    >>> settings.delete_own_comment_enabled = True
 | 
			
		||||
 | 
			
		||||
    >>> import transaction
 | 
			
		||||
    >>> transaction.commit()
 | 
			
		||||
 | 
			
		||||
Anonymous still cannot delete comments
 | 
			
		||||
 | 
			
		||||
    >>> unprivileged_browser.open(urldoc1)
 | 
			
		||||
    >>> 'form.button.Delete' in unprivileged_browser.contents
 | 
			
		||||
    False
 | 
			
		||||
 | 
			
		||||
A member can now delete his own comments
 | 
			
		||||
 | 
			
		||||
    >>> browser_member.open(urldoc1)
 | 
			
		||||
    >>> 'form.button.Delete' in browser_member.contents
 | 
			
		||||
    True
 | 
			
		||||
 | 
			
		||||
    >>> form = browser_member.getForm(name='delete', index=0)
 | 
			
		||||
    >>> '@@moderate-delete-comment' in form.action
 | 
			
		||||
    True
 | 
			
		||||
 | 
			
		||||
    >>> comment_id = form.action.split('/')[-2]
 | 
			
		||||
 | 
			
		||||
Submitting the form runs into a testbrowser notFoundException.
 | 
			
		||||
We'll just catch that and check the result later.
 | 
			
		||||
 | 
			
		||||
    >>> try:
 | 
			
		||||
    ...   form.submit()    
 | 
			
		||||
    ... except:
 | 
			
		||||
    ...   pass
 | 
			
		||||
 | 
			
		||||
Returning to the document we find the deleted comment is indeed gone
 | 
			
		||||
 | 
			
		||||
    >>> browser_member.open(urldoc1)
 | 
			
		||||
    >>> comment_id in browser_member.contents
 | 
			
		||||
    False
 | 
			
		||||
    >>> 'Comment from Jim' in browser_member.contents
 | 
			
		||||
    >>> browser_reviewer.open(urldoc1)
 | 
			
		||||
    >>> comment_id in browser_reviewer.contents
 | 
			
		||||
    False
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user