diff --git a/CHANGES.rst b/CHANGES.rst index 4ac4976..181c1cf 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -21,6 +21,9 @@ Changelog - Make comments editable. [pjstevns, gyst] +- Provide 'Delete comments' permission to handle comments deletion + [cekk] + 2.3.2 (2014-04-05) ------------------ @@ -100,8 +103,6 @@ Changelog [toutpt] -======= ->>>>>>> rebased branch from master 2.2.10 (2013-09-24) ------------------- diff --git a/plone/app/discussion/browser/comments.py b/plone/app/discussion/browser/comments.py index 8993303..5376875 100644 --- a/plone/app/discussion/browser/comments.py +++ b/plone/app/discussion/browser/comments.py @@ -328,18 +328,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() diff --git a/plone/app/discussion/browser/configure.zcml b/plone/app/discussion/browser/configure.zcml index facb643..427395d 100644 --- a/plone/app/discussion/browser/configure.zcml +++ b/plone/app/discussion/browser/configure.zcml @@ -88,7 +88,7 @@ name="moderate-delete-comment" layer="..interfaces.IDiscussionLayer" class=".moderation.DeleteComment" - permission="zope2.DeleteObjects" + permission="plone.app.discussion.DeleteComments" /> diff --git a/plone/app/discussion/browser/controlpanel.py b/plone/app/discussion/browser/controlpanel.py index 84ded37..822ca2b 100644 --- a/plone/app/discussion/browser/controlpanel.py +++ b/plone/app/discussion/browser/controlpanel.py @@ -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 = \ diff --git a/plone/app/discussion/browser/moderation.py b/plone/app/discussion/browser/moderation.py index ea92515..84748f7 100644 --- a/plone/app/discussion/browser/moderation.py +++ b/plone/app/discussion/browser/moderation.py @@ -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. diff --git a/plone/app/discussion/interfaces.py b/plone/app/discussion/interfaces.py index 5a6cc8d..a807580 100644 --- a/plone/app/discussion/interfaces.py +++ b/plone/app/discussion/interfaces.py @@ -254,17 +254,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"), diff --git a/plone/app/discussion/permissions.zcml b/plone/app/discussion/permissions.zcml index dd71e63..97c6782 100644 --- a/plone/app/discussion/permissions.zcml +++ b/plone/app/discussion/permissions.zcml @@ -14,5 +14,9 @@ title="Edit comments" /> + diff --git a/plone/app/discussion/profiles/default/rolemap.xml b/plone/app/discussion/profiles/default/rolemap.xml index 8e8b019..83a67fc 100644 --- a/plone/app/discussion/profiles/default/rolemap.xml +++ b/plone/app/discussion/profiles/default/rolemap.xml @@ -3,15 +3,20 @@ - + - + + + + + + diff --git a/plone/app/discussion/testing.py b/plone/app/discussion/testing.py index e7a397d..90f08f9 100644 --- a/plone/app/discussion/testing.py +++ b/plone/app/discussion/testing.py @@ -34,6 +34,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 @@ -66,7 +68,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'}) diff --git a/plone/app/discussion/tests/functional_test_comments.txt b/plone/app/discussion/tests/functional_test_comments.txt index 9e7350c..c0d1159 100644 --- a/plone/app/discussion/tests/functional_test_comments.txt +++ b/plone/app/discussion/tests/functional_test_comments.txt @@ -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