I recently wired together the GenericSetup handlers from PAS in an
extension profile for another product.  This way I can support fully
declaritive import/export steps for setting up a PAS user folder
within a CMF GS profile using the PAS subdirectory.  As such we can
avoid the declaritive abuse of GS used in borg, membrane, remember,

It all worked great with a minimum of code in the other product with
one exception.  If a plugin type and active plugins for that type have
been configured previously (whether by a GS profile or not) then
registering the plugin type again with a new list of active plugins
will result in duplicates in registry._plugin_types (as in
acl_users.plugins._plugin_types).  This doesn't actually break any
functionality but results in duplicates in the PAS ZMI.

Attached is a small patch that avoids this rather simply.  I'd love to
see it merged so I don't have to maintain changed copies in my own
product to have extension profiles that modify a PAS UF configuration.

Index: exportimport.py
--- exportimport.py	(revision 71599)
+++ exportimport.py	(working copy)
@@ -81,7 +81,9 @@
     for info in reg_info['plugin_types']:
         iface = _resolveDottedName(info['interface'])
-        registry._plugin_types.append(iface)
+        # Avoid duplicate plugin types
+        if iface not in registry._plugin_types:
+            registry._plugin_types.append(iface)
         registry._plugin_type_info[iface] = {'id': info['id'],
                                              'title': info['title'],
                                              'description': info['description'],
I've also attached the module within my product's exportimport package
and the overrides.zcml used in case this is of interest to anyone.

"""GenericSetup export/import handlers for setting up
PluggableAuthService plugins in acl_users."""

from StringIO import StringIO

from Persistence import PersistentMapping

from Products.GenericSetup.interfaces import IFilesystemImporter
from Products.GenericSetup.interfaces import IFilesystemExporter
from Products.GenericSetup.utils import _resolveDottedName
from Products.GenericSetup.content import FauxDAVRequest
from Products.GenericSetup.content import FauxDAVResponse

from Products.PluginRegistry.exportimport import PluginRegistryFileExportImportAdapter as Base
from Products.PluginRegistry.exportimport import PluginRegistryImporter
from Products.PluginRegistry.exportimport import _FILENAME
from Products.CMFCore.utils import getToolByName

# TODO: Wire up importers that don't remove objects not specified in
# either .preserve or .objects

def importPAS(context):
    """Import and setup any PAS plugins."""
    uf = getToolByName(context.getSite(), 'acl_users')
    IFilesystemImporter(uf).import_(context, 'PAS', True)

def exportPAS(context):
    """Export any PAS plugins with configurations."""
    uf = getToolByName(context.getSite(), 'acl_users')
    IFilesystemExporter(uf).export(context, 'PAS', True)

Attachment: overrides.zcml
Description: Binary data


Zope-PAS mailing list

Reply via email to