From e093533811a878967b88c989a0a8014bab25d127 Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Wed, 2 Feb 2022 11:00:47 +0100 Subject: [PATCH 01/52] basic refactoring for plone 6 --- .travis.yml | 39 --------- CHANGES.rst | 5 +- TODO.rst | 2 +- buildout-5.1.x.cfg | 5 -- buildout-5.2.x.cfg | 5 -- ldap.cfg | 42 ---------- requirements-5.1.x.txt | 1 - requirements-5.2.x.txt | 1 - setup.cfg | 81 +++++++++++++++++- setup.py | 83 +------------------ src/pas/__init__.py | 9 +- src/pas/plugins/__init__.py | 9 +- src/pas/plugins/ldap/__init__.py | 10 +-- src/pas/plugins/ldap/cache.py | 8 +- .../plugins/ldap/plonecontrolpanel/cache.py | 2 +- .../ldap/plonecontrolpanel/configure.zcml | 10 +-- .../ldap/plonecontrolpanel/controlpanel.py | 2 +- .../profiles/base/registry.xml | 8 -- .../{base => default}/componentregistry.xml | 0 .../{plone5 => default}/controlpanel.xml | 0 .../{base => default}/ldapsettings.xml | 0 .../profiles/{base => default}/metadata.xml | 0 .../profiles/{plone5 => default}/registry.xml | 10 ++- .../profiles/plone5/metadata.xml | 7 -- .../ldap/plonecontrolpanel/upgrades.py | 2 +- src/pas/plugins/ldap/plugin.py | 8 +- src/pas/plugins/ldap/properties.py | 6 +- src/pas/plugins/ldap/setuphandlers.py | 2 +- src/pas/plugins/ldap/sheet.py | 4 +- src/pas/plugins/ldap/testing.py | 25 ++---- src/pas/plugins/ldap/tests/test_doctests.py | 2 +- src/pas/plugins/ldap/tests/test_plugin.py | 2 +- src/pas/plugins/ldap/zmi/manage_plugin.py | 2 +- 33 files changed, 128 insertions(+), 264 deletions(-) delete mode 100644 .travis.yml delete mode 100644 buildout-5.1.x.cfg delete mode 100644 buildout-5.2.x.cfg delete mode 100644 ldap.cfg delete mode 100644 requirements-5.1.x.txt delete mode 100644 requirements-5.2.x.txt delete mode 100644 src/pas/plugins/ldap/plonecontrolpanel/profiles/base/registry.xml rename src/pas/plugins/ldap/plonecontrolpanel/profiles/{base => default}/componentregistry.xml (100%) rename src/pas/plugins/ldap/plonecontrolpanel/profiles/{plone5 => default}/controlpanel.xml (100%) rename src/pas/plugins/ldap/plonecontrolpanel/profiles/{base => default}/ldapsettings.xml (100%) rename src/pas/plugins/ldap/plonecontrolpanel/profiles/{base => default}/metadata.xml (100%) rename src/pas/plugins/ldap/plonecontrolpanel/profiles/{plone5 => default}/registry.xml (66%) delete mode 100644 src/pas/plugins/ldap/plonecontrolpanel/profiles/plone5/metadata.xml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 749b104..0000000 --- a/.travis.yml +++ /dev/null @@ -1,39 +0,0 @@ -language: python -sudo: false -addons: - apt: - packages: - - libssl-dev - - libdb-dev -cache: - pip: true - directories: - - eggs - - downloads - - openldap -matrix: - fast_finish: true - include: - - python: "2.7" - env: PLONE_VERSION=5.1.x - - python: "2.7" - env: PLONE_VERSION=5.2.x - - python: "3.6" - env: PLONE_VERSION=5.2.x - - python: "3.7" - env: PLONE_VERSION=5.2.x - dist: xenial -sudo: true -install: - - pip install -r requirements-${PLONE_VERSION}.txt - - buildout -Nc buildout-${PLONE_VERSION}.cfg buildout:download-cache=downloads code-analysis:return-status-codes=True "parts=test code-analysis coverage test-coverage testldap" annotate - - buildout -Nc buildout-${PLONE_VERSION}.cfg buildout:download-cache=downloads code-analysis:return-status-codes=True "parts=test code-analysis coverage test-coverage testldap" -script: - - bin/code-analysis - - bin/test -after_success: - - bin/createcoverage - - bin/pip install coverage - - bin/python -m coverage.pickle2json - - pip install coveralls - - coveralls \ No newline at end of file diff --git a/CHANGES.rst b/CHANGES.rst index 28fae20..8f62b18 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,10 +2,11 @@ History ======= -1.8.3 (unreleased) +1.9.0 (unreleased) ------------------ -- Nothing changed yet. +- Drop support for Plone 5/ Python < 3.9 + [jensens] 1.8.2 (2022-10-31) diff --git a/TODO.rst b/TODO.rst index 4a8f0bd..ef07018 100644 --- a/TODO.rst +++ b/TODO.rst @@ -5,7 +5,7 @@ TODO See also `Issue-Tracker `_ -Milestone 2.0 +Milestone 3.0 ------------- - remove portrait monkey patch diff --git a/buildout-5.1.x.cfg b/buildout-5.1.x.cfg deleted file mode 100644 index f1cb536..0000000 --- a/buildout-5.1.x.cfg +++ /dev/null @@ -1,5 +0,0 @@ -[buildout] -extends = - base.cfg - https://dist.plone.org/release/5.1-latest/versions.cfg - versions.cfg diff --git a/buildout-5.2.x.cfg b/buildout-5.2.x.cfg deleted file mode 100644 index 438e3a8..0000000 --- a/buildout-5.2.x.cfg +++ /dev/null @@ -1,5 +0,0 @@ -[buildout] -extends = - base.cfg - https://dist.plone.org/release/5.2-latest/versions.cfg - versions.cfg diff --git a/ldap.cfg b/ldap.cfg deleted file mode 100644 index 1f1f634..0000000 --- a/ldap.cfg +++ /dev/null @@ -1,42 +0,0 @@ -[buildout] -parts += - python-ldap - testldap - -[openldap] -# this build needs (on debian based systems): -# apt-get install libssl-dev -recipe = zc.recipe.cmmi>=2.0.0 -url = https://www.openldap.org/software/download/OpenLDAP/openldap-release/openldap-2.4.49.tgz -extra_options = --with-tls --enable-slapd=yes --enable-overlays --disable-bdb --disable-hdb CPPFLAGS=-D_GNU_SOURCE -shared = true - - -[python-ldap] -recipe = zc.recipe.egg:custom -egg = python-ldap -include-dirs = - ${openldap:location}/include -library-dirs = - ${openldap:location}/lib -rpath = - ${openldap:location}/lib - - -[testenv] -LDAP_ADD_BIN = ${openldap:location}/bin/ldapadd -LDAP_DELETE_BIN = ${openldap:location}/bin/ldapdelete -SLAPD_BIN = ${openldap:location}/libexec/slapd -SLAPD_URIS = ldap://127.0.0.1:12345 - - -[testldap] -recipe = zc.recipe.egg:script -eggs = - node.ext.ldap[test] -initialization = - import os - os.environ['SLAPD_BIN'] = '${testenv:SLAPD_BIN}' - os.environ['SLAPD_URIS'] = '${testenv:SLAPD_URIS}' - os.environ['LDAP_DELETE_BIN'] = '${testenv:LDAP_DELETE_BIN}' - os.environ['LDAP_ADD_BIN'] = '${testenv:LDAP_ADD_BIN}' diff --git a/requirements-5.1.x.txt b/requirements-5.1.x.txt deleted file mode 100644 index 196bcda..0000000 --- a/requirements-5.1.x.txt +++ /dev/null @@ -1 +0,0 @@ --r https://dist.plone.org/release/5.1-latest/requirements.txt \ No newline at end of file diff --git a/requirements-5.2.x.txt b/requirements-5.2.x.txt deleted file mode 100644 index 6fbe573..0000000 --- a/requirements-5.2.x.txt +++ /dev/null @@ -1 +0,0 @@ --r https://dist.plone.org/release/5.2-latest/requirements.txt \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index 6a52b8a..4f29950 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,11 +1,86 @@ +[metadata] +name = pas.plugins.ldap +version=2.0.0.dev0 +description=LDAP/AD Plugin for Plone/Zope PluggableAuthService (users+groups) +long_description = file: README.rst, CHANGES.rst +keywords = zope pas plone ldap authentication plugin users groups +author = BlueDynamics Alliance +author_email = dev@bluedynamics.com +license = GPLv2 +license_files = LICENSE.rst +url = https://github.com/collective/pas.plugins.ldap/ +project_urls = + ChangeLog = https://github.com/collective/pas.plugins.ldap/blob/master/CHANGES.rst + Issue Tracker = https://github.com/collective/pas.plugins.ldap/issues + Source Code = https://github.com/collective/pas.plugins.ldap +classifiers = + Development Status :: 5 - Production/Stable + Environment :: Web Environment + Framework :: Plone :: 6.0 + Framework :: Plone :: Addon + Framework :: Plone + Framework :: Zope :: 5 + Framework :: Zope + License :: OSI Approved :: GNU General Public License v2 (GPLv2) + Operating System :: OS Independent + Programming Language :: Python :: 3.9 + Programming Language :: Python :: 3.10 + Programming Language :: Python :: 3.11 + Topic :: System :: Systems Administration :: Authentication/Directory :: LDAP + Programming Language :: Python + +[options] +setup_requires = setuptools +install_requires = + bda.cache + five.globalrequest + node.ext.ldap>=1.0rc1 + odict + plone.registry + Products.CMFCore + Products.GenericSetup + Products.PlonePAS + Products.PluggableAuthService + Products.statusmessages + python-ldap>=3.4.0 + setuptools + yafowil.plone>=4.0.0a3 + yafowil.widget.array + yafowil.widget.dict + yafowil.yaml + zope.globalrequest + Zope>=5 + +include_package_data = True +zip_safe = False +namespace_packages = + pas + pas.plugins + +package_dir = + = src +packages = find: + +[options.packages.find] +where = + src + +[options.entry_points] +z3c.autoinclude.plugin = + target = plone + +[options.extras_require] +test = + plone.testing + +plone = + Products.CMFPlone + [isort] -# https://github.com/timothycrosley/isort/wiki/isort-Settings -# https://github.com/plone/plone.recipe.codeanalysis profile = black force_alphabetical_sort=True force_single_line = True lines_after_imports = 2 -line_length = 200 [zest.releaser] create-wheel = yes diff --git a/setup.py b/setup.py index c2eb5bd..6068493 100644 --- a/setup.py +++ b/setup.py @@ -1,84 +1,3 @@ -from setuptools import find_packages from setuptools import setup -import os - - -version = "1.8.3.dev0" -shortdesc = "LDAP/AD Plugin for Plone/Zope PluggableAuthService (users+groups)" -longdesc = open(os.path.join(os.path.dirname(__file__), "README.rst")).read() -longdesc += open(os.path.join(os.path.dirname(__file__), "TODO.rst")).read() -longdesc += open(os.path.join(os.path.dirname(__file__), "CHANGES.rst")).read() -longdesc += open(os.path.join(os.path.dirname(__file__), "LICENSE.rst")).read() - - -setup( - name="pas.plugins.ldap", - version=version, - description=shortdesc, - long_description=longdesc, - classifiers=[ - "Development Status :: 5 - Production/Stable", - "Environment :: Web Environment", - "Framework :: Plone :: 5.1", - "Framework :: Plone :: 5.2", - "Framework :: Plone :: Addon", - "Framework :: Plone", - "Framework :: Zope :: 2", - "Framework :: Zope :: 4", - "Framework :: Zope", - "License :: OSI Approved :: GNU General Public License v2 (GPLv2)", - "Operating System :: OS Independent", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python", - "Topic :: System :: Systems Administration :: Authentication/Directory :: LDAP", - ], - keywords="zope pas plone ldap authentication plugin", - author="BlueDynamics Alliance", - author_email="dev@bluedynamics.com", - url="https://github.com/collective/pas.plugins.ldap/", - license="GPLv2", - packages=find_packages("src"), - package_dir={"": "src"}, - namespace_packages=["pas", "pas.plugins"], - include_package_data=True, - zip_safe=False, - install_requires=[ - "AccessControl>=3.0", - "Acquisition", - "bda.cache", - "five.globalrequest", - "node", - "node.ext.ldap>=1.1", - "odict", - "plone.registry", - "Products.CMFCore", - "Products.GenericSetup", - "Products.PlonePAS", - "Products.PluggableAuthService", - "Products.statusmessages", - "python-ldap>=3.2.0", - "setuptools", - "six", - "yafowil>=2.3.1", - "yafowil.plone>=4.0.0a3", - "yafowil.widget.array", - "yafowil.widget.dict", - "yafowil.yaml", - "zope.component", - "zope.globalrequest", - "zope.i18nmessageid", - "zope.interface", - "zope.traversing", - ], - extras_require={ - "test": ["plone.testing", "zope.configuration"], - "plone": ["Plone"], - }, - entry_points=""" - [z3c.autoinclude.plugin] - target = plone - """, -) +setup() diff --git a/src/pas/__init__.py b/src/pas/__init__.py index ca12a73..5284146 100644 --- a/src/pas/__init__.py +++ b/src/pas/__init__.py @@ -1,8 +1 @@ -# -*- coding: utf-8 -*- -# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages -try: - __import__("pkg_resources").declare_namespace(__name__) -except ImportError: - from pkgutil import extend_path - - __path__ = extend_path(__path__, __name__) +__import__("pkg_resources").declare_namespace(__name__) diff --git a/src/pas/plugins/__init__.py b/src/pas/plugins/__init__.py index ca12a73..5284146 100644 --- a/src/pas/plugins/__init__.py +++ b/src/pas/plugins/__init__.py @@ -1,8 +1 @@ -# -*- coding: utf-8 -*- -# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages -try: - __import__("pkg_resources").declare_namespace(__name__) -except ImportError: - from pkgutil import extend_path - - __path__ = extend_path(__path__, __name__) +__import__("pkg_resources").declare_namespace(__name__) diff --git a/src/pas/plugins/ldap/__init__.py b/src/pas/plugins/ldap/__init__.py index cd63eb0..0249a2b 100644 --- a/src/pas/plugins/ldap/__init__.py +++ b/src/pas/plugins/ldap/__init__.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- from AccessControl.Permissions import add_user_folders -from pas.plugins.ldap import monkey # noqa -from pas.plugins.ldap.plugin import LDAPPlugin -from pas.plugins.ldap.plugin import manage_addLDAPPlugin -from pas.plugins.ldap.plugin import manage_addLDAPPluginForm -from pas.plugins.ldap.plugin import zmidir +from . import monkey # noqa +from . import LDAPPlugin +from . import manage_addLDAPPlugin +from . import manage_addLDAPPluginForm +from . import zmidir from Products.PluggableAuthService import registerMultiPlugin import os diff --git a/src/pas/plugins/ldap/cache.py b/src/pas/plugins/ldap/cache.py index 74df4c1..9865038 100644 --- a/src/pas/plugins/ldap/cache.py +++ b/src/pas/plugins/ldap/cache.py @@ -3,10 +3,10 @@ from bda.cache import Memcached from bda.cache import NullCache from node.ext.ldap.interfaces import ICacheProviderFactory -from pas.plugins.ldap.interfaces import ICacheSettingsRecordProvider -from pas.plugins.ldap.interfaces import ILDAPPlugin -from pas.plugins.ldap.interfaces import IPluginCacheHandler -from pas.plugins.ldap.interfaces import VALUE_NOT_CACHED +from .interfaces import ICacheSettingsRecordProvider +from .interfaces import ILDAPPlugin +from .interfaces import IPluginCacheHandler +from .interfaces import VALUE_NOT_CACHED from zope.component import adapter from zope.component import queryUtility from zope.globalrequest import getRequest diff --git a/src/pas/plugins/ldap/plonecontrolpanel/cache.py b/src/pas/plugins/ldap/plonecontrolpanel/cache.py index 500a284..89ea514 100644 --- a/src/pas/plugins/ldap/plonecontrolpanel/cache.py +++ b/src/pas/plugins/ldap/plonecontrolpanel/cache.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from pas.plugins.ldap.interfaces import ICacheSettingsRecordProvider +from ..interfaces import ICacheSettingsRecordProvider from persistent import Persistent from plone.registry import field from plone.registry import Record diff --git a/src/pas/plugins/ldap/plonecontrolpanel/configure.zcml b/src/pas/plugins/ldap/plonecontrolpanel/configure.zcml index e261fa1..1bef934 100644 --- a/src/pas/plugins/ldap/plonecontrolpanel/configure.zcml +++ b/src/pas/plugins/ldap/plonecontrolpanel/configure.zcml @@ -7,18 +7,10 @@ - - - diff --git a/src/pas/plugins/ldap/plonecontrolpanel/controlpanel.py b/src/pas/plugins/ldap/plonecontrolpanel/controlpanel.py index d8daccc..48f1753 100644 --- a/src/pas/plugins/ldap/plonecontrolpanel/controlpanel.py +++ b/src/pas/plugins/ldap/plonecontrolpanel/controlpanel.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from pas.plugins.ldap.properties import BasePropertiesForm +from ..properties import BasePropertiesForm from Products.CMFCore.interfaces import ISiteRoot from Products.CMFPlone.resources import add_bundle_on_request from Products.statusmessages.interfaces import IStatusMessage diff --git a/src/pas/plugins/ldap/plonecontrolpanel/profiles/base/registry.xml b/src/pas/plugins/ldap/plonecontrolpanel/profiles/base/registry.xml deleted file mode 100644 index 02403ee..0000000 --- a/src/pas/plugins/ldap/plonecontrolpanel/profiles/base/registry.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - servers, delimited by space - - 127.0.0.1:11211 - - \ No newline at end of file diff --git a/src/pas/plugins/ldap/plonecontrolpanel/profiles/base/componentregistry.xml b/src/pas/plugins/ldap/plonecontrolpanel/profiles/default/componentregistry.xml similarity index 100% rename from src/pas/plugins/ldap/plonecontrolpanel/profiles/base/componentregistry.xml rename to src/pas/plugins/ldap/plonecontrolpanel/profiles/default/componentregistry.xml diff --git a/src/pas/plugins/ldap/plonecontrolpanel/profiles/plone5/controlpanel.xml b/src/pas/plugins/ldap/plonecontrolpanel/profiles/default/controlpanel.xml similarity index 100% rename from src/pas/plugins/ldap/plonecontrolpanel/profiles/plone5/controlpanel.xml rename to src/pas/plugins/ldap/plonecontrolpanel/profiles/default/controlpanel.xml diff --git a/src/pas/plugins/ldap/plonecontrolpanel/profiles/base/ldapsettings.xml b/src/pas/plugins/ldap/plonecontrolpanel/profiles/default/ldapsettings.xml similarity index 100% rename from src/pas/plugins/ldap/plonecontrolpanel/profiles/base/ldapsettings.xml rename to src/pas/plugins/ldap/plonecontrolpanel/profiles/default/ldapsettings.xml diff --git a/src/pas/plugins/ldap/plonecontrolpanel/profiles/base/metadata.xml b/src/pas/plugins/ldap/plonecontrolpanel/profiles/default/metadata.xml similarity index 100% rename from src/pas/plugins/ldap/plonecontrolpanel/profiles/base/metadata.xml rename to src/pas/plugins/ldap/plonecontrolpanel/profiles/default/metadata.xml diff --git a/src/pas/plugins/ldap/plonecontrolpanel/profiles/plone5/registry.xml b/src/pas/plugins/ldap/plonecontrolpanel/profiles/default/registry.xml similarity index 66% rename from src/pas/plugins/ldap/plonecontrolpanel/profiles/plone5/registry.xml rename to src/pas/plugins/ldap/plonecontrolpanel/profiles/default/registry.xml index 535ceab..28c7a7d 100644 --- a/src/pas/plugins/ldap/plonecontrolpanel/profiles/plone5/registry.xml +++ b/src/pas/plugins/ldap/plonecontrolpanel/profiles/default/registry.xml @@ -1,5 +1,13 @@ + + + + servers, delimited by space + + 127.0.0.1:11211 + + @@ -16,4 +24,4 @@ True - + \ No newline at end of file diff --git a/src/pas/plugins/ldap/plonecontrolpanel/profiles/plone5/metadata.xml b/src/pas/plugins/ldap/plonecontrolpanel/profiles/plone5/metadata.xml deleted file mode 100644 index 87d38b6..0000000 --- a/src/pas/plugins/ldap/plonecontrolpanel/profiles/plone5/metadata.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - 2 - - profile-pas.plugins.ldap.plonecontrolpanel:install-base - - diff --git a/src/pas/plugins/ldap/plonecontrolpanel/upgrades.py b/src/pas/plugins/ldap/plonecontrolpanel/upgrades.py index 033e0f6..17afc93 100644 --- a/src/pas/plugins/ldap/plonecontrolpanel/upgrades.py +++ b/src/pas/plugins/ldap/plonecontrolpanel/upgrades.py @@ -14,7 +14,7 @@ def remove_persistent_import_step_from_base_profile(context): A bit double, but then it works cleanly, both within Plone and outside of Plone. """ - from pas.plugins.ldap.setuphandlers import remove_persistent_import_step + from ..setuphandlers import remove_persistent_import_step remove_persistent_import_step(context) context.setLastVersionForProfile("pas.plugins.ldap:default", "2") diff --git a/src/pas/plugins/ldap/plugin.py b/src/pas/plugins/ldap/plugin.py index b2fd2cb..8f12f87 100644 --- a/src/pas/plugins/ldap/plugin.py +++ b/src/pas/plugins/ldap/plugin.py @@ -6,10 +6,10 @@ from node.ext.ldap.interfaces import ILDAPProps from node.ext.ldap.interfaces import ILDAPUsersConfig from node.ext.ldap.ugm import Ugm -from pas.plugins.ldap.cache import get_plugin_cache -from pas.plugins.ldap.interfaces import ILDAPPlugin -from pas.plugins.ldap.interfaces import VALUE_NOT_CACHED -from pas.plugins.ldap.sheet import LDAPUserPropertySheet +from .cache import get_plugin_cache +from .interfaces import ILDAPPlugin +from .interfaces import VALUE_NOT_CACHED +from .sheet import LDAPUserPropertySheet from Products.PageTemplates.PageTemplateFile import PageTemplateFile from Products.PlonePAS import interfaces as plonepas_interfaces from Products.PlonePAS.plugins.group import PloneGroup diff --git a/src/pas/plugins/ldap/properties.py b/src/pas/plugins/ldap/properties.py index ce2edf5..2f3b19e 100644 --- a/src/pas/plugins/ldap/properties.py +++ b/src/pas/plugins/ldap/properties.py @@ -9,9 +9,9 @@ from node.ext.ldap.scope import SUBTREE from node.ext.ldap.ugm import Ugm from odict import odict -from pas.plugins.ldap.defaults import DEFAULTS -from pas.plugins.ldap.interfaces import ICacheSettingsRecordProvider -from pas.plugins.ldap.interfaces import ILDAPPlugin +from .defaults import DEFAULTS +from .interfaces import ICacheSettingsRecordProvider +from .interfaces import ILDAPPlugin from Products.Five import BrowserView from yafowil import loader # noqa: F401 from yafowil.base import ExtractionError diff --git a/src/pas/plugins/ldap/setuphandlers.py b/src/pas/plugins/ldap/setuphandlers.py index b80acfb..df1cf5f 100644 --- a/src/pas/plugins/ldap/setuphandlers.py +++ b/src/pas/plugins/ldap/setuphandlers.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from pas.plugins.ldap.plugin import LDAPPlugin +from .plugin import LDAPPlugin from zope.component.hooks import getSite diff --git a/src/pas/plugins/ldap/sheet.py b/src/pas/plugins/ldap/sheet.py index 2771c4d..6adcd6d 100644 --- a/src/pas/plugins/ldap/sheet.py +++ b/src/pas/plugins/ldap/sheet.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from Acquisition import aq_base -from node.ext.ldap.interfaces import ILDAPGroupsConfig -from node.ext.ldap.interfaces import ILDAPUsersConfig +from .interfaces import ILDAPGroupsConfig +from .interfaces import ILDAPUsersConfig from Products.PlonePAS.interfaces.propertysheets import IMutablePropertySheet from Products.PluggableAuthService.UserPropertySheet import UserPropertySheet from zope.globalrequest import getRequest diff --git a/src/pas/plugins/ldap/testing.py b/src/pas/plugins/ldap/testing.py index 28b7f32..3f50478 100644 --- a/src/pas/plugins/ldap/testing.py +++ b/src/pas/plugins/ldap/testing.py @@ -4,10 +4,10 @@ from node.ext.ldap.interfaces import ILDAPGroupsConfig from node.ext.ldap.interfaces import ILDAPProps from node.ext.ldap.interfaces import ILDAPUsersConfig -from pas.plugins.ldap.cache import cacheProviderFactory -from pas.plugins.ldap.interfaces import ICacheSettingsRecordProvider -from pas.plugins.ldap.plonecontrolpanel.cache import CacheSettingsRecordProvider -from pas.plugins.ldap.properties import LDAPProps +from .cache import cacheProviderFactory +from .interfaces import ICacheSettingsRecordProvider +from .plonecontrolpanel.cache import CacheSettingsRecordProvider +from .properties import LDAPProps from plone.registry import Registry from plone.registry.interfaces import IRegistry from plone.testing import Layer @@ -18,16 +18,10 @@ from zope.component import provideUtility from zope.interface import implementer from zope.interface import Interface - - -try: - # plone 5.x with PlonePAS >=5.0 - from Products.PlonePAS.setuphandlers import migrate_root_uf - from Products.PlonePAS.setuphandlers import registerPluginTypes -except ImportError: - # plone 4.x with PlonePAS <5.0 - from Products.PlonePAS.Extensions.Install import migrate_root_uf - from Products.PlonePAS.Extensions.Install import registerPluginTypes +from Products.PlonePAS.setuphandlers import migrate_root_uf +from Products.PlonePAS.setuphandlers import registerPluginTypes +from zope.configuration import xmlconfig +from zope.dottedname.resolve import resolve SITE_OWNER_NAME = SITE_OWNER_PASSWORD = "admin" @@ -94,9 +88,6 @@ def setUpZCML(self): """ # Load dependent products's ZCML - from zope.configuration import xmlconfig - from zope.dottedname.resolve import resolve - def loadAll(filename): for p, config in self.products: if not config["loadZCML"]: diff --git a/src/pas/plugins/ldap/tests/test_doctests.py b/src/pas/plugins/ldap/tests/test_doctests.py index f4a4e93..9c61239 100644 --- a/src/pas/plugins/ldap/tests/test_doctests.py +++ b/src/pas/plugins/ldap/tests/test_doctests.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from pas.plugins.ldap.testing import PASLDAPLayer +from ..testing import PASLDAPLayer from plone.testing import layered from plone.testing import z2 diff --git a/src/pas/plugins/ldap/tests/test_plugin.py b/src/pas/plugins/ldap/tests/test_plugin.py index 8964f59..d298356 100644 --- a/src/pas/plugins/ldap/tests/test_plugin.py +++ b/src/pas/plugins/ldap/tests/test_plugin.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from pas.plugins.ldap.testing import PASLDAP_FIXTURE +from ..testing import PASLDAP_FIXTURE from Products.PlonePAS.plugins.ufactory import PloneUser import unittest diff --git a/src/pas/plugins/ldap/zmi/manage_plugin.py b/src/pas/plugins/ldap/zmi/manage_plugin.py index 97e0989..3c39d5f 100644 --- a/src/pas/plugins/ldap/zmi/manage_plugin.py +++ b/src/pas/plugins/ldap/zmi/manage_plugin.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from pas.plugins.ldap.properties import BasePropertiesForm +from ..properties import BasePropertiesForm class ManageLDAPPlugin(BasePropertiesForm): From fa5cdb8aa48c4aaa796778e35772bde514c820e8 Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Wed, 2 Feb 2022 11:03:49 +0100 Subject: [PATCH 02/52] automated pyupgrade find . -name "*.py" -exec pyupgrade --py3-only --py37-plus {} + --- src/pas/plugins/ldap/__init__.py | 1 - src/pas/plugins/ldap/cache.py | 16 ++++++------ src/pas/plugins/ldap/defaults.py | 1 - src/pas/plugins/ldap/interfaces.py | 1 - src/pas/plugins/ldap/monkey.py | 3 +-- .../ldap/plonecontrolpanel/__init__.py | 7 +++--- .../plugins/ldap/plonecontrolpanel/cache.py | 5 ++-- .../ldap/plonecontrolpanel/controlpanel.py | 5 ++-- .../ldap/plonecontrolpanel/exportimport.py | 7 +++--- .../ldap/plonecontrolpanel/inspector.py | 6 ++--- .../ldap/plonecontrolpanel/upgrades.py | 3 --- src/pas/plugins/ldap/plugin.py | 25 ++++++++----------- src/pas/plugins/ldap/properties.py | 13 +++++----- src/pas/plugins/ldap/setuphandlers.py | 1 - src/pas/plugins/ldap/sheet.py | 1 - src/pas/plugins/ldap/testing.py | 3 +-- src/pas/plugins/ldap/tests/__init__.py | 1 - src/pas/plugins/ldap/tests/test_doctests.py | 1 - src/pas/plugins/ldap/tests/test_plugin.py | 3 +-- src/pas/plugins/ldap/zmi/__init__.py | 1 - src/pas/plugins/ldap/zmi/manage_plugin.py | 1 - 21 files changed, 38 insertions(+), 67 deletions(-) diff --git a/src/pas/plugins/ldap/__init__.py b/src/pas/plugins/ldap/__init__.py index 0249a2b..9cf037d 100644 --- a/src/pas/plugins/ldap/__init__.py +++ b/src/pas/plugins/ldap/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from AccessControl.Permissions import add_user_folders from . import monkey # noqa from . import LDAPPlugin diff --git a/src/pas/plugins/ldap/cache.py b/src/pas/plugins/ldap/cache.py index 9865038..b11a174 100644 --- a/src/pas/plugins/ldap/cache.py +++ b/src/pas/plugins/ldap/cache.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - from bda.cache import Memcached from bda.cache import NullCache from node.ext.ldap.interfaces import ICacheProviderFactory @@ -22,7 +20,7 @@ class PasLdapMemcached(Memcached): def __init__(self, servers): self._servers = servers - super(PasLdapMemcached, self).__init__(servers) + super().__init__(servers) @property def servers(self): @@ -32,18 +30,18 @@ def disconnect_all(self): self._client.disconnect_all() def __repr__(self): - return "<{0} {1}>".format(self.__class__.__name__, self.servers) + return f"<{self.__class__.__name__} {self.servers}>" @implementer(ICacheProviderFactory) -class cacheProviderFactory(object): +class cacheProviderFactory: # memcache factory for node.ext.ldap _thread_local = threading.local() @property def _key(self): - return "_v_{0}_PasLdapMemcached".format(self.__class__.__name__) + return f"_v_{self.__class__.__name__}_PasLdapMemcached" @property def servers(self): @@ -96,7 +94,7 @@ def get_plugin_cache(context): @implementer(IPluginCacheHandler) -class NullPluginCache(object): +class NullPluginCache: def __init__(self, context): self.context = context @@ -108,12 +106,12 @@ def set(self, value): @implementer(IPluginCacheHandler) -class RequestPluginCache(object): +class RequestPluginCache: def __init__(self, context): self.context = context def _key(self): - return "_v_ldap_ugm_{0}_".format(self.context.getId()) + return f"_v_ldap_ugm_{self.context.getId()}_" def get(self): request = getRequest() diff --git a/src/pas/plugins/ldap/defaults.py b/src/pas/plugins/ldap/defaults.py index 67796f3..425fe48 100644 --- a/src/pas/plugins/ldap/defaults.py +++ b/src/pas/plugins/ldap/defaults.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from node.ext.ldap.scope import ONELEVEL diff --git a/src/pas/plugins/ldap/interfaces.py b/src/pas/plugins/ldap/interfaces.py index c96985a..f25cc41 100644 --- a/src/pas/plugins/ldap/interfaces.py +++ b/src/pas/plugins/ldap/interfaces.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from zope.interface import Interface diff --git a/src/pas/plugins/ldap/monkey.py b/src/pas/plugins/ldap/monkey.py index 46c03f9..4da75cf 100644 --- a/src/pas/plugins/ldap/monkey.py +++ b/src/pas/plugins/ldap/monkey.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # TEMPORARY MONKEY PATCH # until this is changed upstream! from Acquisition import aq_inner @@ -46,7 +45,7 @@ def getPortraitFromSheet(context, userid): @implementer(ITraversable) -class PortraitTraverser(object): +class PortraitTraverser: def __init__(self, context, request=None): self.context = context self.request = request diff --git a/src/pas/plugins/ldap/plonecontrolpanel/__init__.py b/src/pas/plugins/ldap/plonecontrolpanel/__init__.py index c2af1ad..548c5b5 100644 --- a/src/pas/plugins/ldap/plonecontrolpanel/__init__.py +++ b/src/pas/plugins/ldap/plonecontrolpanel/__init__.py @@ -1,15 +1,14 @@ -# -*- coding: utf-8 -*- from Products.CMFPlone.interfaces.installable import INonInstallable from zope.interface import implementer @implementer(INonInstallable) -class HiddenProfiles(object): +class HiddenProfiles: """This hides zope2 profile from the quick installer tool and plone cpanel""" _hidden = [ - u"pas.plugins.ldap:default", - u"pas.plugins.ldap.plonecontrolpanel:install-base", + "pas.plugins.ldap:default", + "pas.plugins.ldap.plonecontrolpanel:install-base", ] def getNonInstallableProducts(self): diff --git a/src/pas/plugins/ldap/plonecontrolpanel/cache.py b/src/pas/plugins/ldap/plonecontrolpanel/cache.py index 89ea514..2717b8a 100644 --- a/src/pas/plugins/ldap/plonecontrolpanel/cache.py +++ b/src/pas/plugins/ldap/plonecontrolpanel/cache.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from ..interfaces import ICacheSettingsRecordProvider from persistent import Persistent from plone.registry import field @@ -11,7 +10,7 @@ REGKEY = "pas.plugins.ldap.memcached" -class NullRecord(object): +class NullRecord: value = "" @@ -25,6 +24,6 @@ def __call__(self): records = registry.records if REGKEY not in records: # init if not exist - value = field.TextLine(title=u"servers, delimited by space") + value = field.TextLine(title="servers, delimited by space") records[REGKEY] = Record(value) return records[REGKEY] diff --git a/src/pas/plugins/ldap/plonecontrolpanel/controlpanel.py b/src/pas/plugins/ldap/plonecontrolpanel/controlpanel.py index 48f1753..17e6a69 100644 --- a/src/pas/plugins/ldap/plonecontrolpanel/controlpanel.py +++ b/src/pas/plugins/ldap/plonecontrolpanel/controlpanel.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from ..properties import BasePropertiesForm from Products.CMFCore.interfaces import ISiteRoot from Products.CMFPlone.resources import add_bundle_on_request @@ -16,7 +15,7 @@ def getPortal(): class LDAPControlPanel(BasePropertiesForm): def __init__(self, context, request): - super(LDAPControlPanel, self).__init__(context, request) + super().__init__(context, request) add_bundle_on_request(request, "yafowil") def next(self, request): @@ -33,4 +32,4 @@ def plugin(self): def save(self, widget, data): BasePropertiesForm.save(self, widget, data) messages = IStatusMessage(self.request) - messages.addStatusMessage(_(u"LDAP Settings saved."), type="info") + messages.addStatusMessage(_("LDAP Settings saved."), type="info") diff --git a/src/pas/plugins/ldap/plonecontrolpanel/exportimport.py b/src/pas/plugins/ldap/plonecontrolpanel/exportimport.py index 43eb9aa..3316839 100644 --- a/src/pas/plugins/ldap/plonecontrolpanel/exportimport.py +++ b/src/pas/plugins/ldap/plonecontrolpanel/exportimport.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from BTrees.OOBTree import OOBTree from Products.GenericSetup.interfaces import IBody from Products.GenericSetup.utils import XMLAdapterBase @@ -14,7 +13,7 @@ def _get_import_export_handler(context): pasldap = aclu.pasldap handler = queryMultiAdapter((pasldap, context), IBody) if handler is not None: - handler.filename = "%s%s" % (handler.name, handler.suffix) + handler.filename = f"{handler.name}{handler.suffix}" return handler logger.warning("Can't find handler for ldap settings") @@ -91,7 +90,7 @@ def _setDataAndType(self, data, node): node.setAttribute("type", "string") else: self._logger.warning( - "Invalid type {0:s} found for key {1:s} on export, skipped.".format( + "Invalid type {:s} found for key {:s} on export, skipped.".format( type(data), data ) ) @@ -130,7 +129,7 @@ def _getDataByType(self, node): data = str(data) else: self._logger.warning( - "Invalid type {0:s} found on import, skipped.".format(vtype) + f"Invalid type {vtype:s} found on import, skipped." ) data = None return data diff --git a/src/pas/plugins/ldap/plonecontrolpanel/inspector.py b/src/pas/plugins/ldap/plonecontrolpanel/inspector.py index d58feea..1622b56 100644 --- a/src/pas/plugins/ldap/plonecontrolpanel/inspector.py +++ b/src/pas/plugins/ldap/plonecontrolpanel/inspector.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from node.ext.ldap import LDAPNode from node.ext.ldap.interfaces import ILDAPGroupsConfig from node.ext.ldap.interfaces import ILDAPProps @@ -9,11 +8,10 @@ from zope.component import getUtility import json -import six def safe_encode(val): - if isinstance(val, six.text_type): + if isinstance(val, str): return val.encode("utf-8") return val @@ -55,7 +53,7 @@ def node_attributes(self): if not node.attrs.is_binary(key): ret[safe_unicode(key)] = safe_unicode(val) else: - ret[safe_unicode(key)] = "(Binary Data with {0} Bytes)".format( + ret[safe_unicode(key)] = "(Binary Data with {} Bytes)".format( len(val) ) except UnicodeDecodeError: diff --git a/src/pas/plugins/ldap/plonecontrolpanel/upgrades.py b/src/pas/plugins/ldap/plonecontrolpanel/upgrades.py index 17afc93..24cbce5 100644 --- a/src/pas/plugins/ldap/plonecontrolpanel/upgrades.py +++ b/src/pas/plugins/ldap/plonecontrolpanel/upgrades.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- - - def remove_persistent_import_step_from_base_profile(context): """Remove broken persistent import step from base profile. diff --git a/src/pas/plugins/ldap/plugin.py b/src/pas/plugins/ldap/plugin.py index 8f12f87..16b8109 100644 --- a/src/pas/plugins/ldap/plugin.py +++ b/src/pas/plugins/ldap/plugin.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from AccessControl import ClassSecurityInfo from AccessControl.class_init import InitializeClass from BTrees import OOBTree @@ -17,7 +16,6 @@ from Products.PluggableAuthService.permissions import ManageGroups from Products.PluggableAuthService.permissions import ManageUsers from Products.PluggableAuthService.plugins.BasePlugin import BasePlugin -from six.moves import map from zope.interface import implementer import ldap @@ -30,10 +28,7 @@ logger = logging.getLogger("pas.plugins.ldap") zmidir = os.path.join(os.path.dirname(__file__), "zmi") -if six.PY2: - process_time = time.clock -else: - process_time = time.process_time +process_time = time.process_time LDAP_ERROR_LOG_TIMEOUT = float( os.environ.get("PAS_PLUGINS_LDAP_ERROR_LOG_TIMEOUT", 300.0) @@ -66,7 +61,7 @@ def _wrapper(self, *args, **kwargs): waiting = time.time() - self._v_ldaperror_timeout if waiting < LDAP_ERROR_LOG_TIMEOUT: logger.debug( - "{0}: retry wait {1:0.5f} of {2:0.0f}s -> {3}".format( + "{}: retry wait {:0.5f} of {:0.0f}s -> {}".format( prefix, waiting, LDAP_ERROR_LOG_TIMEOUT, @@ -79,7 +74,7 @@ def _wrapper(self, *args, **kwargs): start = process_time() result = original_method(self, *args, **kwargs) delta_t = process_time() - start - msg = "Call of {0!r} took {1:0.4f}s".format(original_method, delta_t) + msg = f"Call of {original_method!r} took {delta_t:0.4f}s" if delta_t < LDAP_LONG_RUNNING_LOG_THRESHOLD: logger.debug(msg) else: @@ -90,12 +85,12 @@ def _wrapper(self, *args, **kwargs): except ldap.LDAPError as e: self._v_ldaperror_msg = str(e) self._v_ldaperror_timeout = time.time() - logger.exception("LDAPError in {0}".format(prefix)) + logger.exception(f"LDAPError in {prefix}") return default except Exception as e: self._v_ldaperror_msg = str(e) self._v_ldaperror_timeout = time.time() - logger.exception("Error in {0}".format(prefix)) + logger.exception(f"Error in {prefix}") return default return _wrapper @@ -396,7 +391,7 @@ def enumerateUsers( return default # XXX: sort_by in node.ext.ldap if login: - if not isinstance(login, six.string_types): + if not isinstance(login, str): # XXX raise NotImplementedError("sequence is not supported yet.") kw["login"] = login @@ -404,7 +399,7 @@ def enumerateUsers( if "login" in kw and "name" in kw: del kw["name"] if id: - if not isinstance(id, six.string_types): + if not isinstance(id, str): # XXX raise NotImplementedError("sequence is not supported yet.") kw["id"] = id @@ -558,7 +553,7 @@ def getPropertiesForUser(self, user_or_group, request=None): if not self.is_plugin_active(pas_interfaces.IPropertiesPlugin): return default ugid = user_or_group.getId() - if not isinstance(ugid, six.text_type): + if not isinstance(ugid, str): ugid = ugid.decode("utf-8") try: if self.enumerateUsers(id=ugid) or self.enumerateGroups(id=ugid): @@ -611,7 +606,7 @@ def doChangeUser(self, user_id, password, **kw): try: self.users.passwd(user_id, None, password) except KeyError: - msg = "{0:s} is not an LDAP user.".format(user_id) + msg = f"{user_id:s} is not an LDAP user." logger.warn(msg) raise RuntimeError(msg) @@ -673,7 +668,7 @@ def getGroupById(self, group_id): return default if group_id is None: return None - if not isinstance(group_id, six.text_type): + if not isinstance(group_id, str): group_id = group_id.decode("utf8") groups = self.groups if not groups or group_id not in list(groups.keys()): diff --git a/src/pas/plugins/ldap/properties.py b/src/pas/plugins/ldap/properties.py index 2f3b19e..7a7bbef 100644 --- a/src/pas/plugins/ldap/properties.py +++ b/src/pas/plugins/ldap/properties.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from node.ext.ldap.interfaces import ILDAPGroupsConfig from node.ext.ldap.interfaces import ILDAPProps from node.ext.ldap.interfaces import ILDAPUsersConfig @@ -88,7 +87,7 @@ def form(self): if not controller.next: return controller.rendered self.request.RESPONSE.redirect(controller.next) - return u"" + return "" def save(self, widget, data): props = ILDAPProps(self.plugin) @@ -241,7 +240,7 @@ def _setter(context, value): @implementer(ILDAPProps) @adapter(ILDAPPlugin) -class LDAPProps(object): +class LDAPProps: def __init__(self, plugin): self.plugin = plugin @@ -270,7 +269,7 @@ def memcached(self): if recordProvider is not None: record = recordProvider() return record.value - return u"feature not available" + return "feature not available" @memcached.setter def memcached(self, value): @@ -279,7 +278,7 @@ def memcached(self, value): record = recordProvider() record.value = value else: - return u"feature not available" + return "feature not available" binary_attributes = BINARY_DEFAULTS multivalued_attributes = MULTIVALUED_DEFAULTS @@ -287,7 +286,7 @@ def memcached(self, value): @implementer(ILDAPUsersConfig) @adapter(ILDAPPlugin) -class UsersConfig(object): +class UsersConfig: def __init__(self, plugin): self.plugin = plugin @@ -317,7 +316,7 @@ def expiresUnit(self): @implementer(ILDAPGroupsConfig) @adapter(ILDAPPlugin) -class GroupsConfig(object): +class GroupsConfig: def __init__(self, plugin): self.plugin = plugin diff --git a/src/pas/plugins/ldap/setuphandlers.py b/src/pas/plugins/ldap/setuphandlers.py index df1cf5f..74127d4 100644 --- a/src/pas/plugins/ldap/setuphandlers.py +++ b/src/pas/plugins/ldap/setuphandlers.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from .plugin import LDAPPlugin from zope.component.hooks import getSite diff --git a/src/pas/plugins/ldap/sheet.py b/src/pas/plugins/ldap/sheet.py index 6adcd6d..6c5c6ec 100644 --- a/src/pas/plugins/ldap/sheet.py +++ b/src/pas/plugins/ldap/sheet.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from Acquisition import aq_base from .interfaces import ILDAPGroupsConfig from .interfaces import ILDAPUsersConfig diff --git a/src/pas/plugins/ldap/testing.py b/src/pas/plugins/ldap/testing.py index 3f50478..bba0c8b 100644 --- a/src/pas/plugins/ldap/testing.py +++ b/src/pas/plugins/ldap/testing.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from node.ext.ldap import testing as ldaptesting from node.ext.ldap.interfaces import ICacheProviderFactory from node.ext.ldap.interfaces import ILDAPGroupsConfig @@ -97,7 +96,7 @@ def loadAll(filename): xmlconfig.file( filename, package, context=self["configurationContext"] ) - except IOError: + except OSError: pass loadAll("meta.zcml") diff --git a/src/pas/plugins/ldap/tests/__init__.py b/src/pas/plugins/ldap/tests/__init__.py index 40a96af..e69de29 100644 --- a/src/pas/plugins/ldap/tests/__init__.py +++ b/src/pas/plugins/ldap/tests/__init__.py @@ -1 +0,0 @@ -# -*- coding: utf-8 -*- diff --git a/src/pas/plugins/ldap/tests/test_doctests.py b/src/pas/plugins/ldap/tests/test_doctests.py index 9c61239..861c8db 100644 --- a/src/pas/plugins/ldap/tests/test_doctests.py +++ b/src/pas/plugins/ldap/tests/test_doctests.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from ..testing import PASLDAPLayer from plone.testing import layered from plone.testing import z2 diff --git a/src/pas/plugins/ldap/tests/test_plugin.py b/src/pas/plugins/ldap/tests/test_plugin.py index d298356..21d7b25 100644 --- a/src/pas/plugins/ldap/tests/test_plugin.py +++ b/src/pas/plugins/ldap/tests/test_plugin.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from ..testing import PASLDAP_FIXTURE from Products.PlonePAS.plugins.ufactory import PloneUser @@ -68,7 +67,7 @@ def test_IGroupEnumerationPlugin_id(self): [[("id", "group2"), ("pluginid", "pasldap")]], ) self.assertEqual( - sorted([_["id"] for _ in self.ldap.enumerateGroups(id="group*")]), + sorted(_["id"] for _ in self.ldap.enumerateGroups(id="group*")), [ "group0", "group1", diff --git a/src/pas/plugins/ldap/zmi/__init__.py b/src/pas/plugins/ldap/zmi/__init__.py index 40a96af..e69de29 100644 --- a/src/pas/plugins/ldap/zmi/__init__.py +++ b/src/pas/plugins/ldap/zmi/__init__.py @@ -1 +0,0 @@ -# -*- coding: utf-8 -*- diff --git a/src/pas/plugins/ldap/zmi/manage_plugin.py b/src/pas/plugins/ldap/zmi/manage_plugin.py index 3c39d5f..b6a7893 100644 --- a/src/pas/plugins/ldap/zmi/manage_plugin.py +++ b/src/pas/plugins/ldap/zmi/manage_plugin.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from ..properties import BasePropertiesForm From a3ea9b1d6dbfae9282e8a38ac65f36f684a97faa Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Wed, 9 Feb 2022 12:41:52 +0100 Subject: [PATCH 03/52] updates for plone 6, also make file based install --- .github/workflows/tests.yaml | 36 ++ .gitignore | 28 +- Makefile | 343 ++++++++++++++++++ README_MAKE.md | 78 ++++ build_ldap.sh | 11 + constraints.txt | 1 + instance.yaml | 17 + requirements.txt | 6 + sources.ini | 45 +++ src/pas/plugins/ldap/__init__.py | 10 +- src/pas/plugins/ldap/cache.py | 6 +- src/pas/plugins/ldap/cache_volatile.zcml | 3 +- src/pas/plugins/ldap/configure.zcml | 57 +-- .../ldap/plonecontrolpanel/configure.zcml | 117 +++--- .../ldap/plonecontrolpanel/exportimport.py | 4 +- .../profiles/default/componentregistry.xml | 7 +- .../profiles/default/controlpanel.xml | 7 +- .../profiles/default/ldapsettings.xml | 152 +++++--- .../profiles/default/registry.xml | 2 +- src/pas/plugins/ldap/plugin.py | 10 +- src/pas/plugins/ldap/properties.py | 6 +- src/pas/plugins/ldap/sheet.py | 4 +- src/pas/plugins/ldap/testing.py | 23 +- src/pas/plugins/ldap/tests/test_plugin.py | 4 +- src/pas/plugins/ldap/zmi/configure.zcml | 19 +- 25 files changed, 812 insertions(+), 184 deletions(-) create mode 100644 .github/workflows/tests.yaml create mode 100644 Makefile create mode 100644 README_MAKE.md create mode 100755 build_ldap.sh create mode 100644 constraints.txt create mode 100644 instance.yaml create mode 100644 requirements.txt create mode 100644 sources.ini diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml new file mode 100644 index 0000000..4d3f9c4 --- /dev/null +++ b/.github/workflows/tests.yaml @@ -0,0 +1,36 @@ +name: Test the pas.plugins.ldap code +on: + push + +jobs: + build: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python: + - "3.8" + - "3.9" + plone: + - "6.0.0a3" + + steps: + - uses: actions/checkout@v2 + + - name: Install xmllint + run: sudo apt-get install -y slapd ldap-utils + + - name: Setup Plone ${{ matrix.plone }} with Python ${{ matrix.python }} + id: setup + uses: plone/setup-plone@v1.0.0 + with: + python-version: ${{ matrix.python }} + plone-version: ${{ matrix.plone }} + + - name: Install package + run: | + make VENV=off install + + - name: Run tests + run: | + make VENV=off test-ignore-warnings diff --git a/.gitignore b/.gitignore index b40829b..94a6894 100644 --- a/.gitignore +++ b/.gitignore @@ -1,25 +1,27 @@ -*.pyc +__pycache__ .*.cfg .coverage -.mrsd +.installed.txt .python-version -/*eggs/ +*-dev.txt +*-mxdev.txt +*.egg-info +*.mo +*.pyc +*.pyo +/.make-sentinels/ /.project /.pydevproject /.Python /.settings/ /.vscode/ -/bin +/*eggs/ /coverage/ -/devsrc/ /dist/ /htmlcov/ -/include/ -/lib/ -/local/ -/parts/ -/share/ -/src/*.egg-info -/var/ -/buildout.cfg +/instance/ /pip-selfcheck.json +/sources/ +/src/*.egg-info +/venv/ +/.openldap/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5bc86d4 --- /dev/null +++ b/Makefile @@ -0,0 +1,343 @@ +# Makefile to configure and run Plone instance + +############################################################################## +# SETUP MAKE + +## Defensive settings for make: https://tech.davis-hansson.com/p/make/ +SHELL:=bash +.ONESHELL: +# for Makefile debugging purposes add -x to the .SHELLFLAGS +.SHELLFLAGS:=-eu -o pipefail -O inherit_errexit -c +.SILENT: +.DELETE_ON_ERROR: +MAKEFLAGS+=--warn-undefined-variables +MAKEFLAGS+=--no-builtin-rules + +# Colors +# OK=Green, warn=yellow, error=red +ifeq ($(TERM),) +# no colors if not in terminal + MARK_COLOR= + OK_COLOR= + WARN_COLOR= + ERROR_COLOR= + NO_COLOR= +else + MARK_COLOR=`tput setaf 6` + OK_COLOR=`tput setaf 2` + WARN_COLOR=`tput setaf 3` + ERROR_COLOR=`tput setaf 1` + NO_COLOR=`tput sgr0` +endif + +############################################################################## +# SETTINGS AND VARIABLE +# adjust to your project needs +PROJECT_NAME=pas.plugins.ldap +IMAGE_NAME=${PROJECT_NAME} +CONSTRAINTS=constraints.txt +PIP_REQUIREMENTS_IN_FILE=requirements.txt +ADDONBASE=./ +ADDONFOLDER=${ADDONBASE}src/ +# it is possible to define an alternative YAML file for the the instance.set default i +INSTANCE_YAML?=instance.yaml +INSTANCE_FOLDER?=instance + +PIP_PARAMS= --pre + +############################################################################## +# targets and prerequisites +# target has to be one file, otherwise step gets executes for each file separate +PREPARE_PREREQUISITES=${PIP_REQUIREMENTS_IN_FILE} ${CONSTRAINTS} sources.ini ${ADDONBASE}setup.cfg +PREPARE_TARGET=requirements-mxdev.txt +INSTALL_PREREQUSISTES=${PREPARE_TARGET} +INSTALL_TARGET=.installed.txt +INSTANCE_PREREQUISITES=${INSTALL_TARGET} ${INSTANCE_YAML} +INSTANCE_TARGET=${INSTANCE_FOLDER}/etc/zope.ini ${INSTANCE_FOLDER}/etc/zope.conf ${INSTANCE_FOLDER}/etc/site.zcml +TEST_PREREQUISITES=${INSTALL_TARGET} +RUN_PREREQUISITES=${INSTANCE_TARGET} + +############################################################################## +# CONVINIENCE + +# install and run +.PHONY: all # full install, test and run +all:style testrun + +# Add the following 'help' target to your Makefile +# And add help text after each target name starting with '\#\#' +.PHONY: help +help: ## This help message + @echo "${OK_COLOR}This is the Makefile for ${WARN_COLOR}${PROJECT_NAME}${NO_COLOR}" + @echo + @echo "${WARN_COLOR}Additional parameters:${NO_COLOR}" + @echo "${MARK_COLOR}PYTHON${NO_COLOR}: Python interpreter to be used (default: python3)" + @echo "${MARK_COLOR}VENV${NO_COLOR}: [on|off] wether to create a Python virtual environment or not (default: on)"s + @echo "${MARK_COLOR}VENV_FOLDER${NO_COLOR}: location of the virtual environment (default: ./venv)" + @echo + @echo "${WARN_COLOR}Targets:${NO_COLOR}" + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +############################################################################## +# targets and prerequisites +# target has to be one file, otherwise step gets executes for each file separate +PREPARE_PREREQUISITES=${PIP_REQUIREMENTS_IN_FILE} ${CONSTRAINTS} sources.ini ${ADDONBASE}setup.cfg +PREPARE_TARGET=requirements-mxdev.txt +INSTALL_PREREQUSISTES=${PREPARE_TARGET} +INSTALL_TARGET=.installed.txt +INSTANCE_PREREQUISITES=${INSTALL_TARGET} ${INSTANCE_YAML} +INSTANCE_TARGET=${INSTANCE_FOLDER}/etc/zope.ini ${INSTANCE_FOLDER}/etc/zope.conf ${INSTANCE_FOLDER}/etc/site.zcml +TEST_PREREQUISITES=${INSTALL_TARGET} +RUN_PREREQUISITES=${INSTANCE_TARGET} + +############################################################################## +# BASE + +SENTINELFOLDER=.make-sentinels/ +SENTINEL=${SENTINELFOLDER}ABOUT.txt +${SENTINEL}: + @mkdir -p ${SENTINELFOLDER} + @echo "Sentinels for the Makefile process." > ${SENTINEL} + +# PYTHON, VENV, PIP +# venv and pybin +PYTHON?=python3 +VENV?=on +ifeq ("${VENV}", "on") + VENV_FOLDER?=./venv + PYBIN=${VENV_FOLDER}/bin/ +else + VENV_FOLDER?= + ifneq ("${VENV_FOLDER}", "") + PYBIN=${VENV_FOLDER}/bin/ + PYTHON=${PYBIN}python + else + PYBIN= + endif +endif + +# installed? +ifeq (, $(shell which $(PYTHON) )) + $(error "PYTHON=$(PYTHON) not found in $(PATH)") +endif + +# version ok? +PYTHON_VERSION_MIN=3.7 +PYTHON_VERSION_OK=$(shell $(PYTHON) -c 'import sys; print(int(float("%d.%d"% sys.version_info[0:2]) >= float($(PYTHON_VERSION_MIN))))' ) +ifeq ($(PYTHON_VERSION_OK),0) + $(error "Need python $(PYTHON_VERSION) >= $(PYTHON_VERSION_MIN)") +endif + +VENV_SENTINEL=${SENTINELFOLDER}venv.sentinel +${VENV_SENTINEL}: ${SENTINEL} +ifeq ("${VENV}", "on") + @echo "$(OK_COLOR)Setup Python Virtual Environment under '${VENV_FOLDER}' $(NO_COLOR)" + @${PYTHON} -m venv ${VENV_FOLDER} +else + @echo "$(OK_COLOR)Use current local or global Python: `which ${PYTHON}` $(NO_COLOR)" +endif + @touch ${VENV_SENTINEL} + +PIP_SENTINEL=${SENTINELFOLDER}pip.sentinel +${PIP_SENTINEL}: ${VENV_SENTINEL} ${CONSTRAINTS} ${SENTINEL} + @echo "$(OK_COLOR)Install pip$(NO_COLOR)" + @${PYBIN}pip install -U "pip>=22.0.2" wheel setuptools + @touch ${PIP_SENTINEL} + +############################################################################## +# MXDEV + +MXDEV_SENTINEL=${SENTINELFOLDER}pip-mxdev.sentinel +${MXDEV_SENTINEL}: ${PIP_SENTINEL} + @echo "$(OK_COLOR)Install mxdev$(NO_COLOR)" + @${PYBIN}pip install "mxdev>=2.0.0" + @touch ${MXDEV_SENTINEL} + +.PHONY: prepare +prepare: ${PREPARE_TARGET} ## prepare soures and dependencies + +${PREPARE_PREREQUISITES}: + @touch $@ + +${PREPARE_TARGET}: ${MXDEV_SENTINEL} ${PREPARE_PREREQUISITES} + @echo "$(OK_COLOR)Prepare sources and dependencies$(NO_COLOR)" + @${PYBIN}mxdev -c sources.ini + +.PHONY: install +install: ${INSTALL_TARGET} ## pip install all dependencies and scripts + +${INSTALL_TARGET}: ${PREPARE_TARGET} + @echo "$(OK_COLOR)Install dependencies and scripts$(NO_COLOR)" + @${PYBIN}pip install -r ${PREPARE_TARGET} ${PIP_PARAMS} + @${PYBIN}pip freeze >${INSTALL_TARGET} + +############################################################################## +# INSTANCE + +COOKIECUTTER_SENTINEL=${SENTINELFOLDER}pip-cookiecutter.sentinel +${COOKIECUTTER_SENTINEL}: + @echo "$(OK_COLOR)Install cookiecutter$(NO_COLOR)" + @${PYBIN}pip install git+https://github.com/cookiecutter/cookiecutter.git#egg=cookiecutter + @touch ${COOKIECUTTER_SENTINEL} + +${INSTANCE_YAML}: + @touch ${INSTANCE_YAML} + +.PHONY: instance +instance: ${INSTANCE_TARGET} ## create configuration for an zope (plone) instance + +${INSTANCE_TARGET}: ${INSTANCE_PREREQUISITES} ${COOKIECUTTER_SENTINEL} ${INSTANCE_YAML} + @echo "$(OK_COLOR)Create Plone/Zope configuration from ${INSTANCE_YAML} at ${INSTANCE_FOLDER}$(NO_COLOR)" + @${PYBIN}cookiecutter -f --no-input --config-file ${INSTANCE_YAML} https://github.com/bluedynamics/cookiecutter-zope-instance +# @${PYBIN}cookiecutter -f --no-input --config-file ${INSTANCE_YAML} devsrc/cookiecutter-zope-instance +############################################################################## +# TESTING + +TESTRUNNER_SENTINEL=${SENTINELFOLDER}pip-testrunner.sentinel +${TESTRUNNER_SENTINEL}: ${PIP_SENTINEL} + @echo "$(OK_COLOR)Install zope.testrunner$(NO_COLOR)" + @${PYBIN}pip install zope.testrunner + @touch ${TESTRUNNER_SENTINEL} + +LDAPRELEASE=2.4.59 +BASE_DIR=. +OPENLDAP_BASE_DIR=${BASE_DIR}/.openldap +OPENLDAP_DOWNLOAD_DIR=${OPENLDAP_BASE_DIR}/downloads +OPENLDAP_ARCHIVE=${OPENLDAP_DOWNLOAD_DIR}/openldap-${LDAPRELEASE}.tgz +${OPENLDAP_ARCHIVE}: + @echo "$(OK_COLOR)Download openldap-${LDAPRELEASE}.tgz to ${OPENLDAP_DOWNLOAD_DIR} as ${OPENLDAP_ARCHIVE}$(NO_COLOR)" + @mkdir -p ${OPENLDAP_DOWNLOAD_DIR} + @curl -o ${OPENLDAP_ARCHIVE} https://www.openldap.org/software/download/OpenLDAP/openldap-release/openldap-${LDAPRELEASE}.tgz + +OPENLDAP_INSTALL_DIR=${OPENLDAP_BASE_DIR}/inst +OPENLDAP_BIN_DIR=${OPENLDAP_INSTALL_DIR}/bin +OPENLDAP_SLAPD=${OPENLDAP_INSTALL_DIR}/libexec/slapd +${OPENLDAP_SLAPD}: ${OPENLDAP_ARCHIVE} + @echo "$(OK_COLOR)Unpack ${OPENLDAP_ARCHIVE}$(NO_COLOR)" + @mkdir -p ${OPENLDAP_INSTALL_DIR} + @tar xf ${OPENLDAP_ARCHIVE} -C ${OPENLDAP_BASE_DIR} + @echo "$(OK_COLOR)Build OpenLDAP ${LDAPRELEASE}$(NO_COLOR)" + @./build_ldap.sh ${OPENLDAP_BASE_DIR}/openldap-${LDAPRELEASE} ${shell realpath ${OPENLDAP_INSTALL_DIR}} + +.PHONY: test +test: ${TEST_PREREQUISITES} ${TESTRUNNER_SENTINEL} ${OPENLDAP_SLAPD} ## run tests + @echo "$(OK_COLOR)Run addon tests$(NO_COLOR)" + @SLAPD_BIN=${OPENLDAP_SLAPD} LDAP_ADD_BIN=${OPENLDAP_BIN_DIR}/ldapadd LDAP_DELETE_BIN=${OPENLDAP_BIN_DIR}/ldapdelete SLAPD_URIS=ldap://127.0.0.1:12345 ${PYBIN}zope-testrunner --auto-color --auto-progress --test-path=${ADDONFOLDER} + +.PHONY: test-ignore-warnings +test-ignore-warnings: ${TEST_PREREQUISITES} ${TESTRUNNER_SENTINEL} ${OPENLDAP_SLAPD} ## run tests (hide warnings) + @echo "$(OK_COLOR)Run addon tests$(NO_COLOR)" + @SLAPD_BIN=${OPENLDAP_SLAPD} LDAP_ADD_BIN=${OPENLDAP_BIN_DIR}/ldapadd LDAP_DELETE_BIN=${OPENLDAP_BIN_DIR}/ldapdelete SLAPD_URIS=ldap://127.0.0.1:12345 PYTHONWARNINGS=ignore ${PYBIN}zope-testrunner --auto-color --auto-progress --test-path=${ADDONFOLDER} + +############################################################################## +# CODE FORMATTING + +BLACK_SENTINEL=${SENTINELFOLDER}pip-black.sentinel +${BLACK_SENTINEL}: ${PREPARE_TARGET} + @echo "$(OK_COLOR)Install black$(NO_COLOR)" + @${PYBIN}pip install black + @touch ${BLACK_SENTINEL} + +ISORT_SENTINEL=${SENTINELFOLDER}pip-isort.sentinel +${ISORT_SENTINEL}: ${PREPARE_TARGET} + @echo "$(OK_COLOR)Install isort$(NO_COLOR)" + @${PYBIN}pip install isort + @touch ${ISORT_SENTINEL} + +ZPRETTY_SENTINEL=${SENTINELFOLDER}pip-zpretty.sentinel +${ZPRETTY_SENTINEL}: ${PREPARE_TARGET} + @echo "$(OK_COLOR)Install zpretty$(NO_COLOR)" + @${PYBIN}pip install "zpretty>=2.2.0" + @touch ${ZPRETTY_SENTINEL} + +.PHONY: apply-style-black +apply-style-black: ${BLACK_SENTINEL} ## apply/format code style black (to Python files) + @echo "$(OK_COLOR)Apply style black rules to code in ${ADDONFOLDER}/*$(NO_COLOR)" + @${PYBIN}black ${ADDONFOLDER} + +.PHONY: apply-style-isort +apply-style-isort: ${ISORT_SENTINEL} ## apply/format code style isort (sorted imports in Python files) + @echo "$(OK_COLOR)Apply style isort rules to code in ${ADDONFOLDER}/*$(NO_COLOR)" + @${PYBIN}isort ${ADDONFOLDER} + +.PHONY: apply-style-zpretty +apply-style-zpretty: ${ZPRETTY_SENTINEL} ## apply/format code style zpretty (to XML/ZCML files) + @echo "$(OK_COLOR)Apply style zpretty rules to code in ${ADDONFOLDER}/*$(NO_COLOR)" + @find ${ADDONFOLDER} -name '*.zcml' -exec ${PYBIN}zpretty -iz {} + + @find ${ADDONFOLDER} -name "*.xml"|grep -v locales|xargs ${PYBIN}zpretty -ix + +.PHONY: style ## apply code styles black, isort and zpretty +style: apply-style-black apply-style-isort apply-style-zpretty + +.PHONY: format ## alias for "style" +FORMATTING: style + +.PHONY: lint-black +lint-black: ${BLACK_SENTINEL} ## lint code-style black (to Python files) + @echo "$(OK_COLOR)Lint black rules to code in ${ADDONFOLDER}/*$(NO_COLOR)" + @${PYBIN}black --check ${ADDONFOLDER} + +.PHONY: lint-isort +lint-isort: ${ISORT_SENTINEL} ## lint code-style isort (sorted imports in Python files) + @echo "$(OK_COLOR)Lint style isort rules to code in ${ADDONFOLDER}/*$(NO_COLOR)" + @${PYBIN}isort --check-only ${ADDONFOLDER} + +.PHONY: lint-zpretty +lint-zpretty: ${ZPRETTY_SENTINEL} ## lint code-style zpretty (to XML/ZCML files) + @echo "$(OK_COLOR)Lint style zpretty rules to code in ${ADDONFOLDER}/*$(NO_COLOR)" + @find ${ADDONFOLDER} -name '*.zcml' -exec ${PYBIN}zpretty --check -z {} + + @find ${ADDONFOLDER} -name '*.xml'|grep -v locales|xargs ${PYBIN}zpretty --check -x + +.PHONY: lint ## lint all: check if complies with code-styles black, isort and zpretty +lint: lint-black lint-isort lint-zpretty + +############################################################################## +# RUN + +.PHONY: run +run: ${RUN_PREREQUISITES} ## run/start Plone + @echo "$(OK_COLOR)Run Plone$(NO_COLOR)" + @${PYBIN}runwsgi -v instance/etc/zope.ini + +############################################################################## +# CLEAN +.PHONY: clean-venv +clean-venv: ## remove Python virtual environment +ifeq ("${VENV}", "on") + @echo "$(OK_COLOR)Remove Virtualenv.$(NO_COLOR)" + rm -rf ${VENV_FOLDER} ${SENTINELFOLDER}/pip*.sentinel ${VENV_SENTINEL} +else: + @echo "$(OK_WARN)No self-created Python virtualenv at '${VENV_FOLDER}'! Nothing to do.$(NO_COLOR)" +endif + +.PHONY: clean-pyc +clean-pyc: ## remove Python file artifacts + @echo "$(OK_COLOR)Remove Python file artifacts (like byte-code) of code in current directory.$(NO_COLOR)" + find . -name '*.pyc' -exec rm -f {} + + find . -name '*.pyo' -exec rm -f {} + + find . -name '*~' -exec rm -f {} + + find . -name '__pycache__' -exec rm -fr {} + + +.PHONY: clean-make +clean-make: ## remove make artifact @echo "$(OK_COLOR)Remove Plone/Zope configuration (keeps data) and sentinel files.$(NO_COLOR)" + rm -rf ${INSTALL_PREREQUSISTES} ${INSTANCE_TARGET} ${SENTINELFOLDER} constraints-mxdev.txt + +.PHONY: clean-instance +clean-instance: ## remove instance configuration (keeps data) + @echo "$(OK_COLOR)Remove Plone/Zope configuration (keeps data) and sentinel files.$(NO_COLOR)" + rm -f ${INSTANCE_TARGET} + +.PHONY: clean +clean: clean-venv clean-pyc clean-make clean-instance ## clean all (except local database and pip installed packages) + +############################################################################## +# DOCKER/CONTAINER + +# this needs a Dockerfile, which is not provided by plone-kickstarter +.PHONY: build-image +build-image: ## Build Docker Image +ifneq ("$(wildcard Dockerfile)", "") + @docker build . -t $(IMAGE_NAME) -f Dockerfile +else + @echo "$(ERROR_COLOR)A 'Dockerfile' is required to build an image.$(NO_COLOR)" +endif diff --git a/README_MAKE.md b/README_MAKE.md new file mode 100644 index 0000000..f398b94 --- /dev/null +++ b/README_MAKE.md @@ -0,0 +1,78 @@ +# Information about the Makefile + +How to use the pip, mxdev, cookiecutter-zope-instance and make based install. + +## Usage + +On the commandline, execute the ``make`` command. +Without any options, make will run all steps. + +```bash +make run +``` + +All options are printed with + +```bash +make help +``` + +```text +clean remove instance configuration (keeps data) +help This help message +install pip install all dependencies and scripts +instance create configuration for an zope (plone) instance +prepare prepare soures and dependencies +run run Plone +``` + +Order for ``make run`` is: *prepare*, *install*, *instance*, *run*. + +The Makefile is built to detect changes. +At the first ``make run`` all steps are excuted. +Subsequent calls are only starting the applicaton server in the *run* step. +If one of the input file is changed, steps needed to take those changes into effect are executed again.\ + +## Python + +The Makefile support different modes of Python: + +1. Create new virtualenv under `./venv` (default) from a global Python 3. `python3` is expected to be in the PATH. +2. Like (1), but the `VENV_FOLDER` is passed to every *make* call: `make VENV_FOLDER=./some_folder/ install`. +3. `make VENV=off install`: Direct usage of current configure Python 3 environment. + Like if one uses *pyenv* or another already activated virtual environment, or in CI if the environment is alredy isolated. +4. Like (3), but the environment is not activated, so we need to point *make* to the location with `make VENV=off VENV_FOLDER=~/myenv/myproject_venv` or alike. + +**Attention:** if those paramters are used, they *must* be passed to every make call! + +**Hint:** Edit the `Makefile` and look for `VENV?=on` (which sets the default). And `VENV_FOLDER?=` (look for the if before) and adjust to your needs. + +## Files + +Initially the files below were generated by `plone-kickstarter`. +They are meant to be modified for your needs. + +They aim to ease development and deployment of *Plone 6+* + +`constraints.txt` + Version pins for your project, used by *pip*. +`README_MAKE.md` + (this file) +`instance.yaml` + Zope/Plone application server configuration. Used by *cookiecutter-zope-instance* +`Makefile` + The configuration for *make* +`requirement.txt` + The core requirements. +`sources.ini` + *mxdev* is used to develop with sources from VCS like Git. + If you need sources from git, add them here. + +## Tools + +The configuration here uses: + +- `make` +- [pip](https://pip.pypa.io/en/stable/) +- [mxdev](https://pypi.org/project/mxdev) +- [cookiecutter-zope-instance](https://github.com/bluedynamics/cookiecutter-zope-instance/) diff --git a/build_ldap.sh b/build_ldap.sh new file mode 100755 index 0000000..2321df0 --- /dev/null +++ b/build_ldap.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +cd $1 + +./configure --with-tls --enable-slapd=yes --enable-overlays CPPFLAGS=-D_GNU_SOURCE --prefix=$2 +make clean +make depend +make -j4 +make install + +cd - \ No newline at end of file diff --git a/constraints.txt b/constraints.txt new file mode 100644 index 0000000..72436a6 --- /dev/null +++ b/constraints.txt @@ -0,0 +1 @@ +-c https://dist.plone.org/release/6.0.0a3/constraints.txt diff --git a/instance.yaml b/instance.yaml new file mode 100644 index 0000000..448b03e --- /dev/null +++ b/instance.yaml @@ -0,0 +1,17 @@ +--- +# This is a cookiecutter configuration context file for +# +# cookiecutter-zope-instance +# +# available options are documented at +# https://github.com/bluedynamics/cookiecutter-zope-instance/ +# +# read also README_MAKE.md in this folder +# +default_context: + wsgi_fast_listen: localhost:8080 + initial_user_name: admin + initial_user_password: admin + debug_mode: on + load_zcml: {package_includes: ['pas.plugins.ldap']} + db_storage: direct diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..17178b7 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,6 @@ +-c constraints.txt +waitress_fastlisten +-e .[test] + +# until https://github.com/plone/plone.restapi/issues/1321 is solved +plone.app.iterate diff --git a/sources.ini b/sources.ini new file mode 100644 index 0000000..e8d245d --- /dev/null +++ b/sources.ini @@ -0,0 +1,45 @@ +[settings] +version-overrides = + setuptools==60.6.0 + wheel==0.37.1 + zope.i18n==4.9.0 + pip==22.0.2 + +#github = git+https://github.com +github = git+ssh://git@github.com + +# [node] +# url = ${settings:github}/conestack/node.git +# branch = master + +# [node.ext.ldap] +# url = ${settings:github}/conestack/node.ext.ldap.git` +# branch = master + +# [node.ext.ugm] +# url = ${settings:github}/conestack/node.ext.ugm.git +# branch = master + +[yafowil] +url = ${settings:github}/conestack/yafowil.git +branch = 3.0 + +[yafowil.bootstrap] +url = ${settings:github}/conestack/yafowil.bootstrap.git +branch = 2.0 + +[yafowil.plone] +url = ${settings:github}/bluedynamics/yafowil.plone.git +branch = bootstrap-plone6 + +[yafowil.widget.array] +url = ${settings:github}/conestack/yafowil.widget.array.git +branch = 2.0 + +[yafowil.widget.dict] +url = ${settings:github}/conestack/yafowil.widget.dict.git +branch = 2.0 + +[node.ext.ldap] +url = ${settings:github}/conestack/node.ext.ldap.git +branch = master diff --git a/src/pas/plugins/ldap/__init__.py b/src/pas/plugins/ldap/__init__.py index 9cf037d..8b5d5ee 100644 --- a/src/pas/plugins/ldap/__init__.py +++ b/src/pas/plugins/ldap/__init__.py @@ -1,9 +1,9 @@ -from AccessControl.Permissions import add_user_folders from . import monkey # noqa -from . import LDAPPlugin -from . import manage_addLDAPPlugin -from . import manage_addLDAPPluginForm -from . import zmidir +from .plugin import LDAPPlugin +from .plugin import manage_addLDAPPlugin +from .plugin import manage_addLDAPPluginForm +from .plugin import zmidir +from AccessControl.Permissions import add_user_folders from Products.PluggableAuthService import registerMultiPlugin import os diff --git a/src/pas/plugins/ldap/cache.py b/src/pas/plugins/ldap/cache.py index b11a174..ee98492 100644 --- a/src/pas/plugins/ldap/cache.py +++ b/src/pas/plugins/ldap/cache.py @@ -1,10 +1,10 @@ -from bda.cache import Memcached -from bda.cache import NullCache -from node.ext.ldap.interfaces import ICacheProviderFactory from .interfaces import ICacheSettingsRecordProvider from .interfaces import ILDAPPlugin from .interfaces import IPluginCacheHandler from .interfaces import VALUE_NOT_CACHED +from bda.cache import Memcached +from bda.cache import NullCache +from node.ext.ldap.interfaces import ICacheProviderFactory from zope.component import adapter from zope.component import queryUtility from zope.globalrequest import getRequest diff --git a/src/pas/plugins/ldap/cache_volatile.zcml b/src/pas/plugins/ldap/cache_volatile.zcml index 52a2e0b..38398e5 100644 --- a/src/pas/plugins/ldap/cache_volatile.zcml +++ b/src/pas/plugins/ldap/cache_volatile.zcml @@ -1,5 +1,4 @@ - + - servers, delimited by space + servers, delimited by space 127.0.0.1:11211 diff --git a/src/pas/plugins/ldap/properties.py b/src/pas/plugins/ldap/properties.py index 783caa3..0a7514b 100644 --- a/src/pas/plugins/ldap/properties.py +++ b/src/pas/plugins/ldap/properties.py @@ -11,6 +11,7 @@ from node.ext.ldap.scope import SUBTREE from node.ext.ldap.ugm import Ugm from odict import odict +from pas.plugins.ldap import _ from Products.Five import BrowserView from yafowil import loader # noqa: F401 from yafowil.base import ExtractionError @@ -19,7 +20,6 @@ from yafowil.yaml import parse_from_YAML from zope.component import adapter from zope.component import queryUtility -from zope.i18nmessageid import MessageFactory from zope.interface import implementer import ldap @@ -27,7 +27,6 @@ logger = logging.getLogger("pas.plugins.ldap") -_ = MessageFactory("pas.plugins.ldap") _marker = dict() diff --git a/src/pas/plugins/ldap/properties.yaml b/src/pas/plugins/ldap/properties.yaml index c082540..4ed979d 100644 --- a/src/pas/plugins/ldap/properties.yaml +++ b/src/pas/plugins/ldap/properties.yaml @@ -7,7 +7,7 @@ widgets: - server: factory: "*userpassanon:fieldset" props: - legend: LDAP Server Settings + legend: i18n:lbl_ldap_server_settings:LDAP Server Settings class: formPanel custom: userpassanon: @@ -17,81 +17,81 @@ widgets: factory: '#field:text' value: expr:context.props.uri props: - label: Connection URI - help: "Example: ldap://127.0.0.1:12345" - required: No URI defined + label: i18n:lbl_connection_uri:Connection URI + help: i18n:help_connection_uri:Example, the protocol is ldap, the IP address 127.0.0.1 and the port 12345 + required: i18n:msg_connection_uri:No URI defined - anonymous: factory: '#field:checkbox' value: expr:context.anonymous default: False props: - label: Anonymous Connection? + label: i18n:lbl_anonymous_connection:Anonymous Connection? - conn_timeout: factory: '#field:number' value: expr:context.props.conn_timeout props: - label: LDAP connection timeout in seconds + label: i18n:lbl_ldap_connection_timeout_in_seconds:LDAP connection timeout in seconds datatype: integer - op_timeout: factory: '#field:number' value: expr:context.props.op_timeout props: - label: LDAP operation timeout in seconds + label: i18n:lbl_ldap_operation_timeout_in_seconds:LDAP operation timeout in seconds datatype: integer - user: factory: '#field:text' value: expr:context.props.user props: - label: Manager User + label: i18n:lbl_manager_user:Manager User - password: factory: '#field:password' value: expr:context.props.password props: - label: Manager Password + label: i18n:lbl_manager_password:Manager Password - ignore_cert: factory: '#field:checkbox' value: expr:context.props.ignore_cert props: - label: Ignore certificate check? - help: If set on authenticate a failing certificate chain check including CA is ignored. + label: i18n:lbl_ignore_certificate_check:Ignore certificate check? + help: i18n:help_ignore_certificate_check:If set on authenticate a failing certificate chain check including CA is ignored. - page_size: factory: '#field:number' value: expr:context.props.page_size props: - label: Page Size - help: Maximum page size, number of results to query the server at once for. + label: i18n:lbl_page_size:Page Size + help: i18n:help_page_size:Maximum page size, number of results to query the server at once for. datatype: integer min: 1 - required_message: 'Page size must be given.' + required_message: i18n:msg_page_size:'Page size must be given.' - users: factory: fieldset props: - legend: Users Settings + legend: i18n:lbl_users_settings:Users Settings class: formPanel widgets: - dn: factory: '#field:text' value: expr:context.users.baseDN props: - label: Users container DN - required: No Users DN defined + label: i18n:lbl_users_container_dn:Users container DN + required: i18n:msg_users_container_dn:No Users DN defined - scope: factory: '#field:select' value: expr:str(context.users.scope) props: - label: Users search scope + label: i18n:lbl_users_search_scope:Users search scope vocabulary: expr:context.scope_vocab - query: factory: '#field:text' value: expr:context.users.queryFilter props: - label: Users search query filter + label: i18n:lbl_users_search_query_filter:Users search query filter - object_classes: factory: '#array' value: expr:context.users.objectClasses props: - label: Object classes for User creation - array.label: Object class + label: i18n:lbl_object_classes_for_user_creation:Object classes for User creation + array.label: i18n:lbl_object_class:Object class widgets: - oc: factory: field:text @@ -99,19 +99,19 @@ widgets: factory: '#field:checkbox' value: expr:context.users.memberOfSupport props: - label: memberOf attribute supported? + label: i18n:lbl_memberOf_attribute_supported:memberOf attribute supported? - recursiveGroups: factory: '#field:checkbox' value: expr:context.users.recursiveGroups props: - label: Support recursive/nested groups? - help: If your LDAP/AD supports it this will use LDAP_MATCHING_RULE_IN_CHAIN. By default only AD supports this. + label: i18n:lbl_support_recursive_nested_groups:Support recursive/nested groups? + help: i18n:help_support_recursive_nested_groups:If your LDAP/AD supports it this will use LDAP_MATCHING_RULE_IN_CHAIN. By default only AD supports this. - memberOfExternalGroupDNs: factory: '#array' value: expr:context.users.memberOfExternalGroupDNs props: - array.help: "Group DNs outside of the groups base DN are ignored, except if listed here" - array.label: memberOf external allowed Group DNs + array.help: i18n:help_memberOf_external_allowed_group_dns:"Group DNs outside of the groups base DN are ignored, except if listed here" + array.label: i18n:lbl_memberOf_external_allowed_group_dns:memberOf external allowed Group DNs widgets: - dn: factory: field:text @@ -119,66 +119,66 @@ widgets: factory: '#field:checkbox' value: expr:context.users.account_expiration props: - label: User Accounts expires? + label: i18n:lbl_user_accounts_expires:User Accounts expires? - expires_attr: factory: '#field:text' value: expr:context.users.expiresAttr props: - label: Attribute containing expiration Time + label: i18n:lbl_attribute_containing_expiration_time:Attribute containing expiration Time - expires_unit: factory: '#field:select' value: expr:context.users.expiresUnit props: - label: Account expiration unit + label: i18n:lbl_account_expiration_unit:Account expiration unit vocabulary: expr:((0, 'Days since Epoch'), (1, 'Seconds since epoch')) - aliases_attrmap: factory: '#field:dict' value: expr:context.users_attrmap props: - label: User attribute aliases - required: User attribute aliases values are mandatory + label: i18n:lbl_user_attribute_aliases:User attribute aliases + required: i18n:msg_user_attribute_aliases:User attribute aliases values are mandatory static: True head: - key: Reserved Key - value: LDAP Attribute + key: i18n:head_reserved_key:Reserved Key + value: i18n:head_ldap_attribute:LDAP Attribute - propsheet_attrmap: factory: '#field:dict' value: expr:context.users_propsheet_attrmap props: - label: User Property-Sheet Attributes + label: i18n:lbl_user_property-sheet_attributes:User Property-Sheet Attributes head: - key: Name on Sheet - value: LDAP Attribute + key: i18n:head_name_on_sheet:Name on Sheet + value: i18n:head_ldap_attribute:LDAP Attribute - groups: factory: fieldset props: - legend: Groups Settings + legend: i18n:lbl_groups_settings:Groups Settings class: formPanel widgets: - dn: factory: '#field:text' value: expr:context.groups.baseDN props: - label: Groups container DN - required: No Groups DN defined + label: i18n:lbl_groups_container_dn:Groups container DN + required: i18n:msg_groups_container_dn:No Groups DN defined - scope: factory: '#field:select' value: expr:str(context.groups.scope) props: - label: Groups search scope + label: i18n:lbl_groups_search_scope:Groups search scope vocabulary: expr:context.scope_vocab - query: factory: '#field:text' value: expr:context.groups.queryFilter props: - label: Groups search query filter + label: i18n:lbl_groups_search_query_filter:Groups search query filter - object_classes: factory: '#array' value: expr:context.groups.objectClasses props: - label: Object classes for Groups - help: "One of those is mandatory: groupOfNames, groupOfUniqueNames, posixGroup, group" - array.label: Object class + label: i18n:lbl_object_classes_for_groups:Object classes for Groups + help: i18n:help_object_classes_for_groups:"One of those is mandatory like as one the following options groupOfNames, groupOfUniqueNames, posixGroup, group" + array.label: i18n:lbl_object_class:Object class widgets: - oc: factory: field:text @@ -186,49 +186,49 @@ widgets: factory: '#field:checkbox' value: expr:context.groups.memberOfSupport props: - label: memberOf attribute supported? + label: i18n:lbl_memberOf_attribute_supported:memberOf attribute supported? - aliases_attrmap: factory: '#field:dict' value: expr:context.groups_attrmap props: - label: Group attribute aliases - required: Group attribute aliases values are mandatory + label: i18n:lbl_group_attribute_aliases:Group attribute aliases + required: i18n:msg_group_attribute_aliases:Group attribute aliases values are mandatory static: True head: - key: Reserved key - value: LDAP attr name + key: i18n:head_reserved_key:Reserved key + value: i18n:head_ldap_attr_name:LDAP attr name - propsheet_attrmap: factory: '#field:dict' value: expr:context.groups_propsheet_attrmap props: - label: Group Property-Sheet Attributes + label: i18n:lbl_group_property-sheet_attributes:Group Property-Sheet Attributes head: - key: Name on Sheet - value: LDAP Attribute + key: i18n:head_name_on_sheet:Name on Sheet + value: i18n:head_ldap_attribute:LDAP Attribute - cache: factory: fieldset props: - legend: Cache Settings + legend: i18n:lbl_cache_settings:Cache Settings class: formPanel widgets: - cache: factory: '#field:checkbox' value: expr:context.props.cache props: - label: Cache LDAP queries + label: i18n:lbl_cache_ldap_queries:Cache LDAP queries - memcached: factory: '#field:text' value: expr:context.props.memcached props: - label: Memcached Server to use - help: global - same server for all ldap plugins + label: i18n:lbl_memcached_server_to_use:Memcached Server to use + help: i18n:help_memcached_server_to_use:global - same server for all ldap plugins field.class: memcached field datatype: unicode - timeout: factory: '#field:number' value: expr:context.props.timeout props: - label: Cache timeout in seconds + label: i18n:lbl_cache_timeout_in_seconds:Cache timeout in seconds datatype: integer - save: factory: submit @@ -237,5 +237,5 @@ widgets: expression: True handler: context.save next: context.next - label: Save + label: i18n:lbl_save:Save class: submit-widget button-field context diff --git a/src/pas/plugins/ldap/zmi/add_plugin.pt b/src/pas/plugins/ldap/zmi/add_plugin.pt index fee0d16..971207c 100644 --- a/src/pas/plugins/ldap/zmi/add_plugin.pt +++ b/src/pas/plugins/ldap/zmi/add_plugin.pt @@ -1,25 +1,25 @@

Header

-

Add LDAP plugin

+

Add LDAP plugin

-

+

Add users and groups from LDAP using the pas.plugins.ldap plugin.

- + - + diff --git a/src/pas/plugins/ldap/zmi/manage_plugin.pt b/src/pas/plugins/ldap/zmi/manage_plugin.pt index bf54109..3ad9ff2 100644 --- a/src/pas/plugins/ldap/zmi/manage_plugin.pt +++ b/src/pas/plugins/ldap/zmi/manage_plugin.pt @@ -22,9 +22,10 @@ } -
+
-

Connection Test

+

Connection Test

@@ -34,10 +35,10 @@

-

Manage LDAP/AD plugin properties for id id

+

Manage LDAP/AD plugin properties for id id

-

- Set properties for users and groups from LDAP/ActiveDirectory using the pas.plugins.ldap plugin. +

+ Set properties for users and groups from LDAP/ActiveDirectory using the pas.plugins.ldap plugin.

form From 04efa9417e7bd62216ebde3a28efc2ec0384389c Mon Sep 17 00:00:00 2001 From: "Leonardo J. Caballero G" Date: Sun, 22 Jun 2025 01:27:04 +0200 Subject: [PATCH 25/52] Reorganize the use of the logging library --- src/pas/plugins/ldap/__init__.py | 3 +++ src/pas/plugins/ldap/plonecontrolpanel/exportimport.py | 7 ++++--- src/pas/plugins/ldap/properties.py | 5 +---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/pas/plugins/ldap/__init__.py b/src/pas/plugins/ldap/__init__.py index d9ed91b..874b91d 100644 --- a/src/pas/plugins/ldap/__init__.py +++ b/src/pas/plugins/ldap/__init__.py @@ -8,12 +8,15 @@ from Products.PluggableAuthService import registerMultiPlugin from zope.i18nmessageid import MessageFactory +import logging import os PACKAGE_NAME = "pas.plugins.ldap" _ = MessageFactory(PACKAGE_NAME) +logger = logging.getLogger(PACKAGE_NAME) + def initialize(context): registerMultiPlugin(LDAPPlugin.meta_type) diff --git a/src/pas/plugins/ldap/plonecontrolpanel/exportimport.py b/src/pas/plugins/ldap/plonecontrolpanel/exportimport.py index 5ba4d25..eb88069 100644 --- a/src/pas/plugins/ldap/plonecontrolpanel/exportimport.py +++ b/src/pas/plugins/ldap/plonecontrolpanel/exportimport.py @@ -1,13 +1,14 @@ from BTrees.OOBTree import OOBTree from Products.GenericSetup.interfaces import IBody from Products.GenericSetup.utils import XMLAdapterBase +from pas.plugins.ldap import PACKAGE_NAME from zope.component import queryMultiAdapter from zope.interface import implementer def _get_import_export_handler(context): aclu = context.getSite().acl_users - logger = context.getLogger("pas.plugins.ldap") + logger = context.getLogger(PACKAGE_NAME) if "pasldap" not in aclu.objectIds(): return pasldap = aclu.pasldap @@ -19,7 +20,7 @@ def _get_import_export_handler(context): def import_settings(context): - logger = context.getLogger("pas.plugins.ldap") + logger = context.getLogger(PACKAGE_NAME) handler = _get_import_export_handler(context) if not handler: return @@ -36,7 +37,7 @@ def export_settings(context): return body = handler.body if body is None: - logger = context.getLogger("pas.plugins.ldap") + logger = context.getLogger(PACKAGE_NAME) logger.warning("Problem to get ldap settings.") return context.writeDataFile(handler.filename, body, handler.mime_type) diff --git a/src/pas/plugins/ldap/properties.py b/src/pas/plugins/ldap/properties.py index 0a7514b..0f51b5a 100644 --- a/src/pas/plugins/ldap/properties.py +++ b/src/pas/plugins/ldap/properties.py @@ -11,7 +11,7 @@ from node.ext.ldap.scope import SUBTREE from node.ext.ldap.ugm import Ugm from odict import odict -from pas.plugins.ldap import _ +from pas.plugins.ldap import _, logger from Products.Five import BrowserView from yafowil import loader # noqa: F401 from yafowil.base import ExtractionError @@ -23,11 +23,8 @@ from zope.interface import implementer import ldap -import logging -logger = logging.getLogger("pas.plugins.ldap") - _marker = dict() From 203524e93e02d7c310da835b7b16a4d11d70dfc2 Mon Sep 17 00:00:00 2001 From: "Leonardo J. Caballero G" Date: Sun, 22 Jun 2025 01:30:48 +0200 Subject: [PATCH 26/52] Updated CHANGES file #131 --- CHANGES.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index 8f62b18..6edc9af 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,6 +5,9 @@ History 1.9.0 (unreleased) ------------------ +- Added the initial i18n support #131 + [macagua] + - Drop support for Plone 5/ Python < 3.9 [jensens] From f7d194ed02dabdf9587d8a0d8e978c87b07dd8f9 Mon Sep 17 00:00:00 2001 From: "Leonardo J. Caballero G" Date: Sun, 22 Jun 2025 01:31:21 +0200 Subject: [PATCH 27/52] Updated the i18n script #131 --- src/pas/plugins/ldap/locales/__main__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pas/plugins/ldap/locales/__main__.py b/src/pas/plugins/ldap/locales/__main__.py index 4462d00..6ca0d07 100644 --- a/src/pas/plugins/ldap/locales/__main__.py +++ b/src/pas/plugins/ldap/locales/__main__.py @@ -15,7 +15,6 @@ locale_path = Path(__file__).parent.resolve() target_path = locale_path.parent.resolve() -#domains = [path.name[:-4] for path in locale_path.glob("*.pot")] domain = "pas.plugins.ldap" i18ndude = "uvx i18ndude" From 5fc47c1d28fd4a9acee48928ebc1378b52179232 Mon Sep 17 00:00:00 2001 From: "Leonardo J. Caballero G" Date: Sun, 22 Jun 2025 01:39:10 +0200 Subject: [PATCH 28/52] Added Spanish translation #132 --- CHANGES.rst | 3 + .../es/LC_MESSAGES/pas.plugins.ldap.po | 405 ++++++++++++++++++ 2 files changed, 408 insertions(+) create mode 100644 src/pas/plugins/ldap/locales/es/LC_MESSAGES/pas.plugins.ldap.po diff --git a/CHANGES.rst b/CHANGES.rst index 6edc9af..d8f3a02 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,6 +5,9 @@ History 1.9.0 (unreleased) ------------------ +- Added Spanish translation #132 + [macagua] + - Added the initial i18n support #131 [macagua] diff --git a/src/pas/plugins/ldap/locales/es/LC_MESSAGES/pas.plugins.ldap.po b/src/pas/plugins/ldap/locales/es/LC_MESSAGES/pas.plugins.ldap.po new file mode 100644 index 0000000..e6f8479 --- /dev/null +++ b/src/pas/plugins/ldap/locales/es/LC_MESSAGES/pas.plugins.ldap.po @@ -0,0 +1,405 @@ +# Translation of pas.plugins.ldap.pot to Spanish +# Leonardo J. Caballero G. , 2025. +msgid "" +msgstr "" +"Project-Id-Version: pas.plugins.ldap\n" +"POT-Creation-Date: 2025-06-21 20:09+0000\n" +"PO-Revision-Date: 2025-06-21 19:34+0200\n" +"Last-Translator: Leonardo J. Caballero G. \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Language-Code: en\n" +"Language-Name: English\n" +"Preferred-Encodings: utf-8 latin1\n" +"Domain: pas.plugins.ldap\n" +"Language: es\n" +"X-Generator: Poedit 3.6\n" +"X-Is-Fallback-For: es-ar es-bo es-cl es-co es-cr es-do es-ec es-es es-sv es-gt es-hn es-mx es-ni es-pa es-py es-pe es-pr es-us es-uy es-ve\n" + +#: pas/plugins/ldap/plonecontrolpanel/controlpanel.pt:16 +#: pas/plugins/ldap/zmi/manage_plugin.pt:28 +msgid "Connection Test" +msgstr "Prueba de conexión" + +#: pas/plugins/ldap/properties.py:223 +msgid "Exception in Groups; " +msgstr "Excepción en Grupos; " + +#: pas/plugins/ldap/properties.py:216 +msgid "Exception in Users; " +msgstr "Excepción en Usuarios; " + +#: pas/plugins/ldap/configure.zcml:34 +msgid "Extension profile for pas.plugins.ldap Zope Base." +msgstr "Perfil de extensión base de Zope para pas.plugins.ldap." + +#: pas/plugins/ldap/plonecontrolpanel/inspector.pt:18 +msgid "Groups" +msgstr "Grupos" + +#: pas/plugins/ldap/plonecontrolpanel/inspector.pt:11 +msgid "LDAP Child Inspector" +msgstr "Inspector secundario LDAP" + +#: pas/plugins/ldap/plonecontrolpanel/controlpanel.pt:25 +msgid "LDAP Inspector" +msgstr "Inspector LDAP" + +#: pas/plugins/ldap/configure.zcml:34 +msgid "LDAP Plugin for PAS - Zope 2 Base Installation" +msgstr "Plugin LDAP para PAS - Instalación base de Zope 2" + +#: pas/plugins/ldap/plonecontrolpanel/controlpanel.py:31 +msgid "LDAP Settings saved." +msgstr "Configuración de LDAP guardada." + +#: pas/plugins/ldap/properties.py:220 +msgid "LDAP Users ok, but groups not; " +msgstr "Los usuarios de LDAP están bien, pero los grupos no; " + +#: pas/plugins/ldap/properties.py:213 +msgid "LDAP users; " +msgstr "Usuarios de LDAP; " + +#: pas/plugins/ldap/plonecontrolpanel/profiles/default/controlpanel.xml +msgid "LDAP/ AD Support" +msgstr "Soporte con LDAP/AD" + +#: pas/plugins/ldap/plonecontrolpanel/controlpanel.pt:14 +msgid "LDAP/ Active Directory Configuration" +msgstr "Configuración de LDAP/Active Directory" + +#: pas/plugins/ldap/plonecontrolpanel/configure.zcml:19 +msgid "LDAP/ Active Directory Support" +msgstr "Soporte con LDAP/Active Directory" + +#: pas/plugins/ldap/zmi/manage_plugin.pt:38 +msgid "Manage LDAP/AD plugin properties for id ${plugin_properties_id}" +msgstr "Administre las propiedades del complemento LDAP / AD para id $ {plugin_properties_id}" + +#: pas/plugins/ldap/plonecontrolpanel/inspector.pt:23 +msgid "No search base selected" +msgstr "No se ha seleccionado ninguna base de búsqueda" + +#: pas/plugins/ldap/properties.py:204 +msgid "Non-LDAP error while getting ILDAPGroupsConfig!" +msgstr "¡Error no LDAP al obtener ILDAPGroupsConfig!" + +#: pas/plugins/ldap/properties.py:192 +msgid "Non-LDAP error while getting ILDAPProps!" +msgstr "¡Error no LDAP al obtener ILDAPProps!" + +#: pas/plugins/ldap/properties.py:198 +msgid "Non-LDAP error while getting ILDAPUsersConfig!" +msgstr "¡Error no LDAP al obtener ILDAPUsersConfig!" + +#: pas/plugins/ldap/properties.py:180 +msgid "Password is required for non-anonymous connections." +msgstr "La contraseña es necesaria para las conexiones no anónimas." + +#: pas/plugins/ldap/plonecontrolpanel/inspector.pt:13 +msgid "Select search base" +msgstr "Seleccione la base de búsqueda" + +#: pas/plugins/ldap/properties.py:211 +msgid "Server Down" +msgstr "Servidor caído" + +#: pas/plugins/ldap/zmi/manage_plugin.pt:41 +msgid "Set properties for users and groups from LDAP/ActiveDirectory using the ${plugin_name} plugin." +msgstr "Establezca las propiedades de los usuarios y grupos de LDAP/ActiveDirectory mediante el complemento ${plugin_name}." + +#: pas/plugins/ldap/plonecontrolpanel/controlpanel.pt:34 +msgid "Settings" +msgstr "Ajustes" + +#: pas/plugins/ldap/properties.py:185 +msgid "User/Password are required if not anonymous." +msgstr "El usuario/contraseña son obligatorios si no son anónimos." + +#: pas/plugins/ldap/properties.py:174 +msgid "Username is required for non-anonymous connections." +msgstr "El nombre de usuario es necesario para las conexiones no anónimas." + +#: pas/plugins/ldap/plonecontrolpanel/inspector.pt:17 +msgid "Users" +msgstr "Usuarios" + +#. Default: LDAP attr name +#: pas/plugins/ldap/properties.yaml:199 +msgid "head_ldap_attr_name" +msgstr "Nombre de atributo LDAP" + +#. Default: LDAP Attribute +#: pas/plugins/ldap/properties.yaml:143 +msgid "head_ldap_attribute" +msgstr "Atributo LDAP" + +#. Default: Name on Sheet +#: pas/plugins/ldap/properties.yaml:150 +msgid "head_name_on_sheet" +msgstr "Nombre en la hoja" + +#. Default: Reserved Key +#: pas/plugins/ldap/properties.yaml:142 +#, fuzzy +msgid "head_reserved_key" +msgstr "Clave reservada" + +#. Default: Example, the protocol is ldap, the IP address 127.0.0.1 and the +#. port 12345 +#: pas/plugins/ldap/properties.yaml:21 +msgid "help_connection_uri" +msgstr "Ejemplo, el protocolo es ldap, la dirección IP es 127.0.0.1 y el puerto es 12345" + +#. Default: If set on authenticate a failing certificate chain check including +#. CA is ignored. +#: pas/plugins/ldap/properties.yaml:56 +msgid "help_ignore_certificate_check" +msgstr "Si se establece en autenticar una comprobación de cadena de certificado fallido incluyendo CA se ignora." + +#. Default: "Group DNs outside of the groups base DN are ignored, except if +#. listed here" +#: pas/plugins/ldap/properties.yaml:113 +msgid "help_memberOf_external_allowed_group_dns" +msgstr "Los DN de grupo que no sean el DN base del grupo se ignoran, excepto si se indican aquí" + +#. Default: global - same server for all ldap plugins +#: pas/plugins/ldap/properties.yaml:224 +msgid "help_memcached_server_to_use" +msgstr "global - mismo servidor para todos los plugins ldap" + +#. Default: "One of those is mandatory like as one the following options +#. groupOfNames, groupOfUniqueNames, posixGroup, group" +#: pas/plugins/ldap/properties.yaml:180 +msgid "help_object_classes_for_groups" +msgstr "Uno de ellos es obligatorio como una de las siguientes opciones groupOfNames, groupOfUniqueNames, posixGroup y group" + +#. Default: Maximum page size, number of results to query the server at once +#. for. +#: pas/plugins/ldap/properties.yaml:62 +msgid "help_page_size" +msgstr "Tamaño máximo de la página, número de resultados que se pueden consultar a la vez en el servidor." + +#. Default: If your LDAP/AD supports it this will use +#. LDAP_MATCHING_RULE_IN_CHAIN. By default only AD supports this. +#: pas/plugins/ldap/properties.yaml:108 +msgid "help_support_recursive_nested_groups" +msgstr "Si su LDAP/AD lo admite, utilizará LDAP_MATCHING_RULE_IN_CHAIN. Por defecto sólo AD lo soporta." + +#. Default: Account expiration unit +#: pas/plugins/ldap/properties.yaml:132 +msgid "lbl_account_expiration_unit" +msgstr "Unidad de caducidad de la cuenta" + +#. Default: Anonymous Connection? +#: pas/plugins/ldap/properties.yaml:28 +msgid "lbl_anonymous_connection" +msgstr "¿Conexión anónima?" + +#. Default: Attribute containing expiration Time +#: pas/plugins/ldap/properties.yaml:127 +msgid "lbl_attribute_containing_expiration_time" +msgstr "Atributo que contiene la hora de expiración" + +#. Default: Cache LDAP queries +#: pas/plugins/ldap/properties.yaml:218 +msgid "lbl_cache_ldap_queries" +msgstr "Caché de consultas LDAP" + +#. Default: Cache Settings +#: pas/plugins/ldap/properties.yaml:211 +msgid "lbl_cache_settings" +msgstr "Configuración de la caché" + +#. Default: Cache timeout in seconds +#: pas/plugins/ldap/properties.yaml:231 +msgid "lbl_cache_timeout_in_seconds" +msgstr "Tiempo de espera de la caché en segundos" + +#. Default: Connection URI +#: pas/plugins/ldap/properties.yaml:20 +msgid "lbl_connection_uri" +msgstr "URI de conexión" + +#. Default: Group attribute aliases +#: pas/plugins/ldap/properties.yaml:194 +msgid "lbl_group_attribute_aliases" +msgstr "Alias de atributos de grupo" + +#. Default: Group Property-Sheet Attributes +#: pas/plugins/ldap/properties.yaml:204 +msgid "lbl_group_property-sheet_attributes" +msgstr "Atributos de la hoja de propiedades de grupo" + +#. Default: Groups container DN +#: pas/plugins/ldap/properties.yaml:162 +msgid "lbl_groups_container_dn" +msgstr "DN del contenedor de Grupos" + +#. Default: Groups search query filter +#: pas/plugins/ldap/properties.yaml:174 +msgid "lbl_groups_search_query_filter" +msgstr "Filtro de búsqueda de grupos" + +#. Default: Groups search scope +#: pas/plugins/ldap/properties.yaml:168 +msgid "lbl_groups_search_scope" +msgstr "Ámbito de búsqueda de grupos" + +#. Default: Groups Settings +#: pas/plugins/ldap/properties.yaml:155 +msgid "lbl_groups_settings" +msgstr "Configuración de grupos" + +#. Default: Ignore certificate check? +#: pas/plugins/ldap/properties.yaml:55 +msgid "lbl_ignore_certificate_check" +msgstr "¿Ignorar la comprobación del certificado?" + +#. Default: LDAP connection timeout in seconds +#: pas/plugins/ldap/properties.yaml:33 +msgid "lbl_ldap_connection_timeout_in_seconds" +msgstr "Tiempo de espera de la conexión LDAP en segundos" + +#. Default: LDAP operation timeout in seconds +#: pas/plugins/ldap/properties.yaml:39 +msgid "lbl_ldap_operation_timeout_in_seconds" +msgstr "Tiempo de espera de la operación LDAP en segundos" + +#. Default: LDAP Server Settings +#: pas/plugins/ldap/properties.yaml:10 +msgid "lbl_ldap_server_settings" +msgstr "Configuración del servidor LDAP" + +#. Default: Manager Password +#: pas/plugins/ldap/properties.yaml:50 +msgid "lbl_manager_password" +msgstr "Contraseña de administrador" + +#. Default: Manager User +#: pas/plugins/ldap/properties.yaml:45 +msgid "lbl_manager_user" +msgstr "Usuario de administrador" + +#. Default: memberOf attribute supported? +#: pas/plugins/ldap/properties.yaml:102 +msgid "lbl_memberOf_attribute_supported" +msgstr "¿se admite el atributo memberOf?" + +#. Default: memberOf external allowed Group DNs +#: pas/plugins/ldap/properties.yaml:114 +msgid "lbl_memberOf_external_allowed_group_dns" +msgstr "DNs de grupo permitidos memberOf externos" + +#. Default: Memcached Server to use +#: pas/plugins/ldap/properties.yaml:223 +msgid "lbl_memcached_server_to_use" +msgstr "Servidor Memcached a utilizar" + +#. Default: Object class +#: pas/plugins/ldap/properties.yaml:94 +msgid "lbl_object_class" +msgstr "Clase de objeto" + +#. Default: Object classes for Groups +#: pas/plugins/ldap/properties.yaml:179 +msgid "lbl_object_classes_for_groups" +msgstr "Clases de objetos para Grupos" + +#. Default: Object classes for User creation +#: pas/plugins/ldap/properties.yaml:93 +msgid "lbl_object_classes_for_user_creation" +msgstr "Clases de objetos para la creación de usuarios" + +#. Default: Page Size +#: pas/plugins/ldap/properties.yaml:61 +msgid "lbl_page_size" +msgstr "Tamaño de página" + +#. Default: Save +#: pas/plugins/ldap/properties.yaml:240 +msgid "lbl_save" +msgstr "Guardar" + +#. Default: Support recursive/nested groups? +#: pas/plugins/ldap/properties.yaml:107 +msgid "lbl_support_recursive_nested_groups" +msgstr "¿Admite grupos recursivos/anidados?" + +#. Default: User Accounts expires? +#: pas/plugins/ldap/properties.yaml:122 +msgid "lbl_user_accounts_expires" +msgstr "¿Caducan las cuentas de usuario?" + +#. Default: User attribute aliases +#: pas/plugins/ldap/properties.yaml:138 +msgid "lbl_user_attribute_aliases" +msgstr "Alias de atributos de usuario" + +#. Default: User Property-Sheet Attributes +#: pas/plugins/ldap/properties.yaml:148 +msgid "lbl_user_property-sheet_attributes" +msgstr "Atributos de la hoja de propiedades del usuario" + +#. Default: Users container DN +#: pas/plugins/ldap/properties.yaml:76 +msgid "lbl_users_container_dn" +msgstr "DN del contenedor de usuarios" + +#. Default: Users search query filter +#: pas/plugins/ldap/properties.yaml:88 +msgid "lbl_users_search_query_filter" +msgstr "Filtro de consulta de búsqueda de usuarios" + +#. Default: Users search scope +#: pas/plugins/ldap/properties.yaml:82 +msgid "lbl_users_search_scope" +msgstr "Ámbito de búsqueda de los usuarios" + +#. Default: Users Settings +#: pas/plugins/ldap/properties.yaml:69 +msgid "lbl_users_settings" +msgstr "Configuración de usuarios" + +#. Default: No URI defined +#: pas/plugins/ldap/properties.yaml:22 +msgid "msg_connection_uri" +msgstr "No hay URI definido" + +#. Default: Group attribute aliases values are mandatory +#: pas/plugins/ldap/properties.yaml:195 +msgid "msg_group_attribute_aliases" +msgstr "Los valores de los alias de atributos de grupo son obligatorios" + +#. Default: No Groups DN defined +#: pas/plugins/ldap/properties.yaml:163 +msgid "msg_groups_container_dn" +msgstr "No hay grupos DN definidos" + +#. Default: 'Page size must be given.' +#: pas/plugins/ldap/properties.yaml:65 +msgid "msg_page_size" +msgstr "'Debe indicarse el tamaño de la página.'" + +#. Default: User attribute aliases values are mandatory +#: pas/plugins/ldap/properties.yaml:139 +msgid "msg_user_attribute_aliases" +msgstr "Los valores de los alias de atributos de usuario son obligatorios" + +#. Default: No Users DN defined +#: pas/plugins/ldap/properties.yaml:77 +msgid "msg_users_container_dn" +msgstr "No se ha definido ningún DN de usuario" + +#: pas/plugins/ldap/plonecontrolpanel/configure.zcml:19 +msgid "pas.plugins.ldap support for users and groups from ldap/active directory." +msgstr "Soporte para usuarios y grupos de LDAP/Active Directory con el complemento pas.plugins.ldap." + +#: pas/plugins/ldap/plonecontrolpanel/cache.py:28 +#: pas/plugins/ldap/plonecontrolpanel/profiles/default/registry.xml +msgid "servers, delimited by space" +msgstr "servidores, delimitados por el espacio" From 78959985b6bd7b1db7884f8fa6105198b75df09c Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Mon, 23 Jun 2025 19:51:56 +0200 Subject: [PATCH 29/52] mxmake update, remove ldap --- Makefile | 341 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 172 insertions(+), 169 deletions(-) diff --git a/Makefile b/Makefile index 408b8d7..dd7c090 100644 --- a/Makefile +++ b/Makefile @@ -10,8 +10,6 @@ #: core.packages #: core.sources #: i18n.gettext -#: ldap.openldap -#: ldap.python-ldap #: qa.black #: qa.coverage #: qa.isort @@ -29,7 +27,7 @@ DEPLOY_TARGETS?= # target to be executed when calling `make run` # No default value. -RUN_TARGET?= +RUN_TARGET?=zope-start # Additional files and folders to remove when running clean target # No default value. @@ -40,36 +38,39 @@ CLEAN_FS?= # Default: include.mk INCLUDE_MAKEFILE?=include.mk -## ldap.openldap - -# OpenLDAP version to download -# Default: 2.4.59 -OPENLDAP_VERSION?=2.4.59 - -# OpenLDAP base download URL -# Default: https://www.openldap.org/software/download/OpenLDAP/openldap-release/ -OPENLDAP_URL?=https://www.openldap.org/software/download/OpenLDAP/openldap-release/ - -# Build directory for OpenLDAP -# Default: $(shell echo $(realpath .))/openldap -OPENLDAP_DIR?=$(shell echo $(realpath .))/openldap - -# Build environment for OpenLDAP -# Default: PATH=/usr/local/bin:/usr/bin:/bin -OPENLDAP_ENV?=PATH=/usr/local/bin:/usr/bin:/bin +# Optional additional directories to be added to PATH in format +# `/path/to/dir/:/path/to/other/dir`. Gets inserted first, thus gets searched +# first. +# No default value. +EXTRA_PATH?= ## core.mxenv -# Python interpreter to use. +# Primary Python interpreter to use. It is used to create the +# virtual environment if `VENV_ENABLED` and `VENV_CREATE` are set to `true`. # Default: python3 -PYTHON_BIN?=python3 +PRIMARY_PYTHON?=3.12 # Minimum required Python version. -# Default: 3.7 -PYTHON_MIN_VERSION?=3.9 +# Default: 3.9 +PYTHON_MIN_VERSION?=3.10 + +# Install packages using the given package installer method. +# Supported are `pip` and `uv`. If uv is used, its global availability is +# checked. Otherwise, it is installed, either in the virtual environment or +# using the `PRIMARY_PYTHON`, dependent on the `VENV_ENABLED` setting. If +# `VENV_ENABLED` and uv is selected, uv is used to create the virtual +# environment. +# Default: pip +PYTHON_PACKAGE_INSTALLER?=uv + +# Flag whether to use a global installed 'uv' or install +# it in the virtual environment. +# Default: false +MXENV_UV_GLOBAL?=true # Flag whether to use virtual environment. If `false`, the -# interpreter according to `PYTHON_BIN` found in `PATH` is used. +# interpreter according to `PRIMARY_PYTHON` found in `PATH` is used. # Default: true VENV_ENABLED?=true @@ -84,7 +85,7 @@ VENV_CREATE?=true # target folder for the virtual environment. If `VENV_ENABLED` is `true` and # `VENV_CREATE` is false it is expected to point to an existing virtual # environment. If `VENV_ENABLED` is `false` it is ignored. -# Default: venv +# Default: .venv VENV_FOLDER?=venv # mxdev to install in virtual environment. @@ -119,6 +120,13 @@ BLACK_SRC?=src # Default: mx.ini PROJECT_CONFIG?=mx.ini +## core.packages + +# Allow prerelease and development versions. +# By default, the package installer only finds stable versions. +# Default: false +PACKAGES_ALLOW_PRERELEASES?=false + ## qa.test # The command which gets executed. Defaults to the location the @@ -152,6 +160,10 @@ ZOPE_CONFIGURATION_FILE?=instance.yaml # Default: https://github.com/plone/cookiecutter-zope-instance ZOPE_TEMPLATE?=https://github.com/plone/cookiecutter-zope-instance +# cookiecutter branch, tag or commit to checkout from the ZOPE_TEMPLATE. If empty, `--checkout` is not passed to cookiecutter. +# Default: main +ZOPE_TEMPLATE_CHECKOUT?=main + # The Zope folder "instance" will be generated relative to this existing folder. # Default: . ZOPE_BASE_FOLDER?=. @@ -160,6 +172,14 @@ ZOPE_BASE_FOLDER?=. # Default: No Default ZOPE_SCRIPTNAME?=No Default +# user name to create +# Default: No Default +ZOPE_USER_NAME?=No Default + +# user name to create +# Default: No Default +ZOPE_USER_PASSWORD?=No Default + ## i18n.gettext # Path of directory containing the message catalogs. @@ -170,7 +190,7 @@ GETTEXT_LOCALES_PATH?=locale # No default value. GETTEXT_DOMAIN?= -# List of language identifiers. +# Space separated list of language identifiers. # No default value. GETTEXT_LANGUAGES?= @@ -183,8 +203,11 @@ DIRTY_TARGETS?= CLEAN_TARGETS?= PURGE_TARGETS?= CHECK_TARGETS?= +TYPECHECK_TARGETS?= FORMAT_TARGETS?= +export PATH:=$(if $(EXTRA_PATH),$(EXTRA_PATH):,)$(PATH) + # Defensive settings for make: https://tech.davis-hansson.com/p/make/ SHELL:=bash .ONESHELL: @@ -201,90 +224,66 @@ MXMAKE_FOLDER?=.mxmake # Sentinel files SENTINEL_FOLDER?=$(MXMAKE_FOLDER)/sentinels SENTINEL?=$(SENTINEL_FOLDER)/about.txt -$(SENTINEL): +$(SENTINEL): $(firstword $(MAKEFILE_LIST)) @mkdir -p $(SENTINEL_FOLDER) @echo "Sentinels for the Makefile process." > $(SENTINEL) -############################################################################## -# openldap -############################################################################## - -# case `system.dependencies` domain is included -SYSTEM_DEPENDENCIES+=libdb-dev libsasl2-dev - -OPENLDAP_TARGET:=$(SENTINEL_FOLDER)/openldap.sentinel -$(OPENLDAP_TARGET): $(SENTINEL) - @echo "Building openldap server in '$(OPENLDAP_DIR)'" - @test -d $(OPENLDAP_DIR) || curl -o openldap-$(OPENLDAP_VERSION).tgz \ - $(OPENLDAP_URL)/openldap-$(OPENLDAP_VERSION).tgz - @test -d $(OPENLDAP_DIR) || tar xf openldap-$(OPENLDAP_VERSION).tgz - @test -d $(OPENLDAP_DIR) || rm openldap-$(OPENLDAP_VERSION).tgz - @test -d $(OPENLDAP_DIR) || mv openldap-$(OPENLDAP_VERSION) $(OPENLDAP_DIR) - @env -i -C $(OPENLDAP_DIR) $(OPENLDAP_ENV) bash -c \ - './configure \ - --with-tls \ - --enable-slapd=yes \ - --enable-overlays \ - --prefix=$(OPENLDAP_DIR) \ - && make depend \ - && make -j4 \ - && make install' - @touch $(OPENLDAP_TARGET) - -.PHONY: openldap -openldap: $(OPENLDAP_TARGET) - -.PHONY: openldap-dirty -openldap-dirty: - @test -d $(OPENLDAP_DIR) \ - && env -i -C $(OPENLDAP_DIR) $(OPENLDAP_ENV) bash -c 'make clean' - @rm -f $(OPENLDAP_TARGET) - -.PHONY: openldap-clean -openldap-clean: - @rm -f $(OPENLDAP_TARGET) - @rm -rf $(OPENLDAP_DIR) - -INSTALL_TARGETS+=openldap -DIRTY_TARGETS+=openldap-dirty -CLEAN_TARGETS+=openldap-clean - ############################################################################## # mxenv ############################################################################## -# Check if given Python is installed -ifeq (,$(shell which $(PYTHON_BIN))) -$(error "PYTHON=$(PYTHON_BIN) not found in $(PATH)") -endif +OS?= -# Check if given Python version is ok -PYTHON_VERSION_OK=$(shell $(PYTHON_BIN) -c "import sys; print((int(sys.version_info[0]), int(sys.version_info[1])) >= tuple(map(int, '$(PYTHON_MIN_VERSION)'.split('.'))))") -ifeq ($(PYTHON_VERSION_OK),0) -$(error "Need Python >= $(PYTHON_MIN_VERSION)") +# Determine the executable path +ifeq ("$(VENV_ENABLED)", "true") +export VIRTUAL_ENV=$(abspath $(VENV_FOLDER)) +ifeq ("$(OS)", "Windows_NT") +VENV_EXECUTABLE_FOLDER=$(VIRTUAL_ENV)/Scripts +else +VENV_EXECUTABLE_FOLDER=$(VIRTUAL_ENV)/bin endif - -# Check if venv folder is configured if venv is enabled -ifeq ($(shell [[ "$(VENV_ENABLED)" == "true" && "$(VENV_FOLDER)" == "" ]] && echo "true"),"true") -$(error "VENV_FOLDER must be configured if VENV_ENABLED is true") +export PATH:=$(VENV_EXECUTABLE_FOLDER):$(PATH) +MXENV_PYTHON=python +else +MXENV_PYTHON=$(PRIMARY_PYTHON) endif -# determine the executable path -ifeq ("$(VENV_ENABLED)", "true") -MXENV_PATH=$(VENV_FOLDER)/bin/ +# Determine the package installer +ifeq ("$(PYTHON_PACKAGE_INSTALLER)","uv") +PYTHON_PACKAGE_COMMAND=uv pip else -MXENV_PATH= +PYTHON_PACKAGE_COMMAND=$(MXENV_PYTHON) -m pip endif MXENV_TARGET:=$(SENTINEL_FOLDER)/mxenv.sentinel $(MXENV_TARGET): $(SENTINEL) + @$(PRIMARY_PYTHON) -c "import sys; vi = sys.version_info; sys.exit(1 if (int(vi[0]), int(vi[1])) >= tuple(map(int, '$(PYTHON_MIN_VERSION)'.split('.'))) else 0)" \ + && echo "Need Python >= $(PYTHON_MIN_VERSION)" && exit 1 || : + @[[ "$(VENV_ENABLED)" == "true" && "$(VENV_FOLDER)" == "" ]] \ + && echo "VENV_FOLDER must be configured if VENV_ENABLED is true" && exit 1 || : + @[[ "$(VENV_ENABLED)$(PYTHON_PACKAGE_INSTALLER)" == "falseuv" ]] \ + && echo "Package installer uv does not work with a global Python interpreter." && exit 1 || : ifeq ("$(VENV_ENABLED)", "true") - @echo "Setup Python Virtual Environment under '$(VENV_FOLDER)'" - @$(PYTHON_BIN) -m venv $(VENV_FOLDER) +ifeq ("$(VENV_CREATE)", "true") +ifeq ("$(PYTHON_PACKAGE_INSTALLER)$(MXENV_UV_GLOBAL)","uvtrue") + @echo "Setup Python Virtual Environment using package 'uv' at '$(VENV_FOLDER)'" + @uv venv -p $(PRIMARY_PYTHON) --seed $(VENV_FOLDER) +else + @echo "Setup Python Virtual Environment using module 'venv' at '$(VENV_FOLDER)'" + @$(PRIMARY_PYTHON) -m venv $(VENV_FOLDER) + @$(MXENV_PYTHON) -m ensurepip -U +endif endif - @$(MXENV_PATH)pip install -U pip setuptools wheel - @$(MXENV_PATH)pip install -U $(MXDEV) - @$(MXENV_PATH)pip install -U $(MXMAKE) +else + @echo "Using system Python interpreter" +endif +ifeq ("$(PYTHON_PACKAGE_INSTALLER)$(MXENV_UV_GLOBAL)","uvfalse") + @echo "Install uv" + @$(MXENV_PYTHON) -m pip install uv +endif + @$(PYTHON_PACKAGE_COMMAND) install -U pip setuptools wheel + @echo "Install/Update MXStack Python packages" + @$(PYTHON_PACKAGE_COMMAND) install -U $(MXDEV) $(MXMAKE) @touch $(MXENV_TARGET) .PHONY: mxenv @@ -297,10 +296,12 @@ mxenv-dirty: .PHONY: mxenv-clean mxenv-clean: mxenv-dirty ifeq ("$(VENV_ENABLED)", "true") +ifeq ("$(VENV_CREATE)", "true") @rm -rf $(VENV_FOLDER) +endif else - @$(MXENV_PATH)pip uninstall -y $(MXDEV) - @$(MXENV_PATH)pip uninstall -y $(MXMAKE) + @$(PYTHON_PACKAGE_COMMAND) uninstall -y $(MXDEV) + @$(PYTHON_PACKAGE_COMMAND) uninstall -y $(MXMAKE) endif INSTALL_TARGETS+=mxenv @@ -314,18 +315,18 @@ CLEAN_TARGETS+=mxenv-clean ZPRETTY_TARGET:=$(SENTINEL_FOLDER)/zpretty.sentinel $(ZPRETTY_TARGET): $(MXENV_TARGET) @echo "Install zpretty" - @$(MXENV_PATH)pip install zpretty + @$(PYTHON_PACKAGE_COMMAND) install zpretty @touch $(ZPRETTY_TARGET) .PHONY: zpretty-check zpretty-check: $(ZPRETTY_TARGET) @echo "Run zpretty check in: $(ZPRETTY_SRC)" - @find $(ZPRETTY_SRC) -name '*.zcml' -or -name '*.xml' -exec $(MXENV_PATH)zpretty --check {} + + @find $(ZPRETTY_SRC) -name '*.zcml' -or -name '*.xml' -exec zpretty --check {} + .PHONY: zpretty-format zpretty-format: $(ZPRETTY_TARGET) @echo "Run zpretty format in: $(ZPRETTY_SRC)" - @find $(ZPRETTY_SRC) -name '*.zcml' -or -name '*.xml' -exec $(MXENV_PATH)zpretty -i {} + + @find $(ZPRETTY_SRC) -name '*.zcml' -or -name '*.xml' -exec zpretty -i {} + .PHONY: zpretty-dirty zpretty-dirty: @@ -333,7 +334,7 @@ zpretty-dirty: .PHONY: zpretty-clean zpretty-clean: zpretty-dirty - @test -e $(MXENV_PATH)pip && $(MXENV_PATH)pip uninstall -y zpretty || : + @test -e $(MXENV_PYTHON) && $(MXENV_PYTHON) -m pip uninstall -y zpretty || : INSTALL_TARGETS+=$(ZPRETTY_TARGET) CHECK_TARGETS+=zpretty-check @@ -348,18 +349,18 @@ CLEAN_TARGETS+=zpretty-clean ISORT_TARGET:=$(SENTINEL_FOLDER)/isort.sentinel $(ISORT_TARGET): $(MXENV_TARGET) @echo "Install isort" - @$(MXENV_PATH)pip install isort + @$(PYTHON_PACKAGE_COMMAND) install isort @touch $(ISORT_TARGET) .PHONY: isort-check isort-check: $(ISORT_TARGET) @echo "Run isort check" - @$(MXENV_PATH)isort --check $(ISORT_SRC) + @isort --check $(ISORT_SRC) .PHONY: isort-format isort-format: $(ISORT_TARGET) @echo "Run isort format" - @$(MXENV_PATH)isort $(ISORT_SRC) + @isort $(ISORT_SRC) .PHONY: isort-dirty isort-dirty: @@ -367,7 +368,7 @@ isort-dirty: .PHONY: isort-clean isort-clean: isort-dirty - @test -e $(MXENV_PATH)pip && $(MXENV_PATH)pip uninstall -y isort || : + @test -e $(MXENV_PYTHON) && $(MXENV_PYTHON) -m pip uninstall -y isort || : INSTALL_TARGETS+=$(ISORT_TARGET) CHECK_TARGETS+=isort-check @@ -382,18 +383,18 @@ CLEAN_TARGETS+=isort-clean BLACK_TARGET:=$(SENTINEL_FOLDER)/black.sentinel $(BLACK_TARGET): $(MXENV_TARGET) @echo "Install Black" - @$(MXENV_PATH)pip install black + @$(PYTHON_PACKAGE_COMMAND) install black @touch $(BLACK_TARGET) .PHONY: black-check black-check: $(BLACK_TARGET) @echo "Run black checks" - @$(MXENV_PATH)black --check $(BLACK_SRC) + @black --check $(BLACK_SRC) .PHONY: black-format black-format: $(BLACK_TARGET) @echo "Run black format" - @$(MXENV_PATH)black $(BLACK_SRC) + @black $(BLACK_SRC) .PHONY: black-dirty black-dirty: @@ -401,7 +402,7 @@ black-dirty: .PHONY: black-clean black-clean: black-dirty - @test -e $(MXENV_PATH)pip && $(MXENV_PATH)pip uninstall -y black || : + @test -e $(MXENV_PYTHON) && $(MXENV_PYTHON) -m pip uninstall -y black || : INSTALL_TARGETS+=$(BLACK_TARGET) CHECK_TARGETS+=black-check @@ -409,44 +410,14 @@ FORMAT_TARGETS+=black-format DIRTY_TARGETS+=black-dirty CLEAN_TARGETS+=black-clean -############################################################################## -# python-ldap -############################################################################## - -PYTHON_LDAP_TARGET:=$(SENTINEL_FOLDER)/python-ldap.sentinel -$(PYTHON_LDAP_TARGET): $(MXENV_TARGET) $(OPENLDAP_TARGET) - @$(MXENV_PATH)pip install \ - --force-reinstall \ - --global-option=build_ext \ - --global-option="-I$(OPENLDAP_DIR)/include" \ - --global-option="-L$(OPENLDAP_DIR)/lib" \ - --global-option="-R$(OPENLDAP_DIR)/lib" \ - python-ldap - @touch $(PYTHON_LDAP_TARGET) - -.PHONY: python-ldap -python-ldap: $(PYTHON_LDAP_TARGET) - -.PHONY: python-ldap-dirty -python-ldap-dirty: - @rm -f $(PYTHON_LDAP_TARGET) - -.PHONY: python-ldap-clean -python-ldap-clean: python-ldap-dirty - @test -e $(MXENV_PATH)pip && $(MXENV_PATH)pip uninstall -y python-ldap || : - -INSTALL_TARGETS+=python-ldap -DIRTY_TARGETS+=python-ldap-dirty -CLEAN_TARGETS+=python-ldap-clean - ############################################################################## # sources ############################################################################## SOURCES_TARGET:=$(SENTINEL_FOLDER)/sources.sentinel -$(SOURCES_TARGET): $(MXENV_TARGET) +$(SOURCES_TARGET): $(PROJECT_CONFIG) $(MXENV_TARGET) @echo "Checkout project sources" - @$(MXENV_PATH)mxdev -o -c $(PROJECT_CONFIG) + @mxdev -o -c $(PROJECT_CONFIG) @touch $(SOURCES_TARGET) .PHONY: sources @@ -476,13 +447,11 @@ MXMAKE_FILES?=$(MXMAKE_FOLDER)/files # set environment variables for mxmake define set_mxfiles_env - @export MXMAKE_MXENV_PATH=$(1) - @export MXMAKE_FILES=$(2) + @export MXMAKE_FILES=$(1) endef # unset environment variables for mxmake define unset_mxfiles_env - @unset MXMAKE_MXENV_PATH @unset MXMAKE_FILES endef @@ -499,9 +468,10 @@ FILES_TARGET:=requirements-mxdev.txt $(FILES_TARGET): $(PROJECT_CONFIG) $(MXENV_TARGET) $(SOURCES_TARGET) $(LOCAL_PACKAGE_FILES) @echo "Create project files" @mkdir -p $(MXMAKE_FILES) - $(call set_mxfiles_env,$(MXENV_PATH),$(MXMAKE_FILES)) - @$(MXENV_PATH)mxdev -n -c $(PROJECT_CONFIG) - $(call unset_mxfiles_env,$(MXENV_PATH),$(MXMAKE_FILES)) + $(call set_mxfiles_env,$(MXMAKE_FILES)) + @mxdev -n -c $(PROJECT_CONFIG) + $(call unset_mxfiles_env) + @test -e $(MXMAKE_FILES)/pip.conf && cp $(MXMAKE_FILES)/pip.conf $(VENV_FOLDER)/pip.conf || : @touch $(FILES_TARGET) .PHONY: mxfiles @@ -529,11 +499,21 @@ ADDITIONAL_SOURCES_TARGETS?= INSTALLED_PACKAGES=$(MXMAKE_FILES)/installed.txt +ifeq ("$(PACKAGES_ALLOW_PRERELEASES)","true") +ifeq ("$(PYTHON_PACKAGE_INSTALLER)","uv") +PACKAGES_PRERELEASES=--prerelease=allow +else +PACKAGES_PRERELEASES=--pre +endif +else +PACKAGES_PRERELEASES= +endif + PACKAGES_TARGET:=$(INSTALLED_PACKAGES) $(PACKAGES_TARGET): $(FILES_TARGET) $(ADDITIONAL_SOURCES_TARGETS) @echo "Install python packages" - @$(MXENV_PATH)pip install -r $(FILES_TARGET) - @$(MXENV_PATH)pip freeze > $(INSTALLED_PACKAGES) + @$(PYTHON_PACKAGE_COMMAND) install $(PACKAGES_PRERELEASES) -r $(FILES_TARGET) + @$(PYTHON_PACKAGE_COMMAND) freeze > $(INSTALLED_PACKAGES) @touch $(PACKAGES_TARGET) .PHONY: packages @@ -546,8 +526,8 @@ packages-dirty: .PHONY: packages-clean packages-clean: @test -e $(FILES_TARGET) \ - && test -e $(MXENV_PATH)pip \ - && $(MXENV_PATH)pip uninstall -y -r $(FILES_TARGET) \ + && test -e $(MXENV_PYTHON) \ + && $(MXENV_PYTHON) -m pip uninstall -y -r $(FILES_TARGET) \ || : @rm -f $(PACKAGES_TARGET) @@ -562,14 +542,14 @@ CLEAN_TARGETS+=packages-clean TEST_TARGET:=$(SENTINEL_FOLDER)/test.sentinel $(TEST_TARGET): $(MXENV_TARGET) @echo "Install $(TEST_REQUIREMENTS)" - @$(MXENV_PATH)pip install $(TEST_REQUIREMENTS) + @$(PYTHON_PACKAGE_COMMAND) install $(TEST_REQUIREMENTS) @touch $(TEST_TARGET) .PHONY: test test: $(FILES_TARGET) $(SOURCES_TARGET) $(PACKAGES_TARGET) $(TEST_TARGET) $(TEST_DEPENDENCY_TARGETS) - @echo "Run tests" - @test -z "$(TEST_COMMAND)" && echo "No test command defined" - @test -z "$(TEST_COMMAND)" || bash -c "$(TEST_COMMAND)" + @test -z "$(TEST_COMMAND)" && echo "No test command defined" && exit 1 || : + @echo "Run tests using $(TEST_COMMAND)" + @/usr/bin/env bash -c "$(TEST_COMMAND)" .PHONY: test-dirty test-dirty: @@ -577,7 +557,7 @@ test-dirty: .PHONY: test-clean test-clean: test-dirty - @test -e $(MXENV_PATH)pip && $(MXENV_PATH)pip uninstall -y $(TEST_REQUIREMENTS) || : + @test -e $(MXENV_PYTHON) && $(MXENV_PYTHON) -m pip uninstall -y $(TEST_REQUIREMENTS) || : @rm -rf .pytest_cache INSTALL_TARGETS+=$(TEST_TARGET) @@ -591,14 +571,14 @@ DIRTY_TARGETS+=test-dirty COVERAGE_TARGET:=$(SENTINEL_FOLDER)/coverage.sentinel $(COVERAGE_TARGET): $(TEST_TARGET) @echo "Install Coverage" - @$(MXENV_PATH)pip install -U coverage + @$(PYTHON_PACKAGE_COMMAND) install -U coverage @touch $(COVERAGE_TARGET) .PHONY: coverage coverage: $(FILES_TARGET) $(SOURCES_TARGET) $(PACKAGES_TARGET) $(COVERAGE_TARGET) - @echo "Run coverage" - @test -z "$(COVERAGE_COMMAND)" && echo "No coverage command defined" - @test -z "$(COVERAGE_COMMAND)" || bash -c "$(COVERAGE_COMMAND)" + @test -z "$(COVERAGE_COMMAND)" && echo "No coverage command defined" && exit 1 || : + @echo "Run coverage using $(COVERAGE_COMMAND)" + @/usr/bin/env bash -c "$(COVERAGE_COMMAND)" .PHONY: coverage-dirty coverage-dirty: @@ -606,7 +586,7 @@ coverage-dirty: .PHONY: coverage-clean coverage-clean: coverage-dirty - @test -e $(MXENV_PATH)pip && $(MXENV_PATH)pip uninstall -y coverage || : + @test -e $(MXENV_PYTHON) && $(MXENV_PYTHON) -m pip uninstall -y coverage || : @rm -rf .coverage htmlcov INSTALL_TARGETS+=$(COVERAGE_TARGET) @@ -620,16 +600,19 @@ CLEAN_TARGETS+=coverage-clean COOKIECUTTER_TARGET:=$(SENTINEL_FOLDER)/cookiecutter.sentinel $(COOKIECUTTER_TARGET): $(MXENV_TARGET) @echo "Install cookiecutter" - @$(MXENV_PATH)pip install "cookiecutter>=2.1.1" + @$(PYTHON_PACKAGE_COMMAND) install "cookiecutter>=2.6.0" @touch $(COOKIECUTTER_TARGET) +.PHONY: cookiecutter +cookiecutter: $(COOKIECUTTER_TARGET) + .PHONY: cookiecutter-dirty cookiecutter-dirty: @rm -f $(COOKIECUTTER_TARGET) .PHONY: cookiecutter-clean cookiecutter-clean: cookiecutter-dirty - @test -e $(MXENV_PATH)pip && $(MXENV_PATH)pip uninstall -y cookiecutter || : + @test -e $(MXENV_PYTHON) && $(MXENV_PYTHON) -m pip uninstall -y cookiecutter || : @rm -f $(COOKIECUTTER_TARGET) DIRTY_TARGETS+=cookiecutter-dirty @@ -641,31 +624,43 @@ CLEAN_TARGETS+=cookiecutter-clean ZOPE_INSTANCE_FOLDER:=$(ZOPE_BASE_FOLDER)/instance ZOPE_INSTANCE_TARGET:=$(ZOPE_INSTANCE_FOLDER)/etc/zope.ini $(ZOPE_INSTANCE_FOLDER)/etc/zope.conf $(ZOPE_INSTANCE_FOLDER)/etc/site.zcml +ZOPE_RUN_TARGET:=$(ZOPE_INSTANCE_TARGET) $(PACKAGES_TARGET) + +ifeq (,$(ZOPE_TEMPLATE_CHECKOUT)) + ZOPE_COOKIECUTTER_TEMPLATE_OPTIONS= +else + ZOPE_COOKIECUTTER_TEMPLATE_OPTIONS=--checkout $(ZOPE_TEMPLATE_CHECKOUT) +endif ${ZOPE_CONFIGURATION_FILE}: @touch ${ZOPE_CONFIGURATION_FILE} $(ZOPE_INSTANCE_TARGET): $(COOKIECUTTER_TARGET) $(ZOPE_CONFIGURATION_FILE) @echo Create Plone/Zope configuration from $(ZOPE_TEMPLATE) to $(ZOPE_INSTANCE_FOLDER) - @$(MXENV_PATH)cookiecutter -f --no-input --config-file $(ZOPE_CONFIGURATION_FILE) --output-dir $(ZOPE_BASE_FOLDER) $(ZOPE_TEMPLATE) + @cookiecutter -f --no-input ${ZOPE_COOKIECUTTER_TEMPLATE_OPTIONS} --config-file $(ZOPE_CONFIGURATION_FILE) --output-dir $(ZOPE_BASE_FOLDER) $(ZOPE_TEMPLATE) .PHONY: zope-instance -zope-instance: $(ZOPE_INSTANCE_TARGET) $(SOURCES) +zope-instance: $(ZOPE_INSTANCE_TARGET) $(SOURCES_TARGET) .PHONY: zope-start -zope-start: $(ZOPE_INSTANCE_TARGET) $(PACKAGES_TARGET) +zope-start: $(ZOPE_RUN_TARGET) @echo "Start Zope/Plone with configuration in $(ZOPE_INSTANCE_FOLDER)" - @$(MXENV_PATH)runwsgi -v "$(ZOPE_INSTANCE_FOLDER)/etc/zope.ini" + @runwsgi -v "$(ZOPE_INSTANCE_FOLDER)/etc/zope.ini" .PHONY: zope-debug -zope-debug: $(ZOPE_INSTANCE_TARGET) $(PACKAGES_TARGET) +zope-debug: $(ZOPE_RUN_TARGET) @echo "Start Zope/Plone with configuration in $(ZOPE_INSTANCE_FOLDER)" - @$(MXENV_PATH)zconsole debug "$(ZOPE_INSTANCE_FOLDER)/etc/zope.ini" + @zconsole debug "$(ZOPE_INSTANCE_FOLDER)/etc/zope.conf" .PHONY: zope-runscript -zope-runscript: $(ZOPE_INSTANCE_TARGET) $(PACKAGES_TARGET) +zope-runscript: $(ZOPE_RUN_TARGET) @echo "Run Zope/Plone Console Script $(ZOPE_SCRIPTNAME) in $(ZOPE_INSTANCE_FOLDER)" - @$(MXENV_PATH)zconsole run "$(ZOPE_INSTANCE_FOLDER)/etc/zope.ini" $(ZOPE_SCRIPTNAME) + @zconsole run "$(ZOPE_INSTANCE_FOLDER)/etc/zope.conf" $(ZOPE_SCRIPTNAME) + +.PHONY: zope-adduser +zope-adduser: $(ZOPE_RUN_TARGET) + @echo "Run Zope addzopeuser to create an emergency user '$(ZOPE_USER_NAME)' with role 'Manager'" + @addzopeuser -c "$(ZOPE_INSTANCE_FOLDER)/etc/zope.conf" $(ZOPE_USER_NAME) $(ZOPE_USER_PASSWORD) .PHONY: zope-dirty zope-dirty: @@ -683,6 +678,7 @@ zope-purge: zope-dirty INSTALL_TARGETS+=zope-instance DIRTY_TARGETS+=zope-dirty CLEAN_TARGETS+=zope-clean +PURGE_TARGETS+=zope-purge ############################################################################## # gettext @@ -727,6 +723,10 @@ gettext-compile: "$(GETTEXT_LOCALES_PATH)/$$lang/LC_MESSAGES/$(GETTEXT_DOMAIN).po"; \ done +############################################################################## +# Custom includes +############################################################################## + -include $(INCLUDE_MAKEFILE) ############################################################################## @@ -768,5 +768,8 @@ runtime-clean: .PHONY: check check: $(CHECK_TARGETS) +.PHONY: typecheck +typecheck: $(TYPECHECK_TARGETS) + .PHONY: format format: $(FORMAT_TARGETS) From 3b2cdd2e68493e620d02fdd2ee403f9b4bdf030a Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Mon, 23 Jun 2025 19:55:31 +0200 Subject: [PATCH 30/52] fix merge --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 6068493..fc1f76c 100644 --- a/setup.py +++ b/setup.py @@ -1,3 +1,3 @@ from setuptools import setup -setup() +setup() \ No newline at end of file From 94ea8d29b91e2ea45c0d3ea5516c301d4d809b4c Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Mon, 23 Jun 2025 19:55:53 +0200 Subject: [PATCH 31/52] update some version for p6 --- setup.cfg | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/setup.cfg b/setup.cfg index 4f29950..58205ce 100644 --- a/setup.cfg +++ b/setup.cfg @@ -16,16 +16,17 @@ project_urls = classifiers = Development Status :: 5 - Production/Stable Environment :: Web Environment - Framework :: Plone :: 6.0 + Framework :: Plone :: 6.1 Framework :: Plone :: Addon Framework :: Plone Framework :: Zope :: 5 Framework :: Zope License :: OSI Approved :: GNU General Public License v2 (GPLv2) Operating System :: OS Independent - Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.11 + Programming Language :: Python :: 3.12 + Programming Language :: Python :: 3.13 Topic :: System :: Systems Administration :: Authentication/Directory :: LDAP Programming Language :: Python @@ -42,11 +43,12 @@ install_requires = Products.PlonePAS Products.PluggableAuthService Products.statusmessages + plone.api python-ldap>=3.4.0 setuptools - yafowil.plone>=4.0.0a3 - yafowil.widget.array - yafowil.widget.dict + yafowil.plone>=5.0.0a1 + yafowil.widget.array>=2.0a1 + yafowil.widget.dict>=2.0a1 yafowil.yaml zope.globalrequest Zope>=5 From fec62c6183b3ba34b09381e96f1f534d2941f549 Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Mon, 23 Jun 2025 19:56:11 +0200 Subject: [PATCH 32/52] pin yafowil --- requirements.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/requirements.txt b/requirements.txt index 17178b7..110e0f8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,7 @@ waitress_fastlisten # until https://github.com/plone/plone.restapi/issues/1321 is solved plone.app.iterate +yafowil.plone==5.0.0a2 +yafowil.bootstrap==2.0.0a1 +yafowil.widget.array==2.0a1 +yafowil.widget.dict==2.0a1 \ No newline at end of file From a0d2f2a2f5973ef4865121258444cc047eca3068 Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Mon, 23 Jun 2025 19:56:37 +0200 Subject: [PATCH 33/52] bump to 6.1 --- constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/constraints.txt b/constraints.txt index dde5b0e..55f014e 100644 --- a/constraints.txt +++ b/constraints.txt @@ -1 +1 @@ --c https://dist.plone.org/release/6.0.5/constraints.txt +-c https://dist.plone.org/release/6.1.2/constraints.txt From 0b89dc4036ae6ff6548da8b20569bc4cd09222ca Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Mon, 23 Jun 2025 19:56:57 +0200 Subject: [PATCH 34/52] use yafowil releases --- mx.ini | 58 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/mx.ini b/mx.ini index 04df64d..f1a3dd5 100644 --- a/mx.ini +++ b/mx.ini @@ -35,32 +35,32 @@ environment = env # url = ${settings:github}/conestack/node.ext.ugm.git # branch = master -[yafowil] -url = ${settings:github}/conestack/yafowil.git -pushurl = ${settings:github-push}:conestack/yafowil.git -branch = master - -[yafowil.bootstrap] -url = ${settings:github}/conestack/yafowil.bootstrap.git -pushurl = ${settings:github-push}:conestack/yafowil.bootstrap.git -branch = 2.0 - -[yafowil.plone] -url = ${settings:github}/bluedynamics/yafowil.plone.git -pushurl = ${settings:github}:bluedynamics/yafowil.plone.git -branch = master - -[yafowil.widget.array] -url = ${settings:github}/conestack/yafowil.widget.array.git -pushurl = ${settings:github-push}:conestack/yafowil.widget.array.git -branch = 2.0 - -[yafowil.widget.dict] -url = ${settings:github}/conestack/yafowil.widget.dict.git -pushurl = ${settings:github-push}:conestack/yafowil.widget.dict.git -branch = 2.0 - -[node.ext.ldap] -url = ${settings:github}/conestack/node.ext.ldap.git -pushurl = ${settings:github-push}:conestack/node.ext.ldap.git -branch = master +# [yafowil] +# url = ${settings:github}/conestack/yafowil.git +# pushurl = ${settings:github-push}:conestack/yafowil.git +# branch = master + +# [yafowil.bootstrap] +# url = ${settings:github}/conestack/yafowil.bootstrap.git +# pushurl = ${settings:github-push}:conestack/yafowil.bootstrap.git +# branch = 2.0 + +# [yafowil.plone] +# url = ${settings:github}/bluedynamics/yafowil.plone.git +# pushurl = ${settings:github}:bluedynamics/yafowil.plone.git +# branch = master + +# [yafowil.widget.array] +# url = ${settings:github}/conestack/yafowil.widget.array.git +# pushurl = ${settings:github-push}:conestack/yafowil.widget.array.git +# branch = 2.0 + +# [yafowil.widget.dict] +# url = ${settings:github}/conestack/yafowil.widget.dict.git +# pushurl = ${settings:github-push}:conestack/yafowil.widget.dict.git +# branch = 2.0 + +# [node.ext.ldap] +# url = ${settings:github}/conestack/node.ext.ldap.git +# pushurl = ${settings:github-push}:conestack/node.ext.ldap.git +# branch = master From f622dc199179cdcbcc1cfc4d6f3ac4827c26f670 Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Mon, 23 Jun 2025 19:57:23 +0200 Subject: [PATCH 35/52] try to update action to run matrix right --- .github/workflows/tests.yaml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index cec88d7..3d3f63f 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -9,27 +9,32 @@ jobs: fail-fast: false matrix: python: - - "3.9" - "3.10" - "3.11" + - "3.12" + - "3.13" plone: - - "6.0.5" + - "6.0.14" + - "6.1.2" steps: - uses: actions/checkout@v2 - name: Install system packages - run: sudo apt-get install -y libsasl2-dev libssl-dev libdb-dev libldap2-dev + run: | + sudo apt-get update -y + sudo apt-get install -y slapd - name: Setup Plone ${{ matrix.plone }} with Python ${{ matrix.python }} id: setup - uses: plone/setup-plone@v2.0.0 + uses: plone/setup-plone@v3.0.0 with: python-version: ${{ matrix.python }} plone-version: ${{ matrix.plone }} - name: Install package run: | + sed -i "s#\(-c https://dist.plone.org/release/\)[^/]\+\(/constraints.txt\)#\1${{ matrix.plone }}\2#" requirements.txt make VENV=off install - name: Run tests From f667363870ef8fbb5e85a4662d5d28f40ab4c5eb Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Mon, 23 Jun 2025 20:01:22 +0200 Subject: [PATCH 36/52] exclude and install uv --- .github/workflows/tests.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 3d3f63f..b1761f7 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -16,12 +16,16 @@ jobs: plone: - "6.0.14" - "6.1.2" + exclude: + - python: "3.13" + plone: "6.0.14" steps: - uses: actions/checkout@v2 - name: Install system packages run: | + curl -LsSf https://astral.sh/uv/install.sh | sh sudo apt-get update -y sudo apt-get install -y slapd From 6408f3b7f0b25bde71936678e6d8d65e7f6632c4 Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Mon, 23 Jun 2025 20:05:01 +0200 Subject: [PATCH 37/52] python-ldap - no wheel --- .github/workflows/tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index b1761f7..db8215b 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -27,7 +27,7 @@ jobs: run: | curl -LsSf https://astral.sh/uv/install.sh | sh sudo apt-get update -y - sudo apt-get install -y slapd + sudo apt-get install -y libsasl2-dev libssl-dev libdb-dev libldap2-dev slapd - name: Setup Plone ${{ matrix.plone }} with Python ${{ matrix.python }} id: setup From c40cb486464d0c2ecd98597b16f89fcbf9e7bcad Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Mon, 23 Jun 2025 20:49:42 +0200 Subject: [PATCH 38/52] no openldap here --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index dd7c090..456bd84 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ TEST_REQUIREMENTS?=zope.testrunner # Additional make targets the test target depends on. # No default value. -TEST_DEPENDENCY_TARGETS?=openldap +TEST_DEPENDENCY_TARGETS?= ## qa.coverage From fb28699eed2a9355e0e013a00bb312e32304c553 Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Mon, 23 Jun 2025 21:08:26 +0200 Subject: [PATCH 39/52] update readme --- README_MAKE.md | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/README_MAKE.md b/README_MAKE.md index f398b94..bf4c8ed 100644 --- a/README_MAKE.md +++ b/README_MAKE.md @@ -1,36 +1,37 @@ # Information about the Makefile -How to use the pip, mxdev, cookiecutter-zope-instance and make based install. +How to use the uv, mxdev, cookiecutter-zope-instance and make based install. ## Usage +Install [uv](https://docs.astral.sh/uv/getting-started/installation/). + On the commandline, execute the ``make`` command. -Without any options, make will run all steps. +Without any options, make will run nothing, so pass in a command. + +Run the Zope-Server: ```bash make run ``` -All options are printed with +Run all tests: ```bash -make help +make test ``` -```text -clean remove instance configuration (keeps data) -help This help message -install pip install all dependencies and scripts -instance create configuration for an zope (plone) instance -prepare prepare soures and dependencies -run run Plone +All options are printed with + +```bash +make help ``` -Order for ``make run`` is: *prepare*, *install*, *instance*, *run*. +``make run`` resolves dependencies in order like: *prepare*, *install*, *instance*, *run*. The Makefile is built to detect changes. -At the first ``make run`` all steps are excuted. -Subsequent calls are only starting the applicaton server in the *run* step. +At the first ``make run`` all steps are executed. +Subsequent calls are only starting the application server in the *run* step. If one of the input file is changed, steps needed to take those changes into effect are executed again.\ ## Python @@ -49,11 +50,6 @@ The Makefile support different modes of Python: ## Files -Initially the files below were generated by `plone-kickstarter`. -They are meant to be modified for your needs. - -They aim to ease development and deployment of *Plone 6+* - `constraints.txt` Version pins for your project, used by *pip*. `README_MAKE.md` @@ -64,7 +60,7 @@ They aim to ease development and deployment of *Plone 6+* The configuration for *make* `requirement.txt` The core requirements. -`sources.ini` +`mx.ini` *mxdev* is used to develop with sources from VCS like Git. If you need sources from git, add them here. @@ -73,6 +69,6 @@ They aim to ease development and deployment of *Plone 6+* The configuration here uses: - `make` -- [pip](https://pip.pypa.io/en/stable/) +- [uv](https://docs.astral.sh/uv/getting-started/installation/) - [mxdev](https://pypi.org/project/mxdev) - [cookiecutter-zope-instance](https://github.com/bluedynamics/cookiecutter-zope-instance/) From 92de68ad25406b8a58207e5c320bb6c0a1e79f63 Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Mon, 23 Jun 2025 21:10:43 +0200 Subject: [PATCH 40/52] pyproejct.tom, hatchling and pep420 namespaces --- pyproject.toml | 88 +++++++++++++++++++ setup.cfg | 88 ------------------- setup.py | 3 - src/pas/__init__.py | 1 - src/pas/plugins/__init__.py | 1 - .../ldap/plonecontrolpanel/__init__.py | 18 ---- src/pas/plugins/ldap/tests/__init__.py | 0 7 files changed, 88 insertions(+), 111 deletions(-) create mode 100644 pyproject.toml delete mode 100644 setup.cfg delete mode 100644 setup.py delete mode 100644 src/pas/__init__.py delete mode 100644 src/pas/plugins/__init__.py delete mode 100644 src/pas/plugins/ldap/plonecontrolpanel/__init__.py delete mode 100644 src/pas/plugins/ldap/tests/__init__.py diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..b14111f --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,88 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "pas-plugins-ldap" +version = "2.0.0.dev0" +description = "LDAP/AD Plugin for Plone/Zope PluggableAuthService (users+groups)" +readme = "README.rst" +license = { text = "GPL 2.0" } +authors = [ + { name = "BlueDynamics Alliance", email = "dev@bluedynamics.com" }, +] +keywords = [ + "authentication", + "groups", + "ldap", + "pas", + "plone", + "plugin", + "users", + "zope", +] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Environment :: Web Environment", + "Framework :: Plone", + "Framework :: Plone :: 6.1", + "Framework :: Plone :: Addon", + "Framework :: Zope", + "Framework :: Zope :: 5", + "License :: OSI Approved :: GNU General Public License v2 (GPLv2)", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Topic :: System :: Systems Administration :: Authentication/Directory :: LDAP", +] +dependencies = [ + "bda.cache", + "five.globalrequest", + "node.ext.ldap>=1.0rc1", + "odict", + "plone.api", + "plone.registry", + "Products.CMFCore", + "Products.GenericSetup", + "Products.PlonePAS", + "Products.PluggableAuthService", + "Products.statusmessages", + "python-ldap>=3.4.0", + "setuptools", + "yafowil.plone>=5.0.0a1", + "yafowil.widget.array>=2.0a1", + "yafowil.widget.dict>=2.0a1", + "yafowil.yaml", + "zope.globalrequest", + "Zope>=5", +] + +[project.optional-dependencies] +plone = [ + "Products.CMFPlone", +] +test = [ + "plone.testing", +] + +[project.entry-points."z3c.autoinclude.plugin"] +target = "plone" + +[project.urls] +ChangeLog = "https://github.com/collective/pas.plugins.ldap/blob/master/CHANGES.rst" +Homepage = "https://github.com/collective/pas.plugins.ldap/" +"Issue Tracker" = "https://github.com/collective/pas.plugins.ldap/issues" +"Source Code" = "https://github.com/collective/pas.plugins.ldap" + +[tool.hatch.build.targets.wheel] +packages = [ + " src/pas_plugins_ldap", +] + +[tool.hatch.build.targets.sdist] +include = [ + "/ src", +] diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 58205ce..0000000 --- a/setup.cfg +++ /dev/null @@ -1,88 +0,0 @@ -[metadata] -name = pas.plugins.ldap -version=2.0.0.dev0 -description=LDAP/AD Plugin for Plone/Zope PluggableAuthService (users+groups) -long_description = file: README.rst, CHANGES.rst -keywords = zope pas plone ldap authentication plugin users groups -author = BlueDynamics Alliance -author_email = dev@bluedynamics.com -license = GPLv2 -license_files = LICENSE.rst -url = https://github.com/collective/pas.plugins.ldap/ -project_urls = - ChangeLog = https://github.com/collective/pas.plugins.ldap/blob/master/CHANGES.rst - Issue Tracker = https://github.com/collective/pas.plugins.ldap/issues - Source Code = https://github.com/collective/pas.plugins.ldap -classifiers = - Development Status :: 5 - Production/Stable - Environment :: Web Environment - Framework :: Plone :: 6.1 - Framework :: Plone :: Addon - Framework :: Plone - Framework :: Zope :: 5 - Framework :: Zope - License :: OSI Approved :: GNU General Public License v2 (GPLv2) - Operating System :: OS Independent - Programming Language :: Python :: 3.10 - Programming Language :: Python :: 3.11 - Programming Language :: Python :: 3.12 - Programming Language :: Python :: 3.13 - Topic :: System :: Systems Administration :: Authentication/Directory :: LDAP - Programming Language :: Python - -[options] -setup_requires = setuptools -install_requires = - bda.cache - five.globalrequest - node.ext.ldap>=1.0rc1 - odict - plone.registry - Products.CMFCore - Products.GenericSetup - Products.PlonePAS - Products.PluggableAuthService - Products.statusmessages - plone.api - python-ldap>=3.4.0 - setuptools - yafowil.plone>=5.0.0a1 - yafowil.widget.array>=2.0a1 - yafowil.widget.dict>=2.0a1 - yafowil.yaml - zope.globalrequest - Zope>=5 - -include_package_data = True -zip_safe = False -namespace_packages = - pas - pas.plugins - -package_dir = - = src -packages = find: - -[options.packages.find] -where = - src - -[options.entry_points] -z3c.autoinclude.plugin = - target = plone - -[options.extras_require] -test = - plone.testing - -plone = - Products.CMFPlone - -[isort] -profile = black -force_alphabetical_sort=True -force_single_line = True -lines_after_imports = 2 - -[zest.releaser] -create-wheel = yes diff --git a/setup.py b/setup.py deleted file mode 100644 index fc1f76c..0000000 --- a/setup.py +++ /dev/null @@ -1,3 +0,0 @@ -from setuptools import setup - -setup() \ No newline at end of file diff --git a/src/pas/__init__.py b/src/pas/__init__.py deleted file mode 100644 index 5284146..0000000 --- a/src/pas/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__import__("pkg_resources").declare_namespace(__name__) diff --git a/src/pas/plugins/__init__.py b/src/pas/plugins/__init__.py deleted file mode 100644 index 5284146..0000000 --- a/src/pas/plugins/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__import__("pkg_resources").declare_namespace(__name__) diff --git a/src/pas/plugins/ldap/plonecontrolpanel/__init__.py b/src/pas/plugins/ldap/plonecontrolpanel/__init__.py deleted file mode 100644 index 548c5b5..0000000 --- a/src/pas/plugins/ldap/plonecontrolpanel/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -from Products.CMFPlone.interfaces.installable import INonInstallable -from zope.interface import implementer - - -@implementer(INonInstallable) -class HiddenProfiles: - """This hides zope2 profile from the quick installer tool and plone cpanel""" - - _hidden = [ - "pas.plugins.ldap:default", - "pas.plugins.ldap.plonecontrolpanel:install-base", - ] - - def getNonInstallableProducts(self): - return self._hidden - - def getNonInstallableProfiles(self): - return self._hidden diff --git a/src/pas/plugins/ldap/tests/__init__.py b/src/pas/plugins/ldap/tests/__init__.py deleted file mode 100644 index e69de29..0000000 From 59263371c511e051f23dd633ed2c7b51776f223a Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Mon, 23 Jun 2025 21:13:24 +0200 Subject: [PATCH 41/52] old stuff removed --- base.cfg | 107 -------------------------------------------------- build_ldap.sh | 11 ------ 2 files changed, 118 deletions(-) delete mode 100644 base.cfg delete mode 100755 build_ldap.sh diff --git a/base.cfg b/base.cfg deleted file mode 100644 index 9c67af6..0000000 --- a/base.cfg +++ /dev/null @@ -1,107 +0,0 @@ -[buildout] -extends = ldap.cfg -parts += - zopeomelette - ploneomelette - coverage - test - test-coverage - releaser - code-analysis - vscode - -develop = . -unzip = true - -[code-analysis] -recipe = plone.recipe.codeanalysis -directory = ${buildout:directory}/src -flake8-ignore = C901,E241,E501 -flake8-max-complexity = 20 -clean-lines = False -imports = True -debug-statements = True -utf8-header = True - -[instance] -recipe = plone.recipe.zope2instance -user = admin:admin -http-address = 8080 -debug-mode = on -verbose-security = off -deprecation-warnings = on -blob-storage = var/blobstorage - -eggs = - ${python-ldap:egg} - pas.plugins.ldap - pdbpp - -zcml = - pas.plugins.ldap - -[plone] -recipe = plone.recipe.zope2instance -user = admin:admin -http-address = 8081 -debug-mode = on -verbose-security = off -deprecation-warnings = on -blob-storage = var/blobstorage - -eggs = - ${python-ldap:egg} - pas.plugins.ldap[plone] - pdbpp - -zcml = - pas.plugins.ldap - -[releaser] -recipe = zc.recipe.egg -eggs = zest.releaser[recommended] - -[test] -recipe = zc.recipe.testrunner -eggs = - ${python-ldap:egg} - pas.plugins.ldap[test] - -environment = testenv -defaults = ['--auto-color', '--auto-progress'] - -[coverage] -recipe = zc.recipe.egg -eggs = coverage - -[test-coverage] -recipe = collective.recipe.template -input = inline: - #!/bin/bash - ${buildout:directory}/bin/coverage run --source=${buildout:directory}/src/pas/plugins/ldap bin/test - ${buildout:directory}/bin/coverage html - ${buildout:directory}/bin/coverage report -m --fail-under=90 - # Fail (exit status 1) if coverage returns exit status 2 (this happens - # when test coverage is below 100%. -output = ${buildout:directory}/bin/test-coverage -mode = 755 - -[zopeomelette] -recipe = collective.recipe.omelette -eggs = - ${instance:eggs} -ignore-develop = true - -[ploneomelette] -recipe = collective.recipe.omelette -eggs = - ${plone:eggs} -ignore-develop = true - -[vscode] -recipe = collective.recipe.vscode -eggs = ${test:eggs} -flake8-enabled = false -black-enabled = true -generate-envfile = true - diff --git a/build_ldap.sh b/build_ldap.sh deleted file mode 100755 index 2321df0..0000000 --- a/build_ldap.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -cd $1 - -./configure --with-tls --enable-slapd=yes --enable-overlays CPPFLAGS=-D_GNU_SOURCE --prefix=$2 -make clean -make depend -make -j4 -make install - -cd - \ No newline at end of file From bdf14e77cec8e9c656f18483700fd276d9b1898c Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Mon, 23 Jun 2025 21:13:41 +0200 Subject: [PATCH 42/52] typo --- README_MAKE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README_MAKE.md b/README_MAKE.md index bf4c8ed..784ab9f 100644 --- a/README_MAKE.md +++ b/README_MAKE.md @@ -32,7 +32,7 @@ make help The Makefile is built to detect changes. At the first ``make run`` all steps are executed. Subsequent calls are only starting the application server in the *run* step. -If one of the input file is changed, steps needed to take those changes into effect are executed again.\ +If one of the input file is changed, steps needed to take those changes into effect are executed again. ## Python From 9d5fdcdf4cf0f74087df1cd6bf9ea5de39fef98d Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Mon, 23 Jun 2025 22:23:45 +0200 Subject: [PATCH 43/52] accidentially deleted --- .../ldap/plonecontrolpanel/__init__.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/pas/plugins/ldap/plonecontrolpanel/__init__.py diff --git a/src/pas/plugins/ldap/plonecontrolpanel/__init__.py b/src/pas/plugins/ldap/plonecontrolpanel/__init__.py new file mode 100644 index 0000000..698012e --- /dev/null +++ b/src/pas/plugins/ldap/plonecontrolpanel/__init__.py @@ -0,0 +1,19 @@ +from Products.CMFPlone.interfaces.installable import INonInstallable +from zope.interface import implementer + + +@implementer(INonInstallable) +class HiddenProfiles: + """This hides zope2 profile from the quick installer tool and plone cpanel""" + + _hidden = [ + "pas.plugins.ldap:default", + "pas.plugins.ldap.plonecontrolpanel:install-base", + ] + + def getNonInstallableProducts(self): + return self._hidden + + def getNonInstallableProfiles(self): + return self._hidden + From 614270279d74690927013e9be112106a97395b1c Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Mon, 23 Jun 2025 22:24:20 +0200 Subject: [PATCH 44/52] move tests and make them run (and fail) --- .gitignore | 3 +- CHANGES.rst | 5 ++ Makefile | 2 +- mx.ini | 4 +- pyproject.toml | 38 +++++++------- src/pas/plugins/ldap/tests/test_doctests.py | 49 ------------------- {src/pas/plugins/ldap => tests}/cache.rst | 0 tests/conftest.py | 15 ++++++ .../pas/plugins/ldap => tests}/properties.rst | 0 tests/test_doctests.py | 33 +++++++++++++ .../ldap/tests => tests}/test_plugin.py | 2 +- {src/pas/plugins/ldap => tests}/testing.py | 9 ++-- 12 files changed, 84 insertions(+), 76 deletions(-) delete mode 100644 src/pas/plugins/ldap/tests/test_doctests.py rename {src/pas/plugins/ldap => tests}/cache.rst (100%) create mode 100644 tests/conftest.py rename {src/pas/plugins/ldap => tests}/properties.rst (100%) create mode 100644 tests/test_doctests.py rename {src/pas/plugins/ldap/tests => tests}/test_plugin.py (99%) rename {src/pas/plugins/ldap => tests}/testing.py (92%) diff --git a/.gitignore b/.gitignore index 65a4f26..78c3c45 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ __pycache__ /.pydevproject /.Python /.settings/ +/.venv/ /.vscode/ /*eggs/ /coverage/ @@ -24,5 +25,3 @@ __pycache__ /pip-selfcheck.json /sources/ /src/*.egg-info -/venv/ -/.openldap/ diff --git a/CHANGES.rst b/CHANGES.rst index 8f62b18..4d1f3a9 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,6 +2,11 @@ History ======= +2.0.0 (unreleased) +------------------ + +- todo + 1.9.0 (unreleased) ------------------ diff --git a/Makefile b/Makefile index 456bd84..f72a9f9 100644 --- a/Makefile +++ b/Makefile @@ -86,7 +86,7 @@ VENV_CREATE?=true # `VENV_CREATE` is false it is expected to point to an existing virtual # environment. If `VENV_ENABLED` is `false` it is ignored. # Default: .venv -VENV_FOLDER?=venv +VENV_FOLDER?=.venv # mxdev to install in virtual environment. # Default: mxdev diff --git a/mx.ini b/mx.ini index f1a3dd5..c39694f 100644 --- a/mx.ini +++ b/mx.ini @@ -9,11 +9,13 @@ mxmake-templates = run-tests run-coverage -mxmake-test-runner = zope-testrunner +# mxmake-test-runner = pytest +# environment variables # environment variables [mxmake-env] # VAR = value +testpaths = tests [mxmake-run-tests] environment = env diff --git a/pyproject.toml b/pyproject.toml index b14111f..8d61d6a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,16 +1,10 @@ -[build-system] -requires = ["hatchling"] -build-backend = "hatchling.build" - [project] -name = "pas-plugins-ldap" +name = "pas.plugins.ldap" version = "2.0.0.dev0" description = "LDAP/AD Plugin for Plone/Zope PluggableAuthService (users+groups)" readme = "README.rst" license = { text = "GPL 2.0" } -authors = [ - { name = "BlueDynamics Alliance", email = "dev@bluedynamics.com" }, -] +authors = [{ name = "BlueDynamics Alliance", email = "dev@bluedynamics.com" }] keywords = [ "authentication", "groups", @@ -61,12 +55,8 @@ dependencies = [ ] [project.optional-dependencies] -plone = [ - "Products.CMFPlone", -] -test = [ - "plone.testing", -] +plone = ["Products.CMFPlone"] +test = ["plone.testing", "pytest-plone"] [project.entry-points."z3c.autoinclude.plugin"] target = "plone" @@ -77,12 +67,24 @@ Homepage = "https://github.com/collective/pas.plugins.ldap/" "Issue Tracker" = "https://github.com/collective/pas.plugins.ldap/issues" "Source Code" = "https://github.com/collective/pas.plugins.ldap" +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + [tool.hatch.build.targets.wheel] -packages = [ - " src/pas_plugins_ldap", -] +packages = ["src/pas"] [tool.hatch.build.targets.sdist] include = [ - "/ src", + "/src", ] + +[tool.pytest.ini_options] +minversion = "6.0" +testpaths = [ + "tests", +] + +[tool.isort] +profile = "plone" + diff --git a/src/pas/plugins/ldap/tests/test_doctests.py b/src/pas/plugins/ldap/tests/test_doctests.py deleted file mode 100644 index 861c8db..0000000 --- a/src/pas/plugins/ldap/tests/test_doctests.py +++ /dev/null @@ -1,49 +0,0 @@ -from ..testing import PASLDAPLayer -from plone.testing import layered -from plone.testing import z2 - -import doctest -import pprint -import re -import six -import unittest - - -optionflags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS -optionflags = optionflags | doctest.REPORT_ONLY_FIRST_FAILURE - - -class Py23DocChecker(doctest.OutputChecker): - def check_output(self, want, got, optionflags): - if want != got and six.PY2: - # if running on py2, ignore any "u" prefixes in the output - got = re.sub("(\\W|^)u'(.*?)'", "\\1'\\2'", got) - got = re.sub('(\\W|^)u"(.*?)"', '\\1"\\2"', got) - # also ignore "b" prefixes in the expected output - want = re.sub("b'(.*?)'", "'\\1'", want) - # we get 'ldap.' prefixes on python 3, e.g. - # ldap.UNWILLING_TO_PERFORM - want = want.lstrip("ldap.") - return doctest.OutputChecker.check_output(self, want, got, optionflags) - - -TESTFILES = [("../properties.rst", PASLDAPLayer), ("../cache.rst", PASLDAPLayer)] - - -def test_suite(): - suite = unittest.TestSuite() - suite.addTests( - [ - layered( - doctest.DocFileSuite( - docfile, - globs={"pprint": pprint.pprint, "z2": z2}, - optionflags=optionflags, - checker=Py23DocChecker(), - ), - layer=layer(), - ) - for docfile, layer in TESTFILES - ] - ) - return suite diff --git a/src/pas/plugins/ldap/cache.rst b/tests/cache.rst similarity index 100% rename from src/pas/plugins/ldap/cache.rst rename to tests/cache.rst diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..198462d --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,15 @@ +from testing import PASLDAP_FIXTURE +from pytest_plone import fixtures_factory + + +pytest_plugins = ["pytest_plone"] + + +globals().update( + fixtures_factory( + ( + (PASLDAP_FIXTURE, "ldap"), + + ) + ) +) \ No newline at end of file diff --git a/src/pas/plugins/ldap/properties.rst b/tests/properties.rst similarity index 100% rename from src/pas/plugins/ldap/properties.rst rename to tests/properties.rst diff --git a/tests/test_doctests.py b/tests/test_doctests.py new file mode 100644 index 0000000..9f433a3 --- /dev/null +++ b/tests/test_doctests.py @@ -0,0 +1,33 @@ +from testing import PASLDAPLayer +from plone.testing import layered +from plone.testing import zope + +import doctest +import pprint +import re +import six +import unittest + + +optionflags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS +optionflags = optionflags | doctest.REPORT_ONLY_FIRST_FAILURE + +TESTFILES = [("properties.rst", PASLDAPLayer), ("cache.rst", PASLDAPLayer)] + + +def test_suite(): + suite = unittest.TestSuite() + suite.addTests( + [ + layered( + doctest.DocFileSuite( + docfile, + globs={"pprint": pprint.pprint, "z2": zope}, + optionflags=optionflags, + ), + layer=layer(), + ) + for docfile, layer in TESTFILES + ] + ) + return suite diff --git a/src/pas/plugins/ldap/tests/test_plugin.py b/tests/test_plugin.py similarity index 99% rename from src/pas/plugins/ldap/tests/test_plugin.py rename to tests/test_plugin.py index 26dae63..9ff094b 100644 --- a/src/pas/plugins/ldap/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -1,4 +1,4 @@ -from ..testing import PASLDAP_FIXTURE +from testing import PASLDAP_FIXTURE from Products.PlonePAS.plugins.ufactory import PloneUser import unittest diff --git a/src/pas/plugins/ldap/testing.py b/tests/testing.py similarity index 92% rename from src/pas/plugins/ldap/testing.py rename to tests/testing.py index 579338a..f7ea0a8 100644 --- a/src/pas/plugins/ldap/testing.py +++ b/tests/testing.py @@ -1,7 +1,8 @@ -from .cache import cacheProviderFactory -from .interfaces import ICacheSettingsRecordProvider -from .plonecontrolpanel.cache import CacheSettingsRecordProvider -from .properties import LDAPProps +from pas.plugins.ldap.cache import cacheProviderFactory +from pas.plugins.ldap.cache import cacheProviderFactory +from pas.plugins.ldap.interfaces import ICacheSettingsRecordProvider +from pas.plugins.ldap.plonecontrolpanel.cache import CacheSettingsRecordProvider +from pas.plugins.ldap.properties import LDAPProps from node.ext.ldap import testing as ldaptesting from node.ext.ldap.interfaces import ICacheProviderFactory from node.ext.ldap.interfaces import ILDAPGroupsConfig From 12f66712adc15f4462702366a22f962422c4b010 Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Mon, 23 Jun 2025 22:34:17 +0200 Subject: [PATCH 45/52] re-add openldap --- Makefile | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f72a9f9..9de22de 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,7 @@ #: core.packages #: core.sources #: i18n.gettext +#: ldap.openldap #: qa.black #: qa.coverage #: qa.isort @@ -44,6 +45,24 @@ INCLUDE_MAKEFILE?=include.mk # No default value. EXTRA_PATH?= +## ldap.openldap + +# OpenLDAP version to download +# Default: 2.4.59 +OPENLDAP_VERSION?=2.4.59 + +# OpenLDAP base download URL +# Default: https://www.openldap.org/software/download/OpenLDAP/openldap-release/ +OPENLDAP_URL?=https://www.openldap.org/software/download/OpenLDAP/openldap-release/ + +# Build directory for OpenLDAP +# Default: $(shell echo $(realpath .))/openldap +OPENLDAP_DIR?=$(shell echo $(realpath .))/openldap + +# Build environment for OpenLDAP +# Default: PATH=/usr/local/bin:/usr/bin:/bin +OPENLDAP_ENV?=PATH=/usr/local/bin:/usr/bin:/bin + ## core.mxenv # Primary Python interpreter to use. It is used to create the @@ -141,7 +160,7 @@ TEST_REQUIREMENTS?=zope.testrunner # Additional make targets the test target depends on. # No default value. -TEST_DEPENDENCY_TARGETS?= +TEST_DEPENDENCY_TARGETS?=openldap ## qa.coverage @@ -228,6 +247,50 @@ $(SENTINEL): $(firstword $(MAKEFILE_LIST)) @mkdir -p $(SENTINEL_FOLDER) @echo "Sentinels for the Makefile process." > $(SENTINEL) +############################################################################## +# openldap +############################################################################## + +# case `system.dependencies` domain is included +SYSTEM_DEPENDENCIES+=libdb-dev libsasl2-dev + +OPENLDAP_TARGET:=$(SENTINEL_FOLDER)/openldap.sentinel +$(OPENLDAP_TARGET): $(SENTINEL) + @echo "Building openldap server in '$(OPENLDAP_DIR)'" + @test -d $(OPENLDAP_DIR) || curl -o openldap-$(OPENLDAP_VERSION).tgz \ + $(OPENLDAP_URL)/openldap-$(OPENLDAP_VERSION).tgz + @test -d $(OPENLDAP_DIR) || tar xf openldap-$(OPENLDAP_VERSION).tgz + @test -d $(OPENLDAP_DIR) || rm openldap-$(OPENLDAP_VERSION).tgz + @test -d $(OPENLDAP_DIR) || mv openldap-$(OPENLDAP_VERSION) $(OPENLDAP_DIR) + @env -i -C $(OPENLDAP_DIR) $(OPENLDAP_ENV) bash -c \ + './configure \ + --with-tls \ + --enable-slapd=yes \ + --enable-overlays \ + --prefix=$(OPENLDAP_DIR) \ + && make depend \ + && make -j4 \ + && make install' + @touch $(OPENLDAP_TARGET) + +.PHONY: openldap +openldap: $(OPENLDAP_TARGET) + +.PHONY: openldap-dirty +openldap-dirty: + @test -d $(OPENLDAP_DIR) \ + && env -i -C $(OPENLDAP_DIR) $(OPENLDAP_ENV) bash -c 'make clean' + @rm -f $(OPENLDAP_TARGET) + +.PHONY: openldap-clean +openldap-clean: + @rm -f $(OPENLDAP_TARGET) + @rm -rf $(OPENLDAP_DIR) + +INSTALL_TARGETS+=openldap +DIRTY_TARGETS+=openldap-dirty +CLEAN_TARGETS+=openldap-clean + ############################################################################## # mxenv ############################################################################## From cba6f0501c042363b6a9fec3bf429beb545c7885 Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Mon, 23 Jun 2025 22:54:53 +0200 Subject: [PATCH 46/52] stuff for openldap --- .github/workflows/tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index db8215b..c80eee4 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -27,7 +27,7 @@ jobs: run: | curl -LsSf https://astral.sh/uv/install.sh | sh sudo apt-get update -y - sudo apt-get install -y libsasl2-dev libssl-dev libdb-dev libldap2-dev slapd + sudo apt-get install -y build-essential libsasl2-dev libssl-dev libdb-dev libldap2-dev - name: Setup Plone ${{ matrix.plone }} with Python ${{ matrix.python }} id: setup From 462cb357e6bf0e2847a11ab98ac185711a1f894a Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Mon, 23 Jun 2025 23:00:15 +0200 Subject: [PATCH 47/52] remove deprecationwarning --- src/pas/plugins/ldap/plonecontrolpanel/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pas/plugins/ldap/plonecontrolpanel/__init__.py b/src/pas/plugins/ldap/plonecontrolpanel/__init__.py index 698012e..cbcc105 100644 --- a/src/pas/plugins/ldap/plonecontrolpanel/__init__.py +++ b/src/pas/plugins/ldap/plonecontrolpanel/__init__.py @@ -1,4 +1,4 @@ -from Products.CMFPlone.interfaces.installable import INonInstallable +from plone.base.interfaces import INonInstallable from zope.interface import implementer From 2d4e95538b753c123b7f71a8207e4895daadbca8 Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Tue, 24 Jun 2025 00:51:41 +0200 Subject: [PATCH 48/52] mxmake update --- Makefile | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Makefile b/Makefile index 9de22de..8771d2c 100644 --- a/Makefile +++ b/Makefile @@ -67,6 +67,9 @@ OPENLDAP_ENV?=PATH=/usr/local/bin:/usr/bin:/bin # Primary Python interpreter to use. It is used to create the # virtual environment if `VENV_ENABLED` and `VENV_CREATE` are set to `true`. +# If global `uv` is used, this value is passed as `--python VALUE` to the venv creation. +# uv then downloads the Python interpreter if it is not available. +# for more on this feature read the [uv python documentation](https://docs.astral.sh/uv/concepts/python-versions/) # Default: python3 PRIMARY_PYTHON?=3.12 @@ -320,8 +323,12 @@ endif MXENV_TARGET:=$(SENTINEL_FOLDER)/mxenv.sentinel $(MXENV_TARGET): $(SENTINEL) +ifneq ("$(PYTHON_PACKAGE_INSTALLER)$(MXENV_UV_GLOBAL)","uvfalse") @$(PRIMARY_PYTHON) -c "import sys; vi = sys.version_info; sys.exit(1 if (int(vi[0]), int(vi[1])) >= tuple(map(int, '$(PYTHON_MIN_VERSION)'.split('.'))) else 0)" \ && echo "Need Python >= $(PYTHON_MIN_VERSION)" && exit 1 || : +else + @echo "Use Python $(PYTHON_MIN_VERSION) over uv" +endif @[[ "$(VENV_ENABLED)" == "true" && "$(VENV_FOLDER)" == "" ]] \ && echo "VENV_FOLDER must be configured if VENV_ENABLED is true" && exit 1 || : @[[ "$(VENV_ENABLED)$(PYTHON_PACKAGE_INSTALLER)" == "falseuv" ]] \ From 196ea43cc1feeab3096dbc2019cb940fdfebf388 Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Tue, 24 Jun 2025 01:04:05 +0200 Subject: [PATCH 49/52] set SLAPD_BIN for test runner --- mx.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/mx.ini b/mx.ini index c39694f..b1144c4 100644 --- a/mx.ini +++ b/mx.ini @@ -16,6 +16,7 @@ mxmake-templates = [mxmake-env] # VAR = value testpaths = tests +SLAPD_BIN = ./openldap/sbin/slapd [mxmake-run-tests] environment = env From 311995694eb2678cfca974cf88cdb0457b3824e9 Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Tue, 24 Jun 2025 01:23:27 +0200 Subject: [PATCH 50/52] fix LDAP build and suage --- Makefile | 4 ++-- mx.ini | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 8771d2c..730d85d 100644 --- a/Makefile +++ b/Makefile @@ -49,7 +49,7 @@ EXTRA_PATH?= # OpenLDAP version to download # Default: 2.4.59 -OPENLDAP_VERSION?=2.4.59 +OPENLDAP_VERSION?=2.6.9 # OpenLDAP base download URL # Default: https://www.openldap.org/software/download/OpenLDAP/openldap-release/ @@ -263,13 +263,13 @@ $(OPENLDAP_TARGET): $(SENTINEL) @test -d $(OPENLDAP_DIR) || curl -o openldap-$(OPENLDAP_VERSION).tgz \ $(OPENLDAP_URL)/openldap-$(OPENLDAP_VERSION).tgz @test -d $(OPENLDAP_DIR) || tar xf openldap-$(OPENLDAP_VERSION).tgz - @test -d $(OPENLDAP_DIR) || rm openldap-$(OPENLDAP_VERSION).tgz @test -d $(OPENLDAP_DIR) || mv openldap-$(OPENLDAP_VERSION) $(OPENLDAP_DIR) @env -i -C $(OPENLDAP_DIR) $(OPENLDAP_ENV) bash -c \ './configure \ --with-tls \ --enable-slapd=yes \ --enable-overlays \ + --without-systemd \ --prefix=$(OPENLDAP_DIR) \ && make depend \ && make -j4 \ diff --git a/mx.ini b/mx.ini index b1144c4..fba898b 100644 --- a/mx.ini +++ b/mx.ini @@ -16,7 +16,9 @@ mxmake-templates = [mxmake-env] # VAR = value testpaths = tests -SLAPD_BIN = ./openldap/sbin/slapd +SLAPD_BIN = ./openldap/libexec/slapd +LDAP_ADD_BIN = ./openldap/bin/ldapadd +LDAP_DELETE_BIN = ./openldap/bin/ldapdelete [mxmake-run-tests] environment = env From 0988299386d67f696a88c37aed91eeda0a5d9a48 Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Tue, 24 Jun 2025 08:13:27 +0200 Subject: [PATCH 51/52] add changelog --- CHANGES.rst | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index ca511d4..715e307 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,26 @@ History 2.0.0 (unreleased) ------------------ -- todo +- Target Plone 6.x only. Drop support for Python < 3.10. + [jensens] + +- Updated package metadata to use `pyproject.toml` and drop `setuptools`. + [jensens] + +- Use mxmake exclusively for development and testing. + [jensens] + +- Refactor test setup to use pytest as runner. + [jensens] + +- Increase PAS_PLUGINS_LDAP_OPT_TIMEOUT t + +- Add i18n support and Spanish translation. + [macagua] + +- Remove five.globalrequest dependency. + [cillianderoiste] + 1.9.0 (unreleased) ------------------ From cdee0790146e39121bf060e0c5ced672795d7d48 Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Tue, 24 Jun 2025 10:22:57 +0200 Subject: [PATCH 52/52] make format --- src/pas/plugins/ldap/__init__.py | 2 ++ src/pas/plugins/ldap/cache.py | 2 +- src/pas/plugins/ldap/locales/__main__.py | 4 ++-- src/pas/plugins/ldap/plonecontrolpanel/__init__.py | 1 - src/pas/plugins/ldap/plonecontrolpanel/cache.py | 2 +- src/pas/plugins/ldap/plonecontrolpanel/controlpanel.py | 2 +- src/pas/plugins/ldap/plonecontrolpanel/exportimport.py | 2 +- .../plonecontrolpanel/profiles/default/controlpanel.xml | 3 ++- .../plonecontrolpanel/profiles/default/ldapsettings.xml | 2 +- .../ldap/plonecontrolpanel/profiles/default/metadata.xml | 2 +- .../ldap/plonecontrolpanel/profiles/default/registry.xml | 5 +++-- src/pas/plugins/ldap/plugin.py | 8 ++------ src/pas/plugins/ldap/profile/metadata.xml | 2 +- src/pas/plugins/ldap/properties.py | 5 +++-- 14 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/pas/plugins/ldap/__init__.py b/src/pas/plugins/ldap/__init__.py index 874b91d..fdaa9f2 100644 --- a/src/pas/plugins/ldap/__init__.py +++ b/src/pas/plugins/ldap/__init__.py @@ -1,4 +1,5 @@ """Init and utils.""" + from . import monkey # noqa from .plugin import LDAPPlugin from .plugin import manage_addLDAPPlugin @@ -11,6 +12,7 @@ import logging import os + PACKAGE_NAME = "pas.plugins.ldap" _ = MessageFactory(PACKAGE_NAME) diff --git a/src/pas/plugins/ldap/cache.py b/src/pas/plugins/ldap/cache.py index f90f708..bd1e5ae 100644 --- a/src/pas/plugins/ldap/cache.py +++ b/src/pas/plugins/ldap/cache.py @@ -1,4 +1,3 @@ -import re from .interfaces import ICacheSettingsRecordProvider from .interfaces import ILDAPPlugin from .interfaces import IPluginCacheHandler @@ -11,6 +10,7 @@ from zope.globalrequest import getRequest from zope.interface import implementer +import re import threading import time diff --git a/src/pas/plugins/ldap/locales/__main__.py b/src/pas/plugins/ldap/locales/__main__.py index 6ca0d07..c4b7125 100644 --- a/src/pas/plugins/ldap/locales/__main__.py +++ b/src/pas/plugins/ldap/locales/__main__.py @@ -26,8 +26,8 @@ def i18n_script_setup(): """Setup the i18n scripts""" - cmd_i18ndude = ("uvx i18ndude") - cmd_lingua = ("uvx lingua") + cmd_i18ndude = "uvx i18ndude" + cmd_lingua = "uvx lingua" subprocess.call(cmd_i18ndude, shell=True) # noQA: S602 subprocess.call(cmd_lingua, shell=True) # noQA: S602 diff --git a/src/pas/plugins/ldap/plonecontrolpanel/__init__.py b/src/pas/plugins/ldap/plonecontrolpanel/__init__.py index cbcc105..28d4f7f 100644 --- a/src/pas/plugins/ldap/plonecontrolpanel/__init__.py +++ b/src/pas/plugins/ldap/plonecontrolpanel/__init__.py @@ -16,4 +16,3 @@ def getNonInstallableProducts(self): def getNonInstallableProfiles(self): return self._hidden - diff --git a/src/pas/plugins/ldap/plonecontrolpanel/cache.py b/src/pas/plugins/ldap/plonecontrolpanel/cache.py index aafeb90..f752ed0 100644 --- a/src/pas/plugins/ldap/plonecontrolpanel/cache.py +++ b/src/pas/plugins/ldap/plonecontrolpanel/cache.py @@ -1,6 +1,6 @@ from ..interfaces import ICacheSettingsRecordProvider -from persistent import Persistent from pas.plugins.ldap import _ +from persistent import Persistent from plone.registry import field from plone.registry import Record from plone.registry.interfaces import IRegistry diff --git a/src/pas/plugins/ldap/plonecontrolpanel/controlpanel.py b/src/pas/plugins/ldap/plonecontrolpanel/controlpanel.py index 51acb01..c947f4a 100644 --- a/src/pas/plugins/ldap/plonecontrolpanel/controlpanel.py +++ b/src/pas/plugins/ldap/plonecontrolpanel/controlpanel.py @@ -1,8 +1,8 @@ from ..properties import BasePropertiesForm +from pas.plugins.ldap import _ from Products.CMFCore.interfaces import ISiteRoot from Products.CMFPlone.resources import add_bundle_on_request from Products.statusmessages.interfaces import IStatusMessage -from pas.plugins.ldap import _ from zope.component import getUtility diff --git a/src/pas/plugins/ldap/plonecontrolpanel/exportimport.py b/src/pas/plugins/ldap/plonecontrolpanel/exportimport.py index eb88069..cb398fe 100644 --- a/src/pas/plugins/ldap/plonecontrolpanel/exportimport.py +++ b/src/pas/plugins/ldap/plonecontrolpanel/exportimport.py @@ -1,7 +1,7 @@ from BTrees.OOBTree import OOBTree +from pas.plugins.ldap import PACKAGE_NAME from Products.GenericSetup.interfaces import IBody from Products.GenericSetup.utils import XMLAdapterBase -from pas.plugins.ldap import PACKAGE_NAME from zope.component import queryMultiAdapter from zope.interface import implementer diff --git a/src/pas/plugins/ldap/plonecontrolpanel/profiles/default/controlpanel.xml b/src/pas/plugins/ldap/plonecontrolpanel/profiles/default/controlpanel.xml index d47af62..b6b493c 100644 --- a/src/pas/plugins/ldap/plonecontrolpanel/profiles/default/controlpanel.xml +++ b/src/pas/plugins/ldap/plonecontrolpanel/profiles/default/controlpanel.xml @@ -2,7 +2,8 @@ + i18n:domain="pas.plugins.ldap" +> + + 1 diff --git a/src/pas/plugins/ldap/plonecontrolpanel/profiles/default/registry.xml b/src/pas/plugins/ldap/plonecontrolpanel/profiles/default/registry.xml index 563fe75..2ad9dda 100644 --- a/src/pas/plugins/ldap/plonecontrolpanel/profiles/default/registry.xml +++ b/src/pas/plugins/ldap/plonecontrolpanel/profiles/default/registry.xml @@ -1,6 +1,7 @@ - + + i18n:domain="pas.plugins.ldap" +> diff --git a/src/pas/plugins/ldap/plugin.py b/src/pas/plugins/ldap/plugin.py index 790783f..bc4488b 100644 --- a/src/pas/plugins/ldap/plugin.py +++ b/src/pas/plugins/ldap/plugin.py @@ -36,12 +36,8 @@ LDAP_LONG_RUNNING_LOG_THRESHOLD = float( os.environ.get("PAS_PLUGINS_LDAP_LONG_RUNNING_LOG_THRESHOLD", 5.0) ) -OPT_NETWORK_TIMEOUT = float( - os.environ.get("PAS_PLUGINS_LDAP_OPT_NETWORK_TIMEOUT", 1.0) -) -OPT_TIMEOUT = float( - os.environ.get("PAS_PLUGINS_LDAP_OPT_TIMEOUT", 30.0) -) +OPT_NETWORK_TIMEOUT = float(os.environ.get("PAS_PLUGINS_LDAP_OPT_NETWORK_TIMEOUT", 1.0)) +OPT_TIMEOUT = float(os.environ.get("PAS_PLUGINS_LDAP_OPT_TIMEOUT", 30.0)) # initial connection timeout ldap.set_option(ldap.OPT_NETWORK_TIMEOUT, OPT_NETWORK_TIMEOUT) diff --git a/src/pas/plugins/ldap/profile/metadata.xml b/src/pas/plugins/ldap/profile/metadata.xml index d02ea5c..58133d6 100644 --- a/src/pas/plugins/ldap/profile/metadata.xml +++ b/src/pas/plugins/ldap/profile/metadata.xml @@ -1,4 +1,4 @@ - + 2 diff --git a/src/pas/plugins/ldap/properties.py b/src/pas/plugins/ldap/properties.py index 0f51b5a..4e3cfb3 100644 --- a/src/pas/plugins/ldap/properties.py +++ b/src/pas/plugins/ldap/properties.py @@ -11,7 +11,8 @@ from node.ext.ldap.scope import SUBTREE from node.ext.ldap.ugm import Ugm from odict import odict -from pas.plugins.ldap import _, logger +from pas.plugins.ldap import _ +from pas.plugins.ldap import logger from Products.Five import BrowserView from yafowil import loader # noqa: F401 from yafowil.base import ExtractionError @@ -205,7 +206,7 @@ def connection_test(self): return False, msg + str(e) try: ugm = Ugm("test", props=props, ucfg=users, gcfg=groups) - ugm.users.authenticate('foo', 'bar') + ugm.users.authenticate("foo", "bar") except ldap.SERVER_DOWN: return False, _("Server Down") except ldap.LDAPError as e:
Id Id
Title Title
- +