added Delete comments permission to manage comments deletion

This commit is contained in:
Andrea Cecchi 2014-03-03 15:12:16 +01:00
parent fd16144b9b
commit 9a4e3718fc
10 changed files with 43 additions and 98 deletions

View File

@ -21,6 +21,9 @@ Changelog
- Make comments editable. - Make comments editable.
[pjstevns, gyst] [pjstevns, gyst]
- Provide 'Delete comments' permission to handle comments deletion
[cekk]
2.3.2 (2014-04-05) 2.3.2 (2014-04-05)
------------------ ------------------
@ -100,8 +103,6 @@ Changelog
[toutpt] [toutpt]
=======
>>>>>>> rebased branch from master
2.2.10 (2013-09-24) 2.2.10 (2013-09-24)
------------------- -------------------

View File

@ -328,18 +328,9 @@ class CommentsViewlet(ViewletBase):
"""By default requires 'Review comments'. """By default requires 'Review comments'.
If 'delete own comments' is enabled, requires 'Edit comments'. If 'delete own comments' is enabled, requires 'Edit comments'.
""" """
if self.is_delete_own_comment_allowed(): return getSecurityManager().checkPermission('Delete comments',
permission = 'Edit comments'
else:
permission = 'Review comments'
return getSecurityManager().checkPermission(permission,
aq_inner(reply)) 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): def is_discussion_allowed(self):
context = aq_inner(self.context) context = aq_inner(self.context)
return context.restrictedTraverse('@@conversation_view').enabled() return context.restrictedTraverse('@@conversation_view').enabled()

View File

@ -88,7 +88,7 @@
name="moderate-delete-comment" name="moderate-delete-comment"
layer="..interfaces.IDiscussionLayer" layer="..interfaces.IDiscussionLayer"
class=".moderation.DeleteComment" class=".moderation.DeleteComment"
permission="zope2.DeleteObjects" permission="plone.app.discussion.DeleteComments"
/> />
<!-- Publish comment view --> <!-- Publish comment view -->

View File

@ -54,8 +54,6 @@ class DiscussionSettingsEditForm(controlpanel.RegistryEditForm):
SingleCheckBoxFieldWidget SingleCheckBoxFieldWidget
self.fields['edit_comment_enabled'].widgetFactory = \ self.fields['edit_comment_enabled'].widgetFactory = \
SingleCheckBoxFieldWidget SingleCheckBoxFieldWidget
self.fields['delete_own_comment_enabled'].widgetFactory = \
SingleCheckBoxFieldWidget
self.fields['anonymous_comments'].widgetFactory = \ self.fields['anonymous_comments'].widgetFactory = \
SingleCheckBoxFieldWidget SingleCheckBoxFieldWidget
self.fields['show_commenter_image'].widgetFactory = \ self.fields['show_commenter_image'].widgetFactory = \

View File

@ -117,18 +117,9 @@ class DeleteComment(BrowserView):
"""By default requires 'Review comments'. """By default requires 'Review comments'.
If 'delete own comments' is enabled, requires 'Edit comments'. If 'delete own comments' is enabled, requires 'Edit comments'.
""" """
if self.is_delete_own_comment_allowed(): return getSecurityManager().checkPermission('Delete comments',
permission = 'Edit comments'
else:
permission = 'Review comments'
return getSecurityManager().checkPermission(permission,
aq_inner(reply)) 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): class PublishComment(BrowserView):
"""Publish a comment. """Publish a comment.

View File

@ -254,17 +254,6 @@ class IDiscussionSettings(Interface):
default=False, 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( text_transform = schema.Choice(
title=_(u"label_text_transform", title=_(u"label_text_transform",
default="Comment text transform"), default="Comment text transform"),

View File

@ -14,5 +14,9 @@
title="Edit comments" title="Edit comments"
/> />
<permission
id="plone.app.discussion.DeleteComments"
title="Delete comments"
/>
</configure> </configure>

View File

@ -3,15 +3,20 @@
<permissions> <permissions>
<permission name="Review comments" acquire="True"> <permission name="Review comments" acquire="True">
<role name="Manager"/> <role name="Manager"/>
<role name="Site Administrator"/> <role name="Site Administrator"/>
<role name="Reviewer"/> <role name="Reviewer"/>
</permission> </permission>
<permission name="Edit comments" acquire="True"> <permission name="Edit comments" acquire="True">
<role name="Manager"/> <role name="Manager"/>
<role name="Site Administrator"/> <role name="Site Administrator"/>
<role name="Reviewer"/> <role name="Reviewer"/>
<role name="Owner"/> <role name="Owner"/>
</permission> </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"> <permission name="Reply to item" acquire="False">
<role name="Authenticated"/> <role name="Authenticated"/>
</permission> </permission>

View File

@ -34,6 +34,8 @@ class PloneAppDiscussion(PloneSandboxLayer):
USER_WITH_FULLNAME_PASSWORD = 'secret' USER_WITH_FULLNAME_PASSWORD = 'secret'
MANAGER_USER_NAME = 'manager' MANAGER_USER_NAME = 'manager'
MANAGER_USER_PASSWORD = 'secret' MANAGER_USER_PASSWORD = 'secret'
REVIEWER_NAME = 'reviewer'
REVIEWER_PASSWORD = 'secret'
def setUpZope(self, app, configurationContext): def setUpZope(self, app, configurationContext):
# Load ZCML # Load ZCML
@ -66,7 +68,15 @@ class PloneAppDiscussion(PloneSandboxLayer):
['Member'], ['Member'],
[], [],
) )
acl_users.userFolderAddUser(
self.REVIEWER_NAME,
self.REVIEWER_PASSWORD,
['Member'],
[],
)
mtool = getToolByName(portal, 'portal_membership', None) mtool = getToolByName(portal, 'portal_membership', None)
gtool = getToolByName(portal, 'portal_groups', None)
gtool.addPrincipalToGroup(self.REVIEWER_NAME, 'Reviewers')
mtool.addMember('jim', 'Jim', ['Member'], []) mtool.addMember('jim', 'Jim', ['Member'], [])
mtool.getMemberById('jim').setMemberProperties( mtool.getMemberById('jim').setMemberProperties(
{"fullname": 'Jim Fult\xc3\xb8rn'}) {"fullname": 'Jim Fult\xc3\xb8rn'})

View File

@ -32,6 +32,7 @@ you're not logged in::
>>> unprivileged_browser = Browser(app) >>> unprivileged_browser = Browser(app)
>>> browser_member = Browser(app) >>> browser_member = Browser(app)
>>> browser_user = 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: 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'. Login as user 'jim'.
>>> browser_member.open(portal_url + '/login_form') >>> browser_member.open(portal_url + '/login_form')
>>> browser_member.getControl(name='__ac_name').value = 'jim' >>> browser_member.getControl(name='__ac_name').value = 'jim'
>>> browser_member.getControl(name='__ac_password').value = 'secret' >>> browser_member.getControl(name='__ac_password').value = 'secret'
@ -320,8 +320,8 @@ But Anon can see the edited comment.
True True
Deleting existing comments | 'delete own comments' disabled Deleting existing comments | 'Delete comments' permission
----------------------------------------------------------- ----------------------------------------------------------
Anonymous cannot delete comments Anonymous cannot delete comments
@ -329,7 +329,7 @@ Anonymous cannot delete comments
>>> 'form.button.Delete' in unprivileged_browser.contents >>> 'form.button.Delete' in unprivileged_browser.contents
False 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) >>> browser_member.open(urldoc1)
>>> 'form.button.Delete' in browser_member.contents >>> 'form.button.Delete' in browser_member.contents
@ -360,7 +360,6 @@ The comment is still there
>>> comment_id in unprivileged_browser.contents >>> comment_id in unprivileged_browser.contents
True True
A Member cannot delete even his own comment by hitting the delete url directly. A Member cannot delete even his own comment by hitting the delete url directly.
Extract the member comment id from the admin browser 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 >>> 'Comment from Jim' in browser_member.contents
True True
Admin, who hase 'review comments' permission, can delete comments Now login as user 'reviewer'
>>> browser.open(urldoc1) >>> browser_reviewer.open(portal_url + '/login_form')
>>> form = browser.getForm(name='delete', index=0) >>> 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 >>> '@@moderate-delete-comment' in form.action
True 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 Returning to the document we find the deleted comment is indeed gone
>>> browser.open(urldoc1) >>> browser_reviewer.open(urldoc1)
>>> comment_id in browser.contents >>> comment_id in browser_reviewer.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
False False