AccessControl 6.3__tar.gz → 7.1__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-6.3 → accesscontrol-7.1}/.manylinux-install.sh +7 -7
- accesscontrol-7.1/.pre-commit-config.yaml +28 -0
- {AccessControl-6.3 → accesscontrol-7.1}/CHANGES.rst +34 -0
- {AccessControl-6.3 → accesscontrol-7.1}/MANIFEST.in +1 -2
- {AccessControl-6.3 → accesscontrol-7.1}/PKG-INFO +40 -6
- accesscontrol-7.1/pyproject.toml +25 -0
- {AccessControl-6.3 → accesscontrol-7.1}/setup.cfg +0 -3
- {AccessControl-6.3 → accesscontrol-7.1}/setup.py +6 -6
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/ImplPython.py +5 -1
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/SecurityInfo.py +10 -9
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/ZopeGuards.py +49 -12
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/cAccessControl.c +29 -7
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/logger_wrapper.py +1 -1
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/tests/actual_python.py +33 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/tests/testClassSecurityInfo.py +5 -5
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/tests/testModuleSecurity.py +2 -2
- accesscontrol-7.1/src/AccessControl/tests/testPermissionRole.py +170 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/tests/testSecurityManager.py +28 -27
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/tests/testZopeGuards.py +26 -10
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/tests/testZopeSecurityPolicy.py +18 -2
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/tests/test_tainted.py +75 -57
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/tests/test_userfolder.py +1 -1
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/users.py +1 -1
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl.egg-info/PKG-INFO +40 -6
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl.egg-info/SOURCES.txt +2 -2
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl.egg-info/requires.txt +1 -4
- {AccessControl-6.3 → accesscontrol-7.1}/tox.ini +17 -20
- AccessControl-6.3/.coveragerc +0 -29
- AccessControl-6.3/appveyor.yml +0 -50
- AccessControl-6.3/src/AccessControl/tests/testPermissionRole.py +0 -129
- {AccessControl-6.3 → accesscontrol-7.1}/.manylinux.sh +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/CONTRIBUTING.md +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/COPYRIGHT.txt +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/HISTORY.rst +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/LICENSE.txt +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/README.rst +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/buildout.cfg +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/docs/AccessControl.rst +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/docs/requestmethod.rst +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/include/Acquisition/Acquisition.h +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/include/ExtensionClass/ExtensionClass.h +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/include/ExtensionClass/_compat.h +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/AuthEncoding.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/ImplC.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/Implementation.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/Owned.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/Permission.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/PermissionMapping.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/PermissionRole.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/Permissions.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/Role.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/SecurityManagement.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/SecurityManager.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/SimpleObjectPolicies.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/SpecialUsers.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/User.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/ZopeSecurityPolicy.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/__init__.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/_compat.h +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/class_init.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/configure.zcml +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/interfaces.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/meta.zcml +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/metaconfigure.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/owner.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/permissions.zcml +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/requestmethod.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/rolemanager.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/safe_formatter.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/security.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/tainted.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/tests/__init__.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/tests/mixed_module/__init__.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/tests/mixed_module/submodule/__init__.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/tests/private_module/__init__.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/tests/private_module/submodule/__init__.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/tests/public_module/__init__.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/tests/public_module/submodule/__init__.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/tests/testImplementation.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/tests/testPermissionMapping.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/tests/testZCML.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/tests/test_owner.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/tests/test_requestmethod.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/tests/test_rolemanager.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/tests/test_safe_formatter.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/tests/test_safeiter.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/tests/test_users.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/unauthorized.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl/userfolder.py +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl.egg-info/dependency_links.txt +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl.egg-info/entry_points.txt +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/src/AccessControl.egg-info/not-zip-safe +0 -0
- {AccessControl-6.3 → accesscontrol-7.1}/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
|
-
*"cp37"*) echo 'py37';;
|
|
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,12 +41,12 @@ tox_env_map() {
|
|
|
41
41
|
# Compile wheels
|
|
42
42
|
for PYBIN in /opt/python/*/bin; do
|
|
43
43
|
if \
|
|
44
|
-
[[ "${PYBIN}" == *"
|
|
45
|
-
[[ "${PYBIN}" == *"
|
|
46
|
-
[[ "${PYBIN}" == *"
|
|
47
|
-
[[ "${PYBIN}" == *"
|
|
48
|
-
[[ "${PYBIN}" == *"
|
|
49
|
-
[[ "${PYBIN}" == *"
|
|
44
|
+
[[ "${PYBIN}" == *"cp38/"* ]] || \
|
|
45
|
+
[[ "${PYBIN}" == *"cp39/"* ]] || \
|
|
46
|
+
[[ "${PYBIN}" == *"cp310/"* ]] || \
|
|
47
|
+
[[ "${PYBIN}" == *"cp311/"* ]] || \
|
|
48
|
+
[[ "${PYBIN}" == *"cp312/"* ]] || \
|
|
49
|
+
[[ "${PYBIN}" == *"cp313/"* ]] ; then
|
|
50
50
|
"${PYBIN}/pip" install -e /io/
|
|
51
51
|
"${PYBIN}/pip" wheel /io/ -w wheelhouse/
|
|
52
52
|
if [ `uname -m` == 'aarch64' ]; then
|
|
@@ -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,40 @@ Changelog
|
|
|
3
3
|
|
|
4
4
|
For changes before version 3.0, see ``HISTORY.rst``.
|
|
5
5
|
|
|
6
|
+
7.1 (2024-10-10)
|
|
7
|
+
----------------
|
|
8
|
+
|
|
9
|
+
- Add final support for Python 3.13.
|
|
10
|
+
|
|
11
|
+
- Respect ``PURE_PYTHON`` environment variable set to ``0`` when running tests.
|
|
12
|
+
|
|
13
|
+
- Let the roles access in ``rolesForPermissionOn`` interpret ``AttributeError``
|
|
14
|
+
and ``Unauthorized`` as "no roles definition for this permission at this
|
|
15
|
+
object" and report any other exception (for the Python and C implementation).
|
|
16
|
+
We have to treat ``Unauthorized`` like ``AttributeError`` to support
|
|
17
|
+
``Shared.DC.Scripts.Bindings.UnauthorizedBinding`` which raises
|
|
18
|
+
``Unauthorized`` for any access.
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
7.0 (2024-05-30)
|
|
22
|
+
----------------
|
|
23
|
+
|
|
24
|
+
- Add preliminary support for Python 3.13 as of 3.13b1.
|
|
25
|
+
|
|
26
|
+
- Remove support for Python 3.7.
|
|
27
|
+
|
|
28
|
+
- Build Windows wheels on GHA.
|
|
29
|
+
|
|
30
|
+
- Make dict views (`.keys()`, `.items()` and `.values()`) behave like their
|
|
31
|
+
unrestricted versions.
|
|
32
|
+
(`#147 <https://github.com/zopefoundation/AccessControl/pull/147>`_)
|
|
33
|
+
|
|
34
|
+
- Make `.items()` validate each keys and values, like `.keys()` and
|
|
35
|
+
`.values()` do.
|
|
36
|
+
|
|
37
|
+
- Fix build errors on recent macOS versions.
|
|
38
|
+
|
|
39
|
+
|
|
6
40
|
6.3 (2023-11-20)
|
|
7
41
|
----------------
|
|
8
42
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: AccessControl
|
|
3
|
-
Version:
|
|
3
|
+
Version: 7.1
|
|
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
|
|
@@ -17,14 +17,15 @@ Classifier: License :: OSI Approved :: Zope Public License
|
|
|
17
17
|
Classifier: Operating System :: OS Independent
|
|
18
18
|
Classifier: Programming Language :: Python
|
|
19
19
|
Classifier: Programming Language :: Python :: 3
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.8
|
|
22
21
|
Classifier: Programming Language :: Python :: 3.9
|
|
23
22
|
Classifier: Programming Language :: Python :: 3.10
|
|
24
23
|
Classifier: Programming Language :: Python :: 3.11
|
|
25
24
|
Classifier: Programming Language :: Python :: 3.12
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
26
26
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
27
|
-
Requires-Python: >=3.
|
|
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,40 @@ Changelog
|
|
|
73
73
|
|
|
74
74
|
For changes before version 3.0, see ``HISTORY.rst``.
|
|
75
75
|
|
|
76
|
+
7.1 (2024-10-10)
|
|
77
|
+
----------------
|
|
78
|
+
|
|
79
|
+
- Add final support for Python 3.13.
|
|
80
|
+
|
|
81
|
+
- Respect ``PURE_PYTHON`` environment variable set to ``0`` when running tests.
|
|
82
|
+
|
|
83
|
+
- Let the roles access in ``rolesForPermissionOn`` interpret ``AttributeError``
|
|
84
|
+
and ``Unauthorized`` as "no roles definition for this permission at this
|
|
85
|
+
object" and report any other exception (for the Python and C implementation).
|
|
86
|
+
We have to treat ``Unauthorized`` like ``AttributeError`` to support
|
|
87
|
+
``Shared.DC.Scripts.Bindings.UnauthorizedBinding`` which raises
|
|
88
|
+
``Unauthorized`` for any access.
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
7.0 (2024-05-30)
|
|
92
|
+
----------------
|
|
93
|
+
|
|
94
|
+
- Add preliminary support for Python 3.13 as of 3.13b1.
|
|
95
|
+
|
|
96
|
+
- Remove support for Python 3.7.
|
|
97
|
+
|
|
98
|
+
- Build Windows wheels on GHA.
|
|
99
|
+
|
|
100
|
+
- Make dict views (`.keys()`, `.items()` and `.values()`) behave like their
|
|
101
|
+
unrestricted versions.
|
|
102
|
+
(`#147 <https://github.com/zopefoundation/AccessControl/pull/147>`_)
|
|
103
|
+
|
|
104
|
+
- Make `.items()` validate each keys and values, like `.keys()` and
|
|
105
|
+
`.values()` do.
|
|
106
|
+
|
|
107
|
+
- Fix build errors on recent macOS versions.
|
|
108
|
+
|
|
109
|
+
|
|
76
110
|
6.3 (2023-11-20)
|
|
77
111
|
----------------
|
|
78
112
|
|
|
@@ -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 = '
|
|
35
|
+
version = '7.1'
|
|
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=[
|
|
@@ -60,12 +61,12 @@ setup(name='AccessControl',
|
|
|
60
61
|
'Operating System :: OS Independent',
|
|
61
62
|
'Programming Language :: Python',
|
|
62
63
|
'Programming Language :: Python :: 3',
|
|
63
|
-
'Programming Language :: Python :: 3.7',
|
|
64
64
|
'Programming Language :: Python :: 3.8',
|
|
65
65
|
'Programming Language :: Python :: 3.9',
|
|
66
66
|
'Programming Language :: Python :: 3.10',
|
|
67
67
|
'Programming Language :: Python :: 3.11',
|
|
68
68
|
'Programming Language :: Python :: 3.12',
|
|
69
|
+
'Programming Language :: Python :: 3.13',
|
|
69
70
|
'Programming Language :: Python :: Implementation :: CPython',
|
|
70
71
|
],
|
|
71
72
|
ext_modules=ext_modules,
|
|
@@ -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,9 +88,8 @@ setup(name='AccessControl',
|
|
|
87
88
|
'zope.schema',
|
|
88
89
|
'zope.security',
|
|
89
90
|
'zope.testing',
|
|
90
|
-
'funcsigs;python_version<"3.3"',
|
|
91
91
|
],
|
|
92
|
-
python_requires='>=3.
|
|
92
|
+
python_requires='>=3.8',
|
|
93
93
|
include_package_data=True,
|
|
94
94
|
zip_safe=False,
|
|
95
95
|
extras_require={
|
|
@@ -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)
|
|
@@ -78,7 +78,8 @@ class SecurityInfo(Implicit):
|
|
|
78
78
|
def _setaccess(self, names, access):
|
|
79
79
|
for name in names:
|
|
80
80
|
if self.names.get(name, access) != access:
|
|
81
|
-
LOG.
|
|
81
|
+
LOG.warning(
|
|
82
|
+
f'Conflicting security declarations for {name!r}')
|
|
82
83
|
self._warnings = 1
|
|
83
84
|
self.names[name] = access
|
|
84
85
|
|
|
@@ -139,7 +140,7 @@ class SecurityInfo(Implicit):
|
|
|
139
140
|
# the decorator returned is remembered in a set and will
|
|
140
141
|
# remove itself upon call. self.apply will check for an empty
|
|
141
142
|
# set and raise an AssertionError otherwise.
|
|
142
|
-
key = "'{}':{
|
|
143
|
+
key = f"'{permission_name}':{id(lambda x: x)}"
|
|
143
144
|
|
|
144
145
|
def decor(func):
|
|
145
146
|
self.declareProtected(permission_name, func.__name__) # NOQA: D001
|
|
@@ -147,7 +148,7 @@ class SecurityInfo(Implicit):
|
|
|
147
148
|
return func
|
|
148
149
|
# make sure our key algo creates unique-enough keys
|
|
149
150
|
if key in self._unused_protected_decorators:
|
|
150
|
-
raise KeyError("Duplicate key: {}"
|
|
151
|
+
raise KeyError(f"Duplicate key: {key}")
|
|
151
152
|
self._unused_protected_decorators.add(key)
|
|
152
153
|
return decor
|
|
153
154
|
|
|
@@ -159,8 +160,8 @@ class SecurityInfo(Implicit):
|
|
|
159
160
|
for role in roles:
|
|
160
161
|
rdict[role] = 1
|
|
161
162
|
if self.roles.get(permission_name, rdict) != rdict:
|
|
162
|
-
LOG.
|
|
163
|
-
|
|
163
|
+
LOG.warning('Conflicting default role'
|
|
164
|
+
' declarations for permission "%s"' % permission_name)
|
|
164
165
|
self._warnings = 1
|
|
165
166
|
self.roles[permission_name] = rdict
|
|
166
167
|
|
|
@@ -248,8 +249,8 @@ class ClassSecurityInfo(SecurityInfo):
|
|
|
248
249
|
access)
|
|
249
250
|
|
|
250
251
|
if getattr(self, '_warnings', None):
|
|
251
|
-
LOG.
|
|
252
|
-
|
|
252
|
+
LOG.warning('Class "%s" had conflicting'
|
|
253
|
+
' security declarations' % classobj.__name__)
|
|
253
254
|
|
|
254
255
|
|
|
255
256
|
class ClassSecurityInformation(ClassSecurityInfo):
|
|
@@ -343,8 +344,8 @@ class _ModuleSecurityInfo(SecurityInfo):
|
|
|
343
344
|
dict['__allow_access_to_unprotected_subobjects__'] = self
|
|
344
345
|
|
|
345
346
|
if getattr(self, '_warnings', None):
|
|
346
|
-
LOG.
|
|
347
|
-
|
|
347
|
+
LOG.warning('Module "%s" had conflicting'
|
|
348
|
+
' security declarations' % dict['__name__'])
|
|
348
349
|
|
|
349
350
|
declareProtected__roles__ = ACCESS_PRIVATE
|
|
350
351
|
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
##############################################################################
|
|
13
13
|
|
|
14
14
|
|
|
15
|
+
import collections.abc
|
|
15
16
|
import math
|
|
16
17
|
import random
|
|
17
18
|
import string
|
|
@@ -127,13 +128,18 @@ def get_dict_pop(d, name):
|
|
|
127
128
|
return guarded_pop
|
|
128
129
|
|
|
129
130
|
|
|
130
|
-
def
|
|
131
|
-
iter = getattr(c, name)
|
|
131
|
+
def get_mapping_view(c, name):
|
|
132
132
|
|
|
133
|
-
|
|
134
|
-
|
|
133
|
+
view_class = {
|
|
134
|
+
'keys': SafeKeysView,
|
|
135
|
+
'items': SafeItemsView,
|
|
136
|
+
'values': SafeValuesView,
|
|
137
|
+
}
|
|
135
138
|
|
|
136
|
-
|
|
139
|
+
def guarded_mapping_view():
|
|
140
|
+
return view_class[name](c)
|
|
141
|
+
|
|
142
|
+
return guarded_mapping_view
|
|
137
143
|
|
|
138
144
|
|
|
139
145
|
def get_list_pop(lst, name):
|
|
@@ -153,18 +159,15 @@ _dict_white_list = {
|
|
|
153
159
|
'copy': 1,
|
|
154
160
|
'fromkeys': 1,
|
|
155
161
|
'get': get_dict_get,
|
|
156
|
-
'items':
|
|
162
|
+
'items': get_mapping_view,
|
|
163
|
+
'keys': get_mapping_view,
|
|
157
164
|
'pop': get_dict_pop,
|
|
158
165
|
'popitem': 1,
|
|
159
166
|
'setdefault': 1,
|
|
160
167
|
'update': 1,
|
|
168
|
+
'values': get_mapping_view,
|
|
161
169
|
}
|
|
162
170
|
|
|
163
|
-
_dict_white_list.update({
|
|
164
|
-
'keys': get_iter,
|
|
165
|
-
'values': get_iter,
|
|
166
|
-
})
|
|
167
|
-
|
|
168
171
|
|
|
169
172
|
def _check_dict_access(name, value):
|
|
170
173
|
# Check whether value is a dict method
|
|
@@ -272,6 +275,40 @@ class NullIter(SafeIter):
|
|
|
272
275
|
next = __next__
|
|
273
276
|
|
|
274
277
|
|
|
278
|
+
# The following three view classes are used only for mappings of type `dict`
|
|
279
|
+
# (not subclasses). Therefore, the mapping does not have security assertions
|
|
280
|
+
# and cannot acquire ones. As a consequence, the `guard` calls used in their
|
|
281
|
+
# methods verify that the checked key or value is accessible based solely on
|
|
282
|
+
# its own virtues, i.e. either because it is public or has its own security
|
|
283
|
+
# assertions allowing access.
|
|
284
|
+
class _SafeMappingView:
|
|
285
|
+
__allow_access_to_unprotected_subobjects__ = 1
|
|
286
|
+
|
|
287
|
+
def __iter__(self):
|
|
288
|
+
for e in super().__iter__():
|
|
289
|
+
guard(self._mapping, e)
|
|
290
|
+
yield e
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
class SafeKeysView(_SafeMappingView, collections.abc.KeysView):
|
|
294
|
+
pass
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
class SafeValuesView(_SafeMappingView, collections.abc.ValuesView):
|
|
298
|
+
pass
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
class SafeItemsView(_SafeMappingView, collections.abc.ItemsView):
|
|
302
|
+
def __iter__(self):
|
|
303
|
+
for k, v in super().__iter__():
|
|
304
|
+
guard(self._mapping, k)
|
|
305
|
+
# When checking the value, we check the guard with index=None,
|
|
306
|
+
# not with index=k, the key name does not matter. guard just
|
|
307
|
+
# needs to verify that the value itself can be accessed.
|
|
308
|
+
guard(self._mapping, v)
|
|
309
|
+
yield k, v
|
|
310
|
+
|
|
311
|
+
|
|
275
312
|
def _error(index):
|
|
276
313
|
raise Unauthorized('unauthorized access to element')
|
|
277
314
|
|
|
@@ -454,7 +491,7 @@ def load_module(module, mname, mnameparts, validate, globals, locals):
|
|
|
454
491
|
if mname is None:
|
|
455
492
|
mname = nextname
|
|
456
493
|
else:
|
|
457
|
-
mname = '{}.{}'
|
|
494
|
+
mname = f'{mname}.{nextname}'
|
|
458
495
|
# import (if not already imported) and check for MSI
|
|
459
496
|
nextmodule = secureModule(mname, globals, locals)
|
|
460
497
|
if nextmodule is None: # not allowed
|
|
@@ -425,7 +425,7 @@ static PyExtensionClass ZopeSecurityPolicyType = {
|
|
|
425
425
|
0, /* tp_itemsize */
|
|
426
426
|
/* Standard methods */
|
|
427
427
|
(destructor) ZopeSecurityPolicy_dealloc,/* tp_dealloc */
|
|
428
|
-
|
|
428
|
+
0, /* tp_vectorcall_offset */
|
|
429
429
|
NULL, /* tp_getattr */
|
|
430
430
|
NULL, /* tp_setattr */
|
|
431
431
|
NULL, /* tp_compare */
|
|
@@ -484,7 +484,7 @@ static PyExtensionClass SecurityManagerType = {
|
|
|
484
484
|
0, /* tp_itemsize */
|
|
485
485
|
/* Standard methods */
|
|
486
486
|
(destructor) SecurityManager_dealloc,/* tp_dealloc */
|
|
487
|
-
|
|
487
|
+
0, /* tp_vectorcall_offset*/
|
|
488
488
|
NULL, /* tp_getattr */
|
|
489
489
|
NULL, /* tp_setattr */
|
|
490
490
|
NULL, /* tp_compare */
|
|
@@ -543,7 +543,7 @@ static PyExtensionClass PermissionRoleType = {
|
|
|
543
543
|
0, /* tp_itemsize */
|
|
544
544
|
/* Standard methods */
|
|
545
545
|
(destructor) PermissionRole_dealloc, /* tp_dealloc */
|
|
546
|
-
|
|
546
|
+
0, /* tp_vectorcall_offset */
|
|
547
547
|
NULL, /* tp_getattr */
|
|
548
548
|
NULL, /* tp_setattr */
|
|
549
549
|
NULL, /* tp_compare */
|
|
@@ -613,7 +613,7 @@ static PyExtensionClass imPermissionRoleType = {
|
|
|
613
613
|
0, /* tp_itemsize */
|
|
614
614
|
/* Standard methods */
|
|
615
615
|
(destructor) imPermissionRole_dealloc, /* tp_dealloc */
|
|
616
|
-
|
|
616
|
+
0, /* tp_vectorcall_offset */
|
|
617
617
|
NULL, /* tp_getattr */
|
|
618
618
|
NULL, /* tp_setattr */
|
|
619
619
|
NULL, /* tp_compare */
|
|
@@ -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;
|
|
@@ -1071,7 +1072,7 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) {
|
|
|
1071
1072
|
**| try:
|
|
1072
1073
|
**| if roles is None or 'Anonymous' in roles: return 1
|
|
1073
1074
|
**| except TypeError:
|
|
1074
|
-
**| LOG.
|
|
1075
|
+
**| LOG.warning('"%s' passed as roles"
|
|
1075
1076
|
**| " during validation of '%s' is not a sequence." %
|
|
1076
1077
|
**| ('roles', name))
|
|
1077
1078
|
**| raise
|
|
@@ -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
|
|
|
@@ -123,6 +123,39 @@ def f7():
|
|
|
123
123
|
access = getattr(d, meth)
|
|
124
124
|
result = sorted(access())
|
|
125
125
|
assert result == expected[kind], (meth, kind, result, expected[kind])
|
|
126
|
+
assert len(access()) == len(expected[kind]), (meth, kind, "len")
|
|
127
|
+
iter_ = access() # iterate twice on the same view
|
|
128
|
+
assert list(iter_) == list(iter_)
|
|
129
|
+
|
|
130
|
+
assert sorted([k for k in getattr(d, meth)()]) == expected[kind]
|
|
131
|
+
assert sorted(k for k in getattr(d, meth)()) == expected[kind]
|
|
132
|
+
assert {k: v for k, v in d.items()} == d
|
|
133
|
+
|
|
134
|
+
assert 1 in d
|
|
135
|
+
assert 1 in d.keys()
|
|
136
|
+
assert 2 in d.values()
|
|
137
|
+
assert (1, 2) in d.items()
|
|
138
|
+
|
|
139
|
+
assert d
|
|
140
|
+
assert d.keys()
|
|
141
|
+
assert d.values()
|
|
142
|
+
assert d.items()
|
|
143
|
+
|
|
144
|
+
empty_d = {}
|
|
145
|
+
assert not empty_d
|
|
146
|
+
assert not empty_d.keys()
|
|
147
|
+
assert not empty_d.values()
|
|
148
|
+
assert not empty_d.items()
|
|
149
|
+
|
|
150
|
+
smaller_d = {1: 2}
|
|
151
|
+
for m, _ in methods:
|
|
152
|
+
assert getattr(d, m)() != getattr(smaller_d, m)()
|
|
153
|
+
assert not getattr(d, m)() == getattr(smaller_d, m)()
|
|
154
|
+
if m != 'values':
|
|
155
|
+
assert getattr(d, m)() > getattr(smaller_d, m)()
|
|
156
|
+
assert getattr(d, m)() >= getattr(smaller_d, m)()
|
|
157
|
+
assert getattr(smaller_d, m)() < getattr(d, m)()
|
|
158
|
+
assert getattr(smaller_d, m)() <= getattr(d, m)()
|
|
126
159
|
|
|
127
160
|
|
|
128
161
|
f7()
|
|
@@ -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', (),
|