AccessControl 7.0__tar.gz → 7.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {AccessControl-7.0 → accesscontrol-7.2}/.manylinux-install.sh +7 -12
- accesscontrol-7.2/.pre-commit-config.yaml +28 -0
- {AccessControl-7.0 → accesscontrol-7.2}/CHANGES.rst +22 -0
- {AccessControl-7.0 → accesscontrol-7.2}/MANIFEST.in +1 -1
- {AccessControl-7.0 → accesscontrol-7.2}/PKG-INFO +26 -4
- accesscontrol-7.2/pyproject.toml +25 -0
- {AccessControl-7.0 → accesscontrol-7.2}/setup.py +4 -4
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/ImplPython.py +5 -1
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/SecurityInfo.py +2 -2
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/ZopeGuards.py +1 -1
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/cAccessControl.c +24 -2
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/tests/testClassSecurityInfo.py +5 -5
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/tests/testModuleSecurity.py +2 -2
- accesscontrol-7.2/src/AccessControl/tests/testPermissionRole.py +170 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/tests/testSecurityManager.py +28 -27
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/tests/testZopeGuards.py +1 -1
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/tests/testZopeSecurityPolicy.py +18 -2
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/tests/test_tainted.py +75 -57
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/tests/test_userfolder.py +1 -1
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/userfolder.py +1 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/users.py +1 -1
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl.egg-info/PKG-INFO +26 -4
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl.egg-info/SOURCES.txt +2 -1
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl.egg-info/requires.txt +1 -4
- {AccessControl-7.0 → accesscontrol-7.2}/tox.ini +14 -20
- AccessControl-7.0/.coveragerc +0 -30
- AccessControl-7.0/src/AccessControl/tests/testPermissionRole.py +0 -129
- {AccessControl-7.0 → accesscontrol-7.2}/.manylinux.sh +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/CONTRIBUTING.md +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/COPYRIGHT.txt +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/HISTORY.rst +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/LICENSE.txt +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/README.rst +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/buildout.cfg +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/docs/AccessControl.rst +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/docs/requestmethod.rst +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/include/Acquisition/Acquisition.h +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/include/ExtensionClass/ExtensionClass.h +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/include/ExtensionClass/_compat.h +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/setup.cfg +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/AuthEncoding.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/ImplC.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/Implementation.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/Owned.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/Permission.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/PermissionMapping.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/PermissionRole.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/Permissions.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/Role.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/SecurityManagement.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/SecurityManager.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/SimpleObjectPolicies.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/SpecialUsers.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/User.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/ZopeSecurityPolicy.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/__init__.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/_compat.h +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/class_init.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/configure.zcml +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/interfaces.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/logger_wrapper.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/meta.zcml +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/metaconfigure.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/owner.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/permissions.zcml +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/requestmethod.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/rolemanager.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/safe_formatter.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/security.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/tainted.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/tests/__init__.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/tests/actual_python.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/tests/mixed_module/__init__.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/tests/mixed_module/submodule/__init__.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/tests/private_module/__init__.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/tests/private_module/submodule/__init__.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/tests/public_module/__init__.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/tests/public_module/submodule/__init__.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/tests/testImplementation.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/tests/testPermissionMapping.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/tests/testZCML.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/tests/test_owner.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/tests/test_requestmethod.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/tests/test_rolemanager.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/tests/test_safe_formatter.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/tests/test_safeiter.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/tests/test_users.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl/unauthorized.py +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl.egg-info/dependency_links.txt +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl.egg-info/entry_points.txt +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl.egg-info/not-zip-safe +0 -0
- {AccessControl-7.0 → accesscontrol-7.2}/src/AccessControl.egg-info/top_level.txt +0 -0
|
@@ -28,12 +28,12 @@ yum -y install libffi-devel
|
|
|
28
28
|
|
|
29
29
|
tox_env_map() {
|
|
30
30
|
case $1 in
|
|
31
|
-
*"cp313"*) echo 'py313';;
|
|
32
31
|
*"cp38"*) echo 'py38';;
|
|
33
32
|
*"cp39"*) echo 'py39';;
|
|
34
33
|
*"cp310"*) echo 'py310';;
|
|
35
34
|
*"cp311"*) echo 'py311';;
|
|
36
35
|
*"cp312"*) echo 'py312';;
|
|
36
|
+
*"cp313"*) echo 'py313';;
|
|
37
37
|
*) echo 'py';;
|
|
38
38
|
esac
|
|
39
39
|
}
|
|
@@ -41,19 +41,14 @@ tox_env_map() {
|
|
|
41
41
|
# Compile wheels
|
|
42
42
|
for PYBIN in /opt/python/*/bin; do
|
|
43
43
|
if \
|
|
44
|
-
[[ "${PYBIN}" == *"cp313/"* ]] || \
|
|
45
|
-
[[ "${PYBIN}" == *"cp311/"* ]] || \
|
|
46
|
-
[[ "${PYBIN}" == *"cp312/"* ]] || \
|
|
47
44
|
[[ "${PYBIN}" == *"cp38/"* ]] || \
|
|
48
45
|
[[ "${PYBIN}" == *"cp39/"* ]] || \
|
|
49
|
-
[[ "${PYBIN}" == *"cp310/"* ]]
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
"${PYBIN}/pip" wheel /io/ -w wheelhouse/
|
|
56
|
-
fi
|
|
46
|
+
[[ "${PYBIN}" == *"cp310/"* ]] || \
|
|
47
|
+
[[ "${PYBIN}" == *"cp311/"* ]] || \
|
|
48
|
+
[[ "${PYBIN}" == *"cp312/"* ]] || \
|
|
49
|
+
[[ "${PYBIN}" == *"cp313/"* ]] ; then
|
|
50
|
+
"${PYBIN}/pip" install -e /io/
|
|
51
|
+
"${PYBIN}/pip" wheel /io/ -w wheelhouse/
|
|
57
52
|
if [ `uname -m` == 'aarch64' ]; then
|
|
58
53
|
cd /io/
|
|
59
54
|
${PYBIN}/pip install tox
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Generated from:
|
|
2
|
+
# https://github.com/zopefoundation/meta/tree/master/config/c-code
|
|
3
|
+
minimum_pre_commit_version: '3.6'
|
|
4
|
+
repos:
|
|
5
|
+
- repo: https://github.com/pycqa/isort
|
|
6
|
+
rev: "5.13.2"
|
|
7
|
+
hooks:
|
|
8
|
+
- id: isort
|
|
9
|
+
- repo: https://github.com/hhatto/autopep8
|
|
10
|
+
rev: "v2.3.1"
|
|
11
|
+
hooks:
|
|
12
|
+
- id: autopep8
|
|
13
|
+
args: [--in-place, --aggressive, --aggressive]
|
|
14
|
+
- repo: https://github.com/asottile/pyupgrade
|
|
15
|
+
rev: v3.17.0
|
|
16
|
+
hooks:
|
|
17
|
+
- id: pyupgrade
|
|
18
|
+
args: [--py38-plus]
|
|
19
|
+
- repo: https://github.com/isidentical/teyit
|
|
20
|
+
rev: 0.4.3
|
|
21
|
+
hooks:
|
|
22
|
+
- id: teyit
|
|
23
|
+
- repo: https://github.com/PyCQA/flake8
|
|
24
|
+
rev: "7.1.1"
|
|
25
|
+
hooks:
|
|
26
|
+
- id: flake8
|
|
27
|
+
additional_dependencies:
|
|
28
|
+
- flake8-debugger == 4.1.2
|
|
@@ -3,6 +3,28 @@ Changelog
|
|
|
3
3
|
|
|
4
4
|
For changes before version 3.0, see ``HISTORY.rst``.
|
|
5
5
|
|
|
6
|
+
7.2 (2024-11-03)
|
|
7
|
+
----------------
|
|
8
|
+
|
|
9
|
+
- Prevent untrusted access to ``AccessControl.userfolder.UserFolder.data``
|
|
10
|
+
(fixes `GHSA-g5vw-3h65-2q3v <https://github.com/zopefoundation/AccessControl/security/advisories/GHSA-g5vw-3h65-2q3v>`_).
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
7.1 (2024-10-10)
|
|
14
|
+
----------------
|
|
15
|
+
|
|
16
|
+
- Add final support for Python 3.13.
|
|
17
|
+
|
|
18
|
+
- Respect ``PURE_PYTHON`` environment variable set to ``0`` when running tests.
|
|
19
|
+
|
|
20
|
+
- Let the roles access in ``rolesForPermissionOn`` interpret ``AttributeError``
|
|
21
|
+
and ``Unauthorized`` as "no roles definition for this permission at this
|
|
22
|
+
object" and report any other exception (for the Python and C implementation).
|
|
23
|
+
We have to treat ``Unauthorized`` like ``AttributeError`` to support
|
|
24
|
+
``Shared.DC.Scripts.Bindings.UnauthorizedBinding`` which raises
|
|
25
|
+
``Unauthorized`` for any access.
|
|
26
|
+
|
|
27
|
+
|
|
6
28
|
7.0 (2024-05-30)
|
|
7
29
|
----------------
|
|
8
30
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: AccessControl
|
|
3
|
-
Version: 7.
|
|
3
|
+
Version: 7.2
|
|
4
4
|
Summary: Security framework for Zope.
|
|
5
5
|
Home-page: https://github.com/zopefoundation/AccessControl
|
|
6
6
|
Author: Zope Foundation and Contributors
|
|
7
|
-
Author-email: zope-dev@zope.
|
|
7
|
+
Author-email: zope-dev@zope.dev
|
|
8
8
|
License: ZPL 2.1
|
|
9
9
|
Project-URL: Issue Tracker, https://github.com/zopefoundation/AccessControl/issues
|
|
10
10
|
Project-URL: Sources, https://github.com/zopefoundation/AccessControl
|
|
@@ -25,6 +25,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
25
25
|
Classifier: Programming Language :: Python :: 3.13
|
|
26
26
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
27
27
|
Requires-Python: >=3.8
|
|
28
|
+
Description-Content-Type: text/x-rst
|
|
28
29
|
License-File: LICENSE.txt
|
|
29
30
|
Requires-Dist: Acquisition
|
|
30
31
|
Requires-Dist: AuthEncoding
|
|
@@ -32,7 +33,7 @@ Requires-Dist: BTrees
|
|
|
32
33
|
Requires-Dist: DateTime
|
|
33
34
|
Requires-Dist: ExtensionClass>=4.2.1
|
|
34
35
|
Requires-Dist: Persistence>=3.0a3
|
|
35
|
-
Requires-Dist: RestrictedPython>=
|
|
36
|
+
Requires-Dist: RestrictedPython>=7.4
|
|
36
37
|
Requires-Dist: transaction
|
|
37
38
|
Requires-Dist: zExceptions
|
|
38
39
|
Requires-Dist: zope.component
|
|
@@ -43,7 +44,6 @@ Requires-Dist: zope.publisher
|
|
|
43
44
|
Requires-Dist: zope.schema
|
|
44
45
|
Requires-Dist: zope.security
|
|
45
46
|
Requires-Dist: zope.testing
|
|
46
|
-
Requires-Dist: funcsigs; python_version < "3.3"
|
|
47
47
|
Provides-Extra: test
|
|
48
48
|
Requires-Dist: zope.testrunner; extra == "test"
|
|
49
49
|
|
|
@@ -73,6 +73,28 @@ Changelog
|
|
|
73
73
|
|
|
74
74
|
For changes before version 3.0, see ``HISTORY.rst``.
|
|
75
75
|
|
|
76
|
+
7.2 (2024-11-03)
|
|
77
|
+
----------------
|
|
78
|
+
|
|
79
|
+
- Prevent untrusted access to ``AccessControl.userfolder.UserFolder.data``
|
|
80
|
+
(fixes `GHSA-g5vw-3h65-2q3v <https://github.com/zopefoundation/AccessControl/security/advisories/GHSA-g5vw-3h65-2q3v>`_).
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
7.1 (2024-10-10)
|
|
84
|
+
----------------
|
|
85
|
+
|
|
86
|
+
- Add final support for Python 3.13.
|
|
87
|
+
|
|
88
|
+
- Respect ``PURE_PYTHON`` environment variable set to ``0`` when running tests.
|
|
89
|
+
|
|
90
|
+
- Let the roles access in ``rolesForPermissionOn`` interpret ``AttributeError``
|
|
91
|
+
and ``Unauthorized`` as "no roles definition for this permission at this
|
|
92
|
+
object" and report any other exception (for the Python and C implementation).
|
|
93
|
+
We have to treat ``Unauthorized`` like ``AttributeError`` to support
|
|
94
|
+
``Shared.DC.Scripts.Bindings.UnauthorizedBinding`` which raises
|
|
95
|
+
``Unauthorized`` for any access.
|
|
96
|
+
|
|
97
|
+
|
|
76
98
|
7.0 (2024-05-30)
|
|
77
99
|
----------------
|
|
78
100
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Generated from:
|
|
3
|
+
# https://github.com/zopefoundation/meta/tree/master/config/c-code
|
|
4
|
+
|
|
5
|
+
[build-system]
|
|
6
|
+
requires = ["setuptools<74"]
|
|
7
|
+
build-backend = "setuptools.build_meta"
|
|
8
|
+
|
|
9
|
+
[tool.coverage.run]
|
|
10
|
+
branch = true
|
|
11
|
+
source = ["AccessControl"]
|
|
12
|
+
relative_files = true
|
|
13
|
+
|
|
14
|
+
[tool.coverage.report]
|
|
15
|
+
fail_under = 80
|
|
16
|
+
precision = 2
|
|
17
|
+
ignore_errors = true
|
|
18
|
+
show_missing = true
|
|
19
|
+
exclude_lines = ["pragma: no cover", "pragma: nocover", "except ImportError:", "raise NotImplementedError", "if __name__ == '__main__':", "self.fail", "raise AssertionError", "raise unittest.Skip"]
|
|
20
|
+
|
|
21
|
+
[tool.coverage.html]
|
|
22
|
+
directory = "parts/htmlcov"
|
|
23
|
+
|
|
24
|
+
[tool.coverage.paths]
|
|
25
|
+
source = ["src/", ".tox/*/lib/python*/site-packages/", ".tox/pypy*/site-packages/"]
|
|
@@ -32,7 +32,7 @@ ext_modules = [
|
|
|
32
32
|
join('include', 'Acquisition', 'Acquisition.h')]),
|
|
33
33
|
]
|
|
34
34
|
|
|
35
|
-
version = '7.
|
|
35
|
+
version = '7.2'
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
setup(name='AccessControl',
|
|
@@ -47,8 +47,9 @@ setup(name='AccessControl',
|
|
|
47
47
|
description='Security framework for Zope.',
|
|
48
48
|
keywords='security access authorization',
|
|
49
49
|
author='Zope Foundation and Contributors',
|
|
50
|
-
author_email='zope-dev@zope.
|
|
50
|
+
author_email='zope-dev@zope.dev',
|
|
51
51
|
long_description=README + '\n\n' + CHANGES,
|
|
52
|
+
long_description_content_type='text/x-rst',
|
|
52
53
|
packages=find_packages('src'),
|
|
53
54
|
package_dir={'': 'src'},
|
|
54
55
|
classifiers=[
|
|
@@ -76,7 +77,7 @@ setup(name='AccessControl',
|
|
|
76
77
|
'DateTime', # optional dependency of RestrictedPython
|
|
77
78
|
'ExtensionClass >= 4.2.1',
|
|
78
79
|
'Persistence >= 3.0a3',
|
|
79
|
-
'RestrictedPython >=
|
|
80
|
+
'RestrictedPython >= 7.4',
|
|
80
81
|
'transaction',
|
|
81
82
|
'zExceptions',
|
|
82
83
|
'zope.component',
|
|
@@ -87,7 +88,6 @@ setup(name='AccessControl',
|
|
|
87
88
|
'zope.schema',
|
|
88
89
|
'zope.security',
|
|
89
90
|
'zope.testing',
|
|
90
|
-
'funcsigs;python_version<"3.3"',
|
|
91
91
|
],
|
|
92
92
|
python_requires='>=3.8',
|
|
93
93
|
include_package_data=True,
|
|
@@ -31,6 +31,7 @@ from Acquisition import aq_inner
|
|
|
31
31
|
from Acquisition import aq_parent
|
|
32
32
|
from ExtensionClass import Base
|
|
33
33
|
from zope.interface import implementer
|
|
34
|
+
from zExceptions import Unauthorized as zExceptions_Unauthorized
|
|
34
35
|
|
|
35
36
|
PURE_PYTHON = int(os.environ.get('PURE_PYTHON', '0'))
|
|
36
37
|
if PURE_PYTHON:
|
|
@@ -71,8 +72,11 @@ def rolesForPermissionOn(perm, object, default=_default_roles, n=None):
|
|
|
71
72
|
r = None
|
|
72
73
|
|
|
73
74
|
while True:
|
|
74
|
-
|
|
75
|
+
try:
|
|
75
76
|
roles = getattr(object, n)
|
|
77
|
+
except (AttributeError, zExceptions_Unauthorized):
|
|
78
|
+
pass
|
|
79
|
+
else:
|
|
76
80
|
if roles is None:
|
|
77
81
|
if _embed_permission_in_roles:
|
|
78
82
|
return (('Anonymous',), n)
|
|
@@ -140,7 +140,7 @@ class SecurityInfo(Implicit):
|
|
|
140
140
|
# the decorator returned is remembered in a set and will
|
|
141
141
|
# remove itself upon call. self.apply will check for an empty
|
|
142
142
|
# set and raise an AssertionError otherwise.
|
|
143
|
-
key = "'{}':{
|
|
143
|
+
key = f"'{permission_name}':{id(lambda x: x)}"
|
|
144
144
|
|
|
145
145
|
def decor(func):
|
|
146
146
|
self.declareProtected(permission_name, func.__name__) # NOQA: D001
|
|
@@ -148,7 +148,7 @@ class SecurityInfo(Implicit):
|
|
|
148
148
|
return func
|
|
149
149
|
# make sure our key algo creates unique-enough keys
|
|
150
150
|
if key in self._unused_protected_decorators:
|
|
151
|
-
raise KeyError("Duplicate key: {}"
|
|
151
|
+
raise KeyError(f"Duplicate key: {key}")
|
|
152
152
|
self._unused_protected_decorators.add(key)
|
|
153
153
|
return decor
|
|
154
154
|
|
|
@@ -491,7 +491,7 @@ def load_module(module, mname, mnameparts, validate, globals, locals):
|
|
|
491
491
|
if mname is None:
|
|
492
492
|
mname = nextname
|
|
493
493
|
else:
|
|
494
|
-
mname = '{}.{}'
|
|
494
|
+
mname = f'{mname}.{nextname}'
|
|
495
495
|
# import (if not already imported) and check for MSI
|
|
496
496
|
nextmodule = secureModule(mname, globals, locals)
|
|
497
497
|
if nextmodule is None: # not allowed
|
|
@@ -652,6 +652,7 @@ static PyExtensionClass imPermissionRoleType = {
|
|
|
652
652
|
static PyObject *Containers = NULL;
|
|
653
653
|
static PyObject *ContainerAssertions = NULL;
|
|
654
654
|
static PyObject *Unauthorized = NULL;
|
|
655
|
+
static PyObject *zExceptions_Unauthorized = NULL;
|
|
655
656
|
static PyObject *warn= NULL;
|
|
656
657
|
static PyObject *NoSequenceFormat = NULL;
|
|
657
658
|
static PyObject *_what_not_even_god_should_do = NULL;
|
|
@@ -1847,15 +1848,27 @@ c_rolesForPermissionOn(PyObject *perm, PyObject *object,
|
|
|
1847
1848
|
Py_INCREF(r);
|
|
1848
1849
|
|
|
1849
1850
|
/*
|
|
1850
|
-
while
|
|
1851
|
+
while True:
|
|
1851
1852
|
*/
|
|
1852
1853
|
while (1)
|
|
1853
1854
|
{
|
|
1854
1855
|
/*
|
|
1855
|
-
|
|
1856
|
+
try:
|
|
1856
1857
|
roles = getattr(object, n)
|
|
1858
|
+
except (AttributeError, zExceptions_Unauthorized):
|
|
1859
|
+
pass
|
|
1860
|
+
else:
|
|
1857
1861
|
*/
|
|
1858
1862
|
PyObject *roles = PyObject_GetAttr(object, n);
|
|
1863
|
+
if (roles == NULL)
|
|
1864
|
+
{
|
|
1865
|
+
if (! (PyErr_ExceptionMatches(PyExc_AttributeError)
|
|
1866
|
+
|| PyErr_ExceptionMatches(zExceptions_Unauthorized)))
|
|
1867
|
+
{
|
|
1868
|
+
/* re-raise */
|
|
1869
|
+
return NULL;
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1859
1872
|
if (roles != NULL)
|
|
1860
1873
|
{
|
|
1861
1874
|
|
|
@@ -2313,6 +2326,7 @@ static struct PyMethodDef dtml_methods[] = {
|
|
|
2313
2326
|
*/
|
|
2314
2327
|
#define IMPORT(module, name) if ((module = PyImport_ImportModule(name)) == NULL) return NULL;
|
|
2315
2328
|
#define GETATTR(module, name) if ((name = PyObject_GetAttrString(module, #name)) == NULL) return NULL;
|
|
2329
|
+
#define GETATTR_AS(module, name, as_name) if ((as_name = PyObject_GetAttrString(module, name)) == NULL) return NULL;
|
|
2316
2330
|
|
|
2317
2331
|
static struct PyModuleDef moduledef =
|
|
2318
2332
|
{
|
|
@@ -2400,6 +2414,14 @@ module_init(void) {
|
|
|
2400
2414
|
Py_DECREF(tmp);
|
|
2401
2415
|
tmp = NULL;
|
|
2402
2416
|
|
|
2417
|
+
/*| from zExceptions import Unauthorized as zExceptions_Unauthorized
|
|
2418
|
+
*/
|
|
2419
|
+
|
|
2420
|
+
IMPORT(tmp, "zExceptions");
|
|
2421
|
+
GETATTR_AS(tmp, "Unauthorized", zExceptions_Unauthorized);
|
|
2422
|
+
Py_DECREF(tmp);
|
|
2423
|
+
tmp = NULL;
|
|
2424
|
+
|
|
2403
2425
|
/*| from AccessControl.SecurityManagement import getSecurityManager
|
|
2404
2426
|
*/
|
|
2405
2427
|
|
|
@@ -102,10 +102,10 @@ class ClassSecurityInfoTests(unittest.TestCase):
|
|
|
102
102
|
self.assertEqual(object.private__roles__, ())
|
|
103
103
|
imPermissionRole = [r for r in object.protected__roles__
|
|
104
104
|
if not r.endswith('_Permission')]
|
|
105
|
-
self.
|
|
105
|
+
self.assertEqual(len(imPermissionRole), 4)
|
|
106
106
|
|
|
107
107
|
for item in ('Manager', 'Role A', 'Role B', 'Role C'):
|
|
108
|
-
self.
|
|
108
|
+
self.assertIn(item, imPermissionRole)
|
|
109
109
|
|
|
110
110
|
# functions exist, i.e. decorators returned them
|
|
111
111
|
self.assertEqual(object.public_new.__name__, 'public_new')
|
|
@@ -117,10 +117,10 @@ class ClassSecurityInfoTests(unittest.TestCase):
|
|
|
117
117
|
self.assertEqual(object.private_new__roles__, ())
|
|
118
118
|
imPermissionRole = [r for r in object.protected_new__roles__
|
|
119
119
|
if not r.endswith('_Permission')]
|
|
120
|
-
self.
|
|
120
|
+
self.assertEqual(len(imPermissionRole), 4)
|
|
121
121
|
|
|
122
122
|
for item in ('Manager', 'Role A', 'Role B', 'Role C'):
|
|
123
|
-
self.
|
|
123
|
+
self.assertIn(item, imPermissionRole)
|
|
124
124
|
|
|
125
125
|
# Make sure that a permission defined without accompanying method
|
|
126
126
|
# is still reflected in __ac_permissions__
|
|
@@ -160,7 +160,7 @@ class ClassSecurityInfoTests(unittest.TestCase):
|
|
|
160
160
|
# Do class initialization.
|
|
161
161
|
exc = self.assertRaises(AssertionError,
|
|
162
162
|
InitializeClass, Test)
|
|
163
|
-
self.
|
|
163
|
+
self.assertIn('has 2 non-decorator', str(exc))
|
|
164
164
|
|
|
165
165
|
def test_aq_context_in_decorators(self):
|
|
166
166
|
from Acquisition import Implicit
|
|
@@ -98,12 +98,12 @@ class ModuleSecurityTests(unittest.TestCase):
|
|
|
98
98
|
from AccessControl.SecurityInfo import _moduleSecurity as MS
|
|
99
99
|
from AccessControl.ZopeGuards import guarded_import
|
|
100
100
|
MSI('AccessControl.tests.nonesuch').declarePublic('pub') # NOQA: D001
|
|
101
|
-
self.
|
|
101
|
+
self.assertIn('AccessControl.tests.nonesuch', MS)
|
|
102
102
|
self.assertRaises(ImportError,
|
|
103
103
|
guarded_import,
|
|
104
104
|
'AccessControl.tests.nonesuch',
|
|
105
105
|
())
|
|
106
|
-
self.
|
|
106
|
+
self.assertIn('AccessControl.tests.nonesuch', MS)
|
|
107
107
|
|
|
108
108
|
def test_level_default(self):
|
|
109
109
|
self.assertAuth('AccessControl.tests.public_module', (),
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
##############################################################################
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2002 Zope Foundation and Contributors.
|
|
4
|
+
#
|
|
5
|
+
# This software is subject to the provisions of the Zope Public License,
|
|
6
|
+
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
|
7
|
+
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
|
8
|
+
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
9
|
+
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
|
10
|
+
# FOR A PARTICULAR PURPOSE
|
|
11
|
+
#
|
|
12
|
+
##############################################################################
|
|
13
|
+
"""Tests of PermissionRole
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import unittest
|
|
17
|
+
|
|
18
|
+
from Acquisition import Explicit
|
|
19
|
+
from Acquisition import Implicit
|
|
20
|
+
from Acquisition import aq_base
|
|
21
|
+
|
|
22
|
+
from ..Implementation import PURE_PYTHON
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
ViewPermission = 'View'
|
|
26
|
+
EditThingsPermission = 'Edit Things!'
|
|
27
|
+
DeletePermission = 'Delete'
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class AppRoot(Explicit):
|
|
31
|
+
_View_Permission = None
|
|
32
|
+
_Edit_Things__Permission = ('Manager', 'Owner')
|
|
33
|
+
# No default for delete permission.
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class ImplicitContainer(Implicit):
|
|
37
|
+
pass
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class ExplicitContainer(Explicit):
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class RestrictiveObject(Implicit):
|
|
45
|
+
_View_Permission = ('Manager',)
|
|
46
|
+
_Delete_Permission = () # Nobody
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class PermissiveObject(Explicit):
|
|
50
|
+
_Edit_Things__Permission = ['Anonymous']
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class PermissionRoleTestBase:
|
|
54
|
+
|
|
55
|
+
def assertPRoles(self, ob, permission, expect):
|
|
56
|
+
"""
|
|
57
|
+
Asserts that in the context of ob, the given permission maps to
|
|
58
|
+
the given roles.
|
|
59
|
+
"""
|
|
60
|
+
pr = self._getTargetClass()(permission)
|
|
61
|
+
roles = pr.__of__(ob)
|
|
62
|
+
roles2 = aq_base(pr).__of__(ob)
|
|
63
|
+
assert roles == roles2 or tuple(roles) == tuple(roles2), (
|
|
64
|
+
'Different methods of checking roles computed unequal results')
|
|
65
|
+
same = 0
|
|
66
|
+
if roles:
|
|
67
|
+
# When verbose security is enabled, permission names are
|
|
68
|
+
# embedded in the computed roles. Remove the permission
|
|
69
|
+
# names.
|
|
70
|
+
roles = [r for r in roles if not r.endswith('_Permission')]
|
|
71
|
+
|
|
72
|
+
if roles is None or expect is None:
|
|
73
|
+
if (roles is None or tuple(roles) == ('Anonymous', )) and \
|
|
74
|
+
(expect is None or tuple(expect) == ('Anonymous', )):
|
|
75
|
+
same = 1
|
|
76
|
+
else:
|
|
77
|
+
got = {}
|
|
78
|
+
for r in roles:
|
|
79
|
+
got[r] = 1
|
|
80
|
+
expected = {}
|
|
81
|
+
for r in expect:
|
|
82
|
+
expected[r] = 1
|
|
83
|
+
if got == expected: # Dict compare does the Right Thing.
|
|
84
|
+
same = 1
|
|
85
|
+
self.assertTrue(same, f'Expected roles: {expect!r}, got: {roles!r}')
|
|
86
|
+
|
|
87
|
+
def testRestrictive(self, explicit=0):
|
|
88
|
+
app = AppRoot()
|
|
89
|
+
if explicit:
|
|
90
|
+
app.c = ExplicitContainer()
|
|
91
|
+
else:
|
|
92
|
+
app.c = ImplicitContainer()
|
|
93
|
+
app.c.o = RestrictiveObject()
|
|
94
|
+
o = app.c.o
|
|
95
|
+
self.assertPRoles(o, ViewPermission, ('Manager', ))
|
|
96
|
+
self.assertPRoles(o, EditThingsPermission, ('Manager', 'Owner'))
|
|
97
|
+
self.assertPRoles(o, DeletePermission, ())
|
|
98
|
+
|
|
99
|
+
def testPermissive(self, explicit=0):
|
|
100
|
+
app = AppRoot()
|
|
101
|
+
if explicit:
|
|
102
|
+
app.c = ExplicitContainer()
|
|
103
|
+
else:
|
|
104
|
+
app.c = ImplicitContainer()
|
|
105
|
+
app.c.o = PermissiveObject()
|
|
106
|
+
o = app.c.o
|
|
107
|
+
self.assertPRoles(o, ViewPermission, ('Anonymous', ))
|
|
108
|
+
self.assertPRoles(o, EditThingsPermission, ('Anonymous',
|
|
109
|
+
'Manager',
|
|
110
|
+
'Owner'))
|
|
111
|
+
self.assertPRoles(o, DeletePermission, ('Manager', ))
|
|
112
|
+
|
|
113
|
+
def testExplicit(self):
|
|
114
|
+
self.testRestrictive(1)
|
|
115
|
+
self.testPermissive(1)
|
|
116
|
+
|
|
117
|
+
def testAppDefaults(self):
|
|
118
|
+
o = AppRoot()
|
|
119
|
+
self.assertPRoles(o, ViewPermission, ('Anonymous', ))
|
|
120
|
+
self.assertPRoles(o, EditThingsPermission, ('Manager', 'Owner'))
|
|
121
|
+
self.assertPRoles(o, DeletePermission, ('Manager', ))
|
|
122
|
+
|
|
123
|
+
def testPermissionRoleSupportsGetattr(self):
|
|
124
|
+
a = self._getTargetClass()('a')
|
|
125
|
+
self.assertEqual(getattr(a, '__roles__'), ('Manager', ))
|
|
126
|
+
self.assertEqual(getattr(a, '_d'), ('Manager', ))
|
|
127
|
+
self.assertEqual(getattr(a, '__name__'), 'a')
|
|
128
|
+
self.assertEqual(getattr(a, '_p'), '_a_Permission')
|
|
129
|
+
|
|
130
|
+
def testErrorsDuringGetattr(self):
|
|
131
|
+
pr = self._getTargetClass()('View')
|
|
132
|
+
|
|
133
|
+
class AttributeErrorObject(Implicit):
|
|
134
|
+
pass
|
|
135
|
+
self.assertEqual(
|
|
136
|
+
tuple(pr.__of__(AttributeErrorObject())), ('Manager', ))
|
|
137
|
+
|
|
138
|
+
# Unauthorized errors are tolerated and equivalent to no
|
|
139
|
+
# permission declaration
|
|
140
|
+
class UnauthorizedErrorObject(Implicit):
|
|
141
|
+
def __getattr__(self, name):
|
|
142
|
+
from zExceptions import Unauthorized
|
|
143
|
+
if name == '_View_Permission':
|
|
144
|
+
raise Unauthorized(name)
|
|
145
|
+
raise AttributeError(name)
|
|
146
|
+
self.assertEqual(
|
|
147
|
+
tuple(pr.__of__(UnauthorizedErrorObject())), ('Manager', ))
|
|
148
|
+
|
|
149
|
+
# other exceptions propagate
|
|
150
|
+
class ErrorObject(Implicit):
|
|
151
|
+
def __getattr__(self, name):
|
|
152
|
+
if name == '_View_Permission':
|
|
153
|
+
raise RuntimeError("Error raised during getattr")
|
|
154
|
+
raise AttributeError(name)
|
|
155
|
+
with self.assertRaisesRegex(
|
|
156
|
+
RuntimeError, "Error raised during getattr"):
|
|
157
|
+
tuple(pr.__of__(ErrorObject()))
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
class Python_PermissionRoleTests(PermissionRoleTestBase, unittest.TestCase):
|
|
161
|
+
def _getTargetClass(self):
|
|
162
|
+
from AccessControl.ImplPython import PermissionRole
|
|
163
|
+
return PermissionRole
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
@unittest.skipIf(PURE_PYTHON, reason="Test expects C impl.")
|
|
167
|
+
class C__PermissionRoleTests(PermissionRoleTestBase, unittest.TestCase):
|
|
168
|
+
def _getTargetClass(self):
|
|
169
|
+
from AccessControl.ImplC import PermissionRole
|
|
170
|
+
return PermissionRole
|