Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions news/1066.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Respect "Access inactive portal content" permission in @search endpoint [cekk]
3 changes: 1 addition & 2 deletions src/plone/restapi/search/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,7 @@ def search(self, query=None):

self._constrain_query_by_path(query)
query = self._parse_query(query)

lazy_resultset = self.catalog.searchResults(query)
lazy_resultset = self.catalog.searchResults(**query)
results = getMultiAdapter((lazy_resultset, self.request), ISerializeToJson)(
fullobjects=fullobjects
)
Expand Down
77 changes: 77 additions & 0 deletions src/plone/restapi/tests/test_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@
import transaction
import unittest

try:
from Products.CMFPlone.factory import _IMREALLYPLONE5 # noqa
except ImportError:
PLONE5 = False
else:
PLONE5 = True


class TestSearchFunctional(unittest.TestCase):

Expand All @@ -37,10 +44,25 @@ def setUp(self):
self.api_session.headers.update({"Accept": "application/json"})
self.api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD)

api.user.create(
email="[email protected]",
username="editoruser",
password="secret",
)
api.user.create(
email="[email protected]",
username="localeditor",
password="secret",
)

# /plone/folder
self.folder = createContentInContainer(
self.portal, u"Folder", id=u"folder", title=u"Some Folder"
)
api.user.grant_roles(username="editoruser", roles=["Editor"])
api.user.grant_roles(
username="localeditor", obj=self.folder, roles=["Editor", "Reader"]
)

# /plone/folder/doc
self.doc = createContentInContainer(
Expand Down Expand Up @@ -587,6 +609,61 @@ def test_uuid_index_query(self):
response = self.api_session.get("/@search", params=query)
self.assertEqual([u"/plone/folder/doc"], result_paths(response.json()))

@unittest.skipIf(
not PLONE5, "searchResults in Plone 4 does not handle correctly that permission"
)
def test_respect_access_inactive_permission(self):
# admin can see everything
response = self.api_session.get("/@search", params={}).json()
self.assertEqual(response["items_total"], 6)
response = self.api_session.get(
"/@search", params={"Title": "Lorem Ipsum"}
).json()
self.assertEqual(response["items_total"], 1)

# not admin users can't see expired items
self.api_session.auth = ("editoruser", "secret")

response = self.api_session.get("/@search", params={}).json()
self.assertEqual(response["items_total"], 3)
response = self.api_session.get(
"/@search", params={"Title": "Lorem Ipsum"}
).json()
self.assertEqual(response["items_total"], 0)

# now grant permission to Editor to access inactive content
self.portal.manage_permission(
"Access inactive portal content", roles=["Manager", "Editor"]
)
transaction.commit()

#  portal-enabled Editor can see expired contents
response = self.api_session.get("/@search", params={}).json()
self.assertEqual(response["items_total"], 6)
response = self.api_session.get(
"/@search", params={"Title": "Lorem Ipsum"}
).json()
self.assertEqual(response["items_total"], 1)

# local-enabled Editor can only access expired contents inside folder
self.api_session.auth = ("localeditor", "secret")
response = self.api_session.get("/@search", params={}).json()
self.assertEqual(response["items_total"], 1)
response = self.api_session.get(
"/@search", params={"path": "/plone/folder"}
).json()

self.assertEqual(response["items_total"], 3)
response = self.api_session.get(
"/@search", params={"Title": "Lorem Ipsum"}
).json()
self.assertEqual(response["items_total"], 0)
response = self.api_session.get(
"/@search",
params={"Title": "Lorem Ipsum", "path": "/plone/folder"},
).json()
self.assertEqual(response["items_total"], 1)


class TestSearchATFunctional(unittest.TestCase):
layer = PLONE_RESTAPI_AT_FUNCTIONAL_TESTING
Expand Down