Skip to content

Commit

Permalink
Do not expose private metadata via relationfield serializer.
Browse files Browse the repository at this point in the history
  • Loading branch information
maethu committed May 1, 2023
1 parent 537a0ff commit bceee96
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 3 deletions.
2 changes: 2 additions & 0 deletions news/1634.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Do not expose private metadata via relationfield serializer.
[maethu]
11 changes: 9 additions & 2 deletions src/plone/restapi/serializer/relationfield.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from plone import api
from plone.dexterity.interfaces import IDexterityContent
from plone.restapi.interfaces import IFieldSerializer
from plone.restapi.interfaces import IJsonCompatible
Expand All @@ -17,7 +18,8 @@
@adapter(IRelationValue)
@implementer(IJsonCompatible)
def relationvalue_converter(value):
if value.to_object:
mtool = api.portal.get_tool("portal_membership")
if value.to_object and mtool.checkPermission("View", value.to_object):
request = getRequest()
request.form["metadata_fields"] = ["UID"]
summary = getMultiAdapter((value.to_object, request), ISerializeToJsonSummary)()
Expand All @@ -33,4 +35,9 @@ class RelationChoiceFieldSerializer(DefaultFieldSerializer):
@adapter(IRelationList, IDexterityContent, Interface)
@implementer(IFieldSerializer)
class RelationListFieldSerializer(DefaultFieldSerializer):
pass
def __call__(self):
value = self.get_value()
if value:
return [item for item in json_compatible(value) if item]
else:
return super().__call__()
26 changes: 25 additions & 1 deletion src/plone/restapi/tests/test_content_get.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@


class TestContentGet(unittest.TestCase):

layer = PLONE_RESTAPI_DX_FUNCTIONAL_TESTING

def setUp(self):
Expand Down Expand Up @@ -137,6 +136,31 @@ def test_get_content_includes_related_items(self):
response.json()["relatedItems"],
)

def test_get_content_includes_related_items_filtered_by_view_permission(self):
intids = getUtility(IIntIds)
self.portal.folder1.doc1.relatedItems = [
RelationValue(intids.getId(self.portal.folder1.folder2.doc2)),
]

# Remove view permission
self.portal.folder1.folder2.doc2.manage_permission(
"View", roles=[], acquire=False
)
self.portal.folder1.folder2.doc2.reindexObjectSecurity()
transaction.commit()

response = requests.get(
self.portal.folder1.doc1.absolute_url(),
headers={"Accept": "application/json"},
auth=(SITE_OWNER_NAME, SITE_OWNER_PASSWORD),
)
self.assertEqual(response.status_code, 200)
self.assertEqual(0, len(response.json()["relatedItems"]))
self.assertEqual(
[],
response.json()["relatedItems"],
)

def test_get_content_related_items_without_workflow(self):
intids = getUtility(IIntIds)

Expand Down

0 comments on commit bceee96

Please sign in to comment.