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
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
matrix:
include:
- python-version: "3.13"
plone-version: "6.2"
plone-version: "6.1"
steps:
# git checkout
- uses: actions/checkout@v5
Expand Down
2 changes: 2 additions & 0 deletions news/2041.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix the security check when a wrong permission is specified.
@ale-rt
14 changes: 13 additions & 1 deletion src/plone/restapi/serializer/schema.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from AccessControl import getSecurityManager
from logging import getLogger
from plone.autoform.interfaces import READ_PERMISSIONS_KEY
from plone.restapi.interfaces import IFieldSerializer
from plone.restapi.interfaces import ISchemaSerializer
Expand All @@ -14,6 +15,9 @@
from zope.security.interfaces import IPermission


logger = getLogger(__name__)


@adapter(IInterface, Interface, Interface)
@implementer(ISchemaSerializer)
class SerializeSchemaToJson:
Expand Down Expand Up @@ -53,7 +57,15 @@ def _check_permission(permission_name, instance, obj=None) -> bool:
if permission_name not in permission_cache:
permission = queryUtility(IPermission, name=permission_name)
if permission is None:
permission_cache[permission_name] = True
logger.warning(
(
"The permission %r was not found, forbidding access. "
"Be sure to specify a properly registered permission id, "
"e.g. zope2.View"
),
permission_name,
)
permission_cache[permission_name] = False
else:
sm = getSecurityManager()
permission_cache[permission_name] = bool(
Expand Down
2 changes: 1 addition & 1 deletion src/plone/restapi/services/inherit/get.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def __call__(self, expand=False):
obj
for obj in self.context.aq_chain
if registration.marker.providedBy(obj)
and _check_permission("View", self, obj)
and _check_permission("zope2.View", self, obj)
),
None,
)
Expand Down
72 changes: 36 additions & 36 deletions src/plone/restapi/tests/http-examples/querystring_get.resp

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,6 @@ Content-Type: application/json
"upgrade_info": {},
"version": "1.2.3"
},
{
"@id": "http://localhost:55001/plone/@addons/plone.app.layout",
"description": "Installs the plone.app.layout add-on.",
"id": "plone.app.layout",
"install_profile_id": "plone.app.layout:default",
"is_installed": false,
"profile_type": "default",
"title": "plone.app.layout",
"uninstall_profile_id": "plone.app.layout:uninstall",
"upgrade_info": {},
"version": "1.2.3"
},
{
"@id": "http://localhost:55001/plone/@addons/plone.app.multilingual",
"description": "Instalar para activar el soporte de contenido multiling\u00fce con plone.app.multilingual",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ Content-Type: application/json+schema
"behavior": "plone.dublincore",
"description": "Usado en listados de elementos y resultados de b\u00fasquedas.",
"factory": "Text",
"maxLength": 10000,
"title": "Descripci\u00f3n",
"type": "string",
"widget": "textarea"
Expand Down Expand Up @@ -251,6 +252,7 @@ Content-Type: application/json+schema
"behavior": "plone.dublincore",
"description": "",
"factory": "Text line (String)",
"maxLength": 1024,
"title": "T\u00edtulo",
"type": "string"
}
Expand Down
2 changes: 2 additions & 0 deletions src/plone/restapi/tests/http-examples/types_document.resp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ Content-Type: application/json+schema
"behavior": "plone.dublincore",
"description": "Used in item listings and search results.",
"factory": "Text",
"maxLength": 10000,
"title": "Summary",
"type": "string",
"widget": "textarea"
Expand Down Expand Up @@ -279,6 +280,7 @@ Content-Type: application/json+schema
"behavior": "plone.dublincore",
"description": "",
"factory": "Text line (String)",
"maxLength": 1024,
"title": "Title",
"type": "string"
},
Expand Down
2 changes: 2 additions & 0 deletions src/plone/restapi/tests/http-examples/types_document_put.req
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ Content-Type: application/json
"behavior": "plone.dublincore",
"description": "Used in item listings and search results.",
"factory": "Text",
"maxLength": 10000,
"title": "Summary",
"type": "string",
"widget": "textarea"
Expand Down Expand Up @@ -244,6 +245,7 @@ Content-Type: application/json
"behavior": "plone.dublincore",
"description": "",
"factory": "Text line (String)",
"maxLength": 1024,
"title": "Title",
"type": "string"
},
Expand Down
14 changes: 13 additions & 1 deletion src/plone/restapi/tests/test_services_inherit.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,15 +180,27 @@ def test_inherit_permissions(self):
title="Restricted Child",
)
alsoProvides(restricted_parent, ITestBehaviorMarker)
api.content.transition(restricted_child, to_state="published")
transaction.commit()

logout()
anon_session = RelativeSession(self.portal.absolute_url())
anon_session.headers.update({"Accept": "application/json"})

# Anonymous is allowed to view the child, as it is published.
url = f"{restricted_child.absolute_url()}"
response = anon_session.get(url)
self.assertEqual(response.status_code, 200)

# Anonymous is also allowed to request an inherited behavior on the
# published child.
url = f"{restricted_child.absolute_url()}/@inherit?expand.inherit.behaviors=plone.testbehavior.ITestBehavior"
response = anon_session.get(url)
self.assertEqual(response.status_code, 401)
self.assertEqual(response.status_code, 200)

# But no data of the parent is exposed, as the parent is private.
data = response.json()
self.assertEqual(sorted(data.keys()), ["@id"])

def test_inherit_expansion(self):
response = self.api_session.get(
Expand Down
6 changes: 3 additions & 3 deletions test-no-uncommitted-doc-changes
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ function red {
echo "$RED $1 $RESET"
}

if [ "$PLONE_VERSION" == "6.2" ] && [ "$PYTHON_VERSION" == '3.13' ]; then
echo "Running check for undocumented changes for Plone 6.2.x on Python 3.13"
if [ "$PLONE_VERSION" == "6.1" ] && [ "$PYTHON_VERSION" == '3.13' ]; then
echo "Running check for undocumented changes for Plone 6.1.x on Python 3.13"
else
# request/response dumps have known differences for different Python/Plone combinations
# => skip, we can't have the Plone 5 build fail because of those
echo "Skipping checks for undocumented changes for everything except Plone 6.2.x on Python 3.13"
echo "Skipping checks for undocumented changes for everything except Plone 6.1.x on Python 3.13"
echo "PLONE_VERSION=$PLONE_VERSION"
echo "PYTHON_VERSION=$PYTHON_VERSION"
exit 0
Expand Down
Loading