Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
slapos
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
106
Merge Requests
106
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
nexedi
slapos
Commits
96a51134
Commit
96a51134
authored
Sep 25, 2024
by
Jérome Perrin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
stack/erp5: backport AccessControl PR for Unauthorized on __getattr__
parent
2a015f1d
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
182 additions
and
1 deletion
+182
-1
component/egg-patch/AccessControl/157.patch
component/egg-patch/AccessControl/157.patch
+122
-0
component/egg-patch/Products.MimetypesRegistry/40.patch
component/egg-patch/Products.MimetypesRegistry/40.patch
+57
-0
stack/erp5/buildout.cfg
stack/erp5/buildout.cfg
+3
-1
No files found.
component/egg-patch/AccessControl/157.patch
0 → 100644
View file @
96a51134
From 27d88c40e251b370f4dd2fcc7ae03c2967c68e4c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9rome=20Perrin?= <jerome@nexedi.com>
Date: Mon, 2 Sep 2024 04:41:13 +0000
Subject: [PATCH] checkPermission: align behavior with objects raising in
__getattr__
The observed problem was a behavior different between C and python
implementation on python 3, happening with Zope python script. When the
context can not be accessed by the current user, Zope binds a
`Shared.DC.Scripts.Bindings.UnauthorizedBinding`,
a class that raises an
Unauthorized error when the context is actually accessed, in order to
postpone the Unauthorized if something is actually accessed. This class
does implements this by raising Unauthorized in __getattr__.
The python implementation of `checkPermission` uses `hasattr` and
`hasattr`
has changed between python2 and python3, on python2 it was
ignoring all exceptions, including potential Unauthorized errors and
just returning False, but on python3 these errors are raised.
This change of behavior of python causes checkPermission to behave
differently: when using python implementation on python2 or when using
C implementation, such Unauthorized errors were gracefully handled and
caused checkPermission to return False, but on python3 checkPermission
raises.
This change make this scenario behave the same between python2, python3
and C implementation: Unauthorized errors raised in __getattr__ are
supported. The code is also micro-simplified by doing only one getattr
instead of hasattr and then getattr.
---
src/AccessControl/ImplPython.py | 6 +++++-
src/AccessControl/cAccessControl.c | 7 +++++--
src/AccessControl/tests/testZopeSecurityPolicy.py | 15 +++++++++++++++
4 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/src/AccessControl/ImplPython.py b/src/AccessControl/ImplPython.py
index 1a7788b..0a9326b 100644
--- a/src/AccessControl/ImplPython.py
+++ b/src/AccessControl/ImplPython.py
@@ -31,6 +31,7 @@
from Acquisition import aq_parent
from ExtensionClass import Base
from zope.interface import implementer
+from zExceptions import Unauthorized as zExceptions_Unauthorized
PURE_PYTHON = int(os.environ.get('PURE_PYTHON', '0'))
if PURE_PYTHON:
@@ -71,8 +72,11 @@
def rolesForPermissionOn(perm, object, default=_default_roles, n=None):
r = None
while True:
- if hasattr(object, n):
+ try:
roles = getattr(object, n)
+ except (AttributeError, zExceptions_Unauthorized):
+ pass
+ else:
if roles is None:
if _embed_permission_in_roles:
return (('Anonymous',), n)
diff --git a/src/AccessControl/cAccessControl.c b/src/AccessControl/cAccessControl.c
index 403ed67..1a109fa 100644
--- a/src/AccessControl/cAccessControl.c
+++ b/src/AccessControl/cAccessControl.c
@@ -1847,13 +1847,16 @@
c_rolesForPermissionOn(PyObject *perm, PyObject *object,
Py_INCREF(r);
/*
- while 1:
+ while True:
*/
while (1)
{
/*
- if hasattr(object, n):
+ try:
roles = getattr(object, n)
+ except (AttributeError, zExceptions_Unauthorized):
+ pass
+ else:
*/
PyObject *roles = PyObject_GetAttr(object, n);
if (roles != NULL)
diff --git a/src/AccessControl/tests/testZopeSecurityPolicy.py b/src/AccessControl/tests/testZopeSecurityPolicy.py
index 9b12a0f..ee74bad 100644
--- a/src/AccessControl/tests/testZopeSecurityPolicy.py
+++ b/src/AccessControl/tests/testZopeSecurityPolicy.py
@@ -157,6 +157,15 @@
class PartlyProtectedSimpleItem3 (PartlyProtectedSimpleItem1):
__roles__ = sysadmin_roles
+class DynamicallyUnauthorized(SimpleItemish):
+ # This class raises an Unauthorized on attribute access,
+ # similar to Zope's Shared.DC.Scripts.Bindings.UnauthorizedBinding
+ __ac_local_roles__ = {}
+
+ def __getattr__(self, name):
+ raise Unauthorized('Not authorized to access: %s' % name)
+
+
class SimpleClass:
attr = 1
@@ -173,6 +182,7 @@
def setUp(self):
a.item1 = PartlyProtectedSimpleItem1()
a.item2 = PartlyProtectedSimpleItem2()
a.item3 = PartlyProtectedSimpleItem3()
+ a.d_item = DynamicallyUnauthorized()
uf = UserFolder()
a.acl_users = uf
self.uf = a.acl_users
@@ -351,6 +361,11 @@
def test_checkPermission_proxy_role_scope(self):
r_subitem,
context))
+ def test_checkPermission_dynamically_unauthorized(self):
+ d_item = self.a.d_item
+ context = self.context
+ self.assertFalse(self.policy.checkPermission('View', d_item, context))
+
def testUnicodeRolesForPermission(self):
r_item = self.a.r_item
context = self.context
component/egg-patch/Products.MimetypesRegistry/40.patch
0 → 100644
View file @
96a51134
From 94785bb0ef91fd69b802b904b6037bc027f9b5b4 Mon Sep 17 00:00:00 2001
From: Kazuhiko SHIOZAKI <kazuhiko@nexedi.com>
Date: Mon, 16 Sep 2024 09:48:40 +0200
Subject: [PATCH] Fix classify() for magic classifier and binary data.
---
Products/MimetypesRegistry/MimeTypesRegistry.py | 3 ++-
Products/MimetypesRegistry/tests/test_mimetypes.py | 8 ++++++++
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/Products/MimetypesRegistry/MimeTypesRegistry.py b/Products/MimetypesRegistry/MimeTypesRegistry.py
index 1f5c4b5..ad480c3 100644
--- a/Products/MimetypesRegistry/MimeTypesRegistry.py
+++ b/Products/MimetypesRegistry/MimeTypesRegistry.py
@@ -303,6 +303,8 @@
def classify(self, data, mimetype=None, filename=None):
if mt is None:
mt = self.globFilename(filename)
if data and not mt:
+ if isinstance(data, str):
+ data = data.encode()
for c in self._classifiers():
if c.classify(data):
mt = c
@@ -322,7 +324,6 @@
def classify(self, data, mimetype=None, filename=None):
failed = "text/x-unknown-content-type"
filename = filename or ""
data = data or ""
- data = data.encode()
ct, enc = guess_content_type(filename, data, None)
if ct == failed:
ct = "text/plain"
diff --git a/Products/MimetypesRegistry/tests/test_mimetypes.py b/Products/MimetypesRegistry/tests/test_mimetypes.py
index 1f55056..1fb75a7 100644
--- a/Products/MimetypesRegistry/tests/test_mimetypes.py
+++ b/Products/MimetypesRegistry/tests/test_mimetypes.py
@@ -58,6 +58,10 @@
def testClassify(self):
mt = reg.classify("<?xml ?>")
self.assertTrue(isinstance(mt, text_xml), str(mt))
+ # test magic classifiers
+ mt = reg.classify("BEGIN:VCARD\n")
+ self.assertEqual(str(mt), "text/vcard")
+
# test no data return default
mt = reg.classify("")
self.assertTrue(isinstance(mt, text_plain), str(mt))
@@ -73,6 +77,10 @@
def testClassify(self):
mt = reg.classify("baz", filename="xxx")
self.assertTrue(isinstance(mt, application_octet_stream), str(mt))
+ # test unclassifiable binary data
+ mt = reg.classify(b"\x01")
+ self.assertTrue(isinstance(mt, application_octet_stream), str(mt))
+
def testExtension(self):
reg = self.registry
data = "<foo>bar</foo>"
stack/erp5/buildout.cfg
View file @
96a51134
...
@@ -662,6 +662,8 @@ SOAPpy-py3-patches = ${:_profile_base_location_}/../../component/egg-patch/SOAPp
...
@@ -662,6 +662,8 @@ SOAPpy-py3-patches = ${:_profile_base_location_}/../../component/egg-patch/SOAPp
SOAPpy-py3-patch-options = -p1
SOAPpy-py3-patch-options = -p1
[eggs:python3]
[eggs:python3]
AccessControl-patches = ${:_profile_base_location_}/../../component/egg-patch/AccessControl/157.patch#9b01341bd4271555c9caa66cb9d0f098
AccessControl-patch-options = -p1
interval-patches = ${:_profile_base_location_}/../../component/egg-patch/interval/0001-python3-support.patch#66ac345f0a6d73e0bd29e394b7646311
interval-patches = ${:_profile_base_location_}/../../component/egg-patch/interval/0001-python3-support.patch#66ac345f0a6d73e0bd29e394b7646311
interval-patch-options = -p1
interval-patch-options = -p1
Products.DCWorkflow-patches = ${:_profile_base_location_}/../../component/egg-patch/Products.DCWorkflow/workflow_method-3.0.0.patch#4cc8607213b1ef08331366d9873becaa
Products.DCWorkflow-patches = ${:_profile_base_location_}/../../component/egg-patch/Products.DCWorkflow/workflow_method-3.0.0.patch#4cc8607213b1ef08331366d9873becaa
...
@@ -751,6 +753,7 @@ depends =
...
@@ -751,6 +753,7 @@ depends =
# neoppod, mysqlclient, slapos.recipe.template
# neoppod, mysqlclient, slapos.recipe.template
# patched eggs
# patched eggs
AccessControl = 7.0+SlapOSPatched001
Acquisition = 5.2+SlapOSPatched001
Acquisition = 5.2+SlapOSPatched001
PyPDF2 = 1.26.0+SlapOSPatched002
PyPDF2 = 1.26.0+SlapOSPatched002
pysvn = 1.9.15+SlapOSPatched001
pysvn = 1.9.15+SlapOSPatched001
...
@@ -887,7 +890,6 @@ zope.session = 4.5
...
@@ -887,7 +890,6 @@ zope.session = 4.5
# temporary versions, until updated in zope-versions.cfg
# temporary versions, until updated in zope-versions.cfg
[versions]
[versions]
AccessControl = 7.0
DateTime = 5.5
DateTime = 5.5
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment