Skip to content

Commit bceee96

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

File tree

3 files changed

+36
-3
lines changed

3 files changed

+36
-3
lines changed

news/1634.bugfix

+2
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

+9-2
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

+25-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919

2020
class TestContentGet(unittest.TestCase):
21-
2221
layer = PLONE_RESTAPI_DX_FUNCTIONAL_TESTING
2322

2423
def setUp(self):
@@ -137,6 +136,31 @@ def test_get_content_includes_related_items(self):
137136
response.json()["relatedItems"],
138137
)
139138

139+
def test_get_content_includes_related_items_filtered_by_view_permission(self):
140+
intids = getUtility(IIntIds)
141+
self.portal.folder1.doc1.relatedItems = [
142+
RelationValue(intids.getId(self.portal.folder1.folder2.doc2)),
143+
]
144+
145+
# Remove view permission
146+
self.portal.folder1.folder2.doc2.manage_permission(
147+
"View", roles=[], acquire=False
148+
)
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(
160+
[],
161+
response.json()["relatedItems"],
162+
)
163+
140164
def test_get_content_related_items_without_workflow(self):
141165
intids = getUtility(IIntIds)
142166

0 commit comments

Comments
 (0)