Skip to content

Commit 66027a5

Browse files
committed
Do not expose private metadata via relationfield serializer.
1 parent 537a0ff commit 66027a5

File tree

3 files changed

+33
-2
lines changed

3 files changed

+33
-2
lines changed

news/1634.bugfix

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Do not expose private metadata via relationfield serializer.
2+
[maethu]

src/plone/restapi/serializer/relationfield.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from plone import api
12
from plone.dexterity.interfaces import IDexterityContent
23
from plone.restapi.interfaces import IFieldSerializer
34
from plone.restapi.interfaces import IJsonCompatible
@@ -17,7 +18,8 @@
1718
@adapter(IRelationValue)
1819
@implementer(IJsonCompatible)
1920
def relationvalue_converter(value):
20-
if value.to_object:
21+
mtool = api.portal.get_tool('portal_membership')
22+
if value.to_object and mtool.checkPermission('View', value.to_object):
2123
request = getRequest()
2224
request.form["metadata_fields"] = ["UID"]
2325
summary = getMultiAdapter((value.to_object, request), ISerializeToJsonSummary)()
@@ -33,4 +35,9 @@ class RelationChoiceFieldSerializer(DefaultFieldSerializer):
3335
@adapter(IRelationList, IDexterityContent, Interface)
3436
@implementer(IFieldSerializer)
3537
class RelationListFieldSerializer(DefaultFieldSerializer):
36-
pass
38+
def __call__(self):
39+
value = self.get_value()
40+
if value:
41+
return [item for item in json_compatible(value) if item]
42+
else:
43+
return super().__call__()

src/plone/restapi/tests/test_content_get.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,28 @@ def test_get_content_includes_related_items(self):
137137
response.json()["relatedItems"],
138138
)
139139

140+
def test_get_content_includes_related_items_filtered_by_view_permission(self):
141+
intids = getUtility(IIntIds)
142+
self.portal.folder1.doc1.relatedItems = [
143+
RelationValue(intids.getId(self.portal.folder1.folder2.doc2)),
144+
]
145+
146+
# Remove view permission
147+
self.portal.folder1.folder2.doc2.manage_permission(
148+
"View", roles=[], acquire=False)
149+
self.portal.folder1.folder2.doc2.reindexObjectSecurity()
150+
transaction.commit()
151+
152+
response = requests.get(
153+
self.portal.folder1.doc1.absolute_url(),
154+
headers={"Accept": "application/json"},
155+
auth=(SITE_OWNER_NAME, SITE_OWNER_PASSWORD),
156+
)
157+
self.assertEqual(response.status_code, 200)
158+
self.assertEqual(0, len(response.json()["relatedItems"]))
159+
self.assertEqual([], response.json()["relatedItems"],
160+
)
161+
140162
def test_get_content_related_items_without_workflow(self):
141163
intids = getUtility(IIntIds)
142164

0 commit comments

Comments
 (0)