Skip to content

Commit a80b337

Browse files
razvanMiuavoinea
andauthored
Added 'View comments' and 'Reply to item' permission to discussion (#1327)
* Added 'View comments' and 'Reply to item' permission to discussion * Changelog * Black format * Use permissions from plone.app.discussion for discussion endpoints * Revert use of permissions from plone.app.discussion * Update tests * Update tests * Update tests * Use permissions from plone.app.discussion for update and delete Co-authored-by: Alin Voinea <contact@avoinea.com>
1 parent dbc4766 commit a80b337

7 files changed

Lines changed: 43 additions & 9 deletions

File tree

news/1327.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Added 'View comments' and 'Reply to item' permission to discussion [@razvanMiu]

src/plone/restapi/serializer/discussion.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
from plone.restapi.interfaces import ISerializeToJson
66
from plone.restapi.services.discussion.utils import can_delete
77
from plone.restapi.services.discussion.utils import can_delete_own
8+
from plone.restapi.services.discussion.utils import can_view
89
from plone.restapi.services.discussion.utils import can_edit
10+
from plone.restapi.services.discussion.utils import can_reply
911
from plone.restapi.services.discussion.utils import delete_own_comment_allowed
1012
from plone.restapi.services.discussion.utils import edit_comment_allowed
1113
from Products.CMFCore.utils import getToolByName
@@ -24,20 +26,29 @@ def __init__(self, context, request):
2426

2527
def __call__(self):
2628
# We'll batch the threads
29+
view_comments = can_view(self.context)
2730
results = list(self.context.getThreads())
2831
batch = HypermediaBatch(self.request, results)
2932

3033
results = {}
3134
results["@id"] = batch.canonical_url
3235

3336
results["items_total"] = batch.items_total
37+
results["permissions"] = {
38+
"view_comments": view_comments,
39+
"can_reply": can_reply(self.context),
40+
}
3441
if batch.links:
3542
results["batching"] = batch.links
3643

37-
results["items"] = [
38-
getMultiAdapter((thread["comment"], self.request), ISerializeToJson)()
39-
for thread in batch
40-
]
44+
results["items"] = (
45+
[
46+
getMultiAdapter((thread["comment"], self.request), ISerializeToJson)()
47+
for thread in batch
48+
]
49+
if view_comments
50+
else []
51+
)
4152

4253
return results
4354

@@ -87,6 +98,7 @@ def __call__(self, include_items=True):
8798
), # noqa
8899
"is_editable": edit_comment_allowed() and can_edit(self.context),
89100
"is_deletable": can_delete(self.context) or delete_own,
101+
"can_reply": can_reply(self.context),
90102
}
91103

92104
def get_author_image(self, username=None):

src/plone/restapi/services/discussion/configure.zcml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,15 @@
3535
method="PATCH"
3636
factory=".conversation.CommentsUpdate"
3737
for="*"
38-
permission="zope2.View"
38+
permission="plone.app.discussion.EditComments"
3939
name="@comments"
4040
/>
4141

4242
<plone:service
4343
method="DELETE"
4444
factory=".conversation.CommentsDelete"
4545
for="*"
46-
permission="zope2.View"
46+
permission="plone.app.discussion.DeleteComments"
4747
name="@comments"
4848
/>
4949

src/plone/restapi/services/discussion/utils.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,27 @@ def permission_exists(permission_id):
2828
return permission is not None
2929

3030

31+
def can_view(context):
32+
"""Returns true if current user has the 'View comments' permission."""
33+
if not permission_exists("plone.app.discussion.ViewComments"):
34+
return bool(getSecurityManager().checkPermission("View", context))
35+
return bool(getSecurityManager().checkPermission("View comments", context))
36+
37+
3138
def can_review(comment):
3239
"""Returns true if current user has the 'Review comments' permission."""
3340
return bool(
3441
getSecurityManager().checkPermission("Review comments", aq_inner(comment))
3542
)
3643

3744

45+
def can_reply(comment):
46+
"""Returns true if current user has the 'Reply to item' permission."""
47+
return bool(
48+
getSecurityManager().checkPermission("Reply to item", aq_inner(comment))
49+
)
50+
51+
3852
def can_delete(comment):
3953
"""Returns true if current user has the 'Delete comments'
4054
permission.

src/plone/restapi/tests/http-examples/comments_get.resp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Content-Type: application/json
1111
"author_image": null,
1212
"author_name": null,
1313
"author_username": null,
14+
"can_reply": true,
1415
"comment_id": "1400000000000000",
1516
"creation_date": "1995-07-31T13:45:00",
1617
"in_reply_to": null,
@@ -30,6 +31,7 @@ Content-Type: application/json
3031
"author_image": null,
3132
"author_name": null,
3233
"author_username": null,
34+
"can_reply": true,
3335
"comment_id": "1400000000000001",
3436
"creation_date": "1995-07-31T13:45:00",
3537
"in_reply_to": "1400000000000000",
@@ -43,5 +45,9 @@ Content-Type: application/json
4345
"user_notification": null
4446
}
4547
],
46-
"items_total": 2
48+
"items_total": 2,
49+
"permissions": {
50+
"can_reply": true,
51+
"view_comments": true
52+
}
4753
}

src/plone/restapi/tests/test_comments.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def test_conversation(self):
5757
)
5858

5959
output = serializer()
60-
self.assertEqual(set(output), {"@id", "items_total", "items"})
60+
self.assertEqual(set(output), {"@id", "permissions", "items_total", "items"})
6161

6262
def test_conversation_batched(self):
6363
self.request.form["b_size"] = 1
@@ -88,6 +88,7 @@ def test_comment(self):
8888
"modification_date",
8989
"is_editable",
9090
"is_deletable",
91+
"can_reply",
9192
]
9293
self.assertEqual(set(output), set(expected))
9394

src/plone/restapi/tests/test_services_comments.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def test_list_datastructure(self):
6262

6363
self.assertEqual(200, response.status_code)
6464
data = response.json()
65-
self.assertEqual({"items_total", "items", "@id"}, set(data))
65+
self.assertEqual({"items_total", "items", "permissions", "@id"}, set(data))
6666

6767
def test_list_batching(self):
6868
url = f"{self.doc.absolute_url()}/@comments"

0 commit comments

Comments
 (0)