[Checkins] SVN: zope.app.authentication/trunk/ merge -r 117492:117504 svn+ssh://svn.zope.org/repos/main/zope.app.authentication/branches/jw-move-authenticator-plugins

Jan-Wijbrand Kolman janwijbrand at gmail.com
Mon Oct 18 05:40:32 EDT 2010


Log message for revision 117633:
  merge -r 117492:117504 svn+ssh://svn.zope.org/repos/main/zope.app.authentication/branches/jw-move-authenticator-plugins

Changed:
  U   zope.app.authentication/trunk/CHANGES.txt
  U   zope.app.authentication/trunk/buildout.cfg
  U   zope.app.authentication/trunk/setup.py
  U   zope.app.authentication/trunk/src/zope/app/authentication/configure.zcml
  U   zope.app.authentication/trunk/src/zope/app/authentication/groupfolder.py
  U   zope.app.authentication/trunk/src/zope/app/authentication/groupfolder.zcml
  U   zope.app.authentication/trunk/src/zope/app/authentication/idpicker.py
  U   zope.app.authentication/trunk/src/zope/app/authentication/interfaces.py
  U   zope.app.authentication/trunk/src/zope/app/authentication/principalfolder.py
  U   zope.app.authentication/trunk/src/zope/app/authentication/principalfolder.zcml

-=-
Modified: zope.app.authentication/trunk/CHANGES.txt
===================================================================
--- zope.app.authentication/trunk/CHANGES.txt	2010-10-18 09:32:52 UTC (rev 117632)
+++ zope.app.authentication/trunk/CHANGES.txt	2010-10-18 09:40:31 UTC (rev 117633)
@@ -5,6 +5,9 @@
 3.9 (unreleased)
 ----------------
 
+* Move concrete IAuthenticatorPlugin implementations to
+  zope.pluggableauth.plugins. Leave backwards compatibility imports.
+
 * Use zope.formlib throughout to lift the dependency on zope.app.form. As it
   turns out, zope.app.form is still a indirect test dependency though.
 

Modified: zope.app.authentication/trunk/buildout.cfg
===================================================================
--- zope.app.authentication/trunk/buildout.cfg	2010-10-18 09:32:52 UTC (rev 117632)
+++ zope.app.authentication/trunk/buildout.cfg	2010-10-18 09:40:31 UTC (rev 117633)
@@ -1,10 +1,13 @@
 [buildout]
 extends =
-  http://download.zope.org/zopetoolkit/index/1.0c3/ztk-versions.cfg
-  http://download.zope.org/zopetoolkit/index/1.0c3/zopeapp-versions.cfg
+  http://download.zope.org/zopetoolkit/index/1.0/ztk-versions.cfg
+  http://download.zope.org/zopetoolkit/index/1.0/zopeapp-versions.cfg
 develop = .
 parts = test
 
+[versions]
+zope.pluggableauth = 1.1.0
+
 [test]
 recipe = zc.recipe.testrunner
 eggs = zope.app.authentication [test]

Modified: zope.app.authentication/trunk/setup.py
===================================================================
--- zope.app.authentication/trunk/setup.py	2010-10-18 09:32:52 UTC (rev 117632)
+++ zope.app.authentication/trunk/setup.py	2010-10-18 09:40:31 UTC (rev 117633)
@@ -87,11 +87,10 @@
           'zope.interface',
           'zope.location',
           'zope.password >= 3.5.1',
-          'zope.pluggableauth >= 1.0.1',
+          'zope.pluggableauth >= 1.1',
           'zope.schema',
           'zope.security',
           'zope.traversing',
-
           # Needed for browser code.
           'zope.app.container',
           'zope.app.component',

Modified: zope.app.authentication/trunk/src/zope/app/authentication/configure.zcml
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/configure.zcml	2010-10-18 09:32:52 UTC (rev 117632)
+++ zope.app.authentication/trunk/src/zope/app/authentication/configure.zcml	2010-10-18 09:40:31 UTC (rev 117633)
@@ -56,8 +56,10 @@
   <include file="password.zcml" />
   <include file="session.zcml" />
   <include file="httpplugins.zcml" />
+
   <include file="principalfolder.zcml" />
   <include file="groupfolder.zcml" />
+
   <include file="ftpplugins.zcml" />
 
   <include package=".browser" />

Modified: zope.app.authentication/trunk/src/zope/app/authentication/groupfolder.py
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/groupfolder.py	2010-10-18 09:32:52 UTC (rev 117632)
+++ zope.app.authentication/trunk/src/zope/app/authentication/groupfolder.py	2010-10-18 09:40:31 UTC (rev 117633)
@@ -16,348 +16,21 @@
 $Id$
 
 """
-import BTrees.OOBTree
-import persistent
-
-from zope import interface, event, schema, component
-from zope.interface import alsoProvides
-from zope.security.interfaces import (
-    IGroup, IGroupAwarePrincipal, IMemberAwareGroup)
-
-from zope.container.btree import BTreeContainer
-import zope.container.constraints
-import zope.container.interfaces
-from zope.app.authentication.i18n import ZopeMessageFactory as _
-import zope.authentication.principal
-from zope.authentication.interfaces import (
-    IAuthentication, IAuthenticatedGroup, IEveryoneGroup)
-from zope.app.authentication import principalfolder, interfaces
-
-
-class IGroupInformation(interface.Interface):
-
-    title = schema.TextLine(
-        title=_("Title"),
-        description=_("Provides a title for the permission."),
-        required=True)
-
-    description = schema.Text(
-        title=_("Description"),
-        description=_("Provides a description for the permission."),
-        required=False)
-
-    principals = schema.List(
-        title=_("Principals"),
-        value_type=schema.Choice(
-            source=zope.authentication.principal.PrincipalSource()),
-        description=_(
-        "List of ids of principals which belong to the group"),
-        required=False)
-
-
-class IGroupFolder(zope.container.interfaces.IContainer):
-
-    zope.container.constraints.contains(IGroupInformation)
-
-    prefix = schema.TextLine(
-        title=_("Group ID prefix"),
-        description=_("Prefix added to IDs of groups in this folder"),
-        readonly=True,
-        )
-
-    def getGroupsForPrincipal(principalid):
-        """Get groups the given principal belongs to"""
-
-    def getPrincipalsForGroup(groupid):
-        """Get principals which belong to the group"""
-
-
-class IGroupContained(zope.container.interfaces.IContained):
-
-    zope.container.constraints.containers(IGroupFolder)
-
-class IGroupSearchCriteria(interface.Interface):
-
-    search = schema.TextLine(
-        title=_("Group Search String"),
-        required=False,
-        missing_value=u'',
-        )
-
-class IGroupPrincipalInfo(interfaces.IPrincipalInfo):
-    members = interface.Attribute('an iterable of members of the group')
-
-class GroupInfo(object):
-    """An implementation of IPrincipalInfo used by the group folder.
-
-    A group info is created with id, title, and description:
-
-      >>> class DemoGroupInformation(object):
-      ...     interface.implements(IGroupInformation)
-      ...     def __init__(self, title, description, principals):
-      ...         self.title = title
-      ...         self.description = description
-      ...         self.principals = principals
-      ...
-      >>> i = DemoGroupInformation(
-      ...     'Managers', 'Taskmasters', ('joe', 'jane'))
-      ...
-      >>> info = GroupInfo('groups.managers', i)
-      >>> info
-      GroupInfo('groups.managers')
-      >>> info.id
-      'groups.managers'
-      >>> info.title
-      'Managers'
-      >>> info.description
-      'Taskmasters'
-      >>> info.members
-      ('joe', 'jane')
-      >>> info.members = ('joe', 'jane', 'jaime')
-      >>> info.members
-      ('joe', 'jane', 'jaime')
-
-    """
-    interface.implements(IGroupPrincipalInfo)
-
-    def __init__(self, id, information):
-        self.id = id
-        self._information = information
-
-    @property
-    def title(self):
-        return self._information.title
-
-    @property
-    def description(self):
-        return self._information.description
-
-    @apply
-    def members():
-        def get(self):
-            return self._information.principals
-        def set(self, value):
-            self._information.principals = value
-        return property(get, set)
-
-    def __repr__(self):
-        return 'GroupInfo(%r)' % self.id
-
-
-class GroupFolder(BTreeContainer):
-
-    interface.implements(
-        interfaces.IAuthenticatorPlugin,
-        interfaces.IQuerySchemaSearch,
-        IGroupFolder)
-
-    schema = IGroupSearchCriteria
-
-    def __init__(self, prefix=u''):
-        super(GroupFolder, self).__init__()
-        self.prefix = prefix
-        # __inversemapping is used to map principals to groups
-        self.__inverseMapping = BTrees.OOBTree.OOBTree()
-
-    def __setitem__(self, name, value):
-        BTreeContainer.__setitem__(self, name, value)
-        group_id = self._groupid(value)
-        self._addPrincipalsToGroup(value.principals, group_id)
-        if value.principals:
-            event.notify(
-                interfaces.PrincipalsAddedToGroup(
-                    value.principals, self.__parent__.prefix + group_id))
-        group = principalfolder.Principal(self.prefix + name)
-        event.notify(interfaces.GroupAdded(group))
-
-    def __delitem__(self, name):
-        value = self[name]
-        group_id = self._groupid(value)
-        self._removePrincipalsFromGroup(value.principals, group_id)
-        if value.principals:
-            event.notify(
-                interfaces.PrincipalsRemovedFromGroup(
-                    value.principals, self.__parent__.prefix + group_id))
-        BTreeContainer.__delitem__(self, name)
-
-    def _groupid(self, group):
-        return self.prefix+group.__name__
-
-    def _addPrincipalsToGroup(self, principal_ids, group_id):
-        for principal_id in principal_ids:
-            self.__inverseMapping[principal_id] = (
-                self.__inverseMapping.get(principal_id, ())
-                + (group_id,))
-
-    def _removePrincipalsFromGroup(self, principal_ids, group_id):
-        for principal_id in principal_ids:
-            groups = self.__inverseMapping.get(principal_id)
-            if groups is None:
-                return
-            new = tuple([id for id in groups if id != group_id])
-            if new:
-                self.__inverseMapping[principal_id] = new
-            else:
-                del self.__inverseMapping[principal_id]
-
-    def getGroupsForPrincipal(self, principalid):
-        """Get groups the given principal belongs to"""
-        return self.__inverseMapping.get(principalid, ())
-
-    def getPrincipalsForGroup(self, groupid):
-        """Get principals which belong to the group"""
-        return self[groupid].principals
-
-    def search(self, query, start=None, batch_size=None):
-        """ Search for groups"""
-        search = query.get('search')
-        if search is not None:
-            n = 0
-            search = search.lower()
-            for i, (id, groupinfo) in enumerate(self.items()):
-                if (search in groupinfo.title.lower() or
-                    (groupinfo.description and 
-                     search in groupinfo.description.lower())):
-                    if not ((start is not None and i < start)
-                            or
-                            (batch_size is not None and n >= batch_size)):
-                        n += 1
-                        yield self.prefix + id
-
-    def authenticateCredentials(self, credentials):
-        # user folders don't authenticate
-        pass
-
-    def principalInfo(self, id):
-        if id.startswith(self.prefix):
-            id = id[len(self.prefix):]
-            info = self.get(id)
-            if info is not None:
-                return GroupInfo(
-                    self.prefix+id, info)
-
-class GroupCycle(Exception):
-    """There is a cyclic relationship among groups
-    """
-
-class InvalidPrincipalIds(Exception):
-    """A user has a group id for a group that can't be found
-    """
-
-class InvalidGroupId(Exception):
-    """A user has a group id for a group that can't be found
-    """
-
-def nocycles(principal_ids, seen, getPrincipal):
-    for principal_id in principal_ids:
-        if principal_id in seen:
-            raise GroupCycle(principal_id, seen)
-        seen.append(principal_id)
-        principal = getPrincipal(principal_id)
-        nocycles(principal.groups, seen, getPrincipal)
-        seen.pop()
-
-class GroupInformation(persistent.Persistent):
-
-    interface.implements(IGroupInformation, IGroupContained)
-
-    __parent__ = __name__ = None
-
-    _principals = ()
-
-    def __init__(self, title='', description=''):
-        self.title = title
-        self.description = description
-
-    def setPrincipals(self, prinlist, check=True):
-        # method is not a part of the interface
-        parent = self.__parent__
-        old = self._principals
-        self._principals = tuple(prinlist)
-
-        if parent is not None:
-            oldset = set(old)
-            new = set(prinlist)
-            group_id = parent._groupid(self)
-            removed = oldset - new
-            added = new - oldset
-            try:
-                parent._removePrincipalsFromGroup(removed, group_id)
-            except AttributeError:
-                removed = None
-
-            try:
-                parent._addPrincipalsToGroup(added, group_id)
-            except AttributeError:
-                added = None
-
-            if check:
-                try:
-                    principalsUtility = component.getUtility(IAuthentication)
-                    nocycles(new, [], principalsUtility.getPrincipal)
-                except GroupCycle:
-                    # abort
-                    self.setPrincipals(old, False)
-                    raise
-            # now that we've gotten past the checks, fire the events.
-            if removed:
-                event.notify(
-                    interfaces.PrincipalsRemovedFromGroup(
-                        removed, self.__parent__.__parent__.prefix + group_id))
-            if added:
-                event.notify(
-                    interfaces.PrincipalsAddedToGroup(
-                        added, self.__parent__.__parent__.prefix + group_id))
-
-    principals = property(lambda self: self._principals, setPrincipals)
-
-
-def specialGroups(event):
-    principal = event.principal
-    if (IGroup.providedBy(principal) or
-        not IGroupAwarePrincipal.providedBy(principal)):
-        return
-
-    everyone = component.queryUtility(IEveryoneGroup)
-    if everyone is not None:
-        principal.groups.append(everyone.id)
-
-    auth = component.queryUtility(IAuthenticatedGroup)
-    if auth is not None:
-        principal.groups.append(auth.id)
-
-
-def setGroupsForPrincipal(event):
-    """Set group information when a principal is created"""
-
-    principal = event.principal
-    if not IGroupAwarePrincipal.providedBy(principal):
-        return
-
-    authentication = event.authentication
-
-    for name, plugin in authentication.getAuthenticatorPlugins():
-        if not IGroupFolder.providedBy(plugin):
-            continue
-        groupfolder = plugin
-        principal.groups.extend(
-            [authentication.prefix + id
-             for id in groupfolder.getGroupsForPrincipal(principal.id)
-             ])
-        id = principal.id
-        prefix = authentication.prefix + groupfolder.prefix
-        if id.startswith(prefix) and id[len(prefix):] in groupfolder:
-            alsoProvides(principal, IGroup)
-
- at component.adapter(interfaces.IFoundPrincipalCreated)
-def setMemberSubscriber(event):
-    """adds `getMembers`, `setMembers` to groups made from IGroupPrincipalInfo.
-    """
-    info = event.info
-    if IGroupPrincipalInfo.providedBy(info):
-        principal = event.principal
-        principal.getMembers = lambda : info.members
-        def setMembers(value):
-            info.members = value
-        principal.setMembers = setMembers
-        alsoProvides(principal, IMemberAwareGroup)
+# BBB using zope.pluggableauth.plugin.groupfolder
+from zope.pluggableauth.plugins.groupfolder import (
+    GroupCycle,
+    GroupFolder,
+    GroupInfo,
+    GroupInformation,
+    IGroupContained,
+    IGroupFolder,
+    IGroupInformation,
+    IGroupPrincipalInfo,
+    IGroupSearchCriteria,
+    InvalidGroupId,
+    InvalidPrincipalIds,
+    nocycles,
+    setGroupsForPrincipal,
+    setMemberSubscriber,
+    specialGroups,
+    )

Modified: zope.app.authentication/trunk/src/zope/app/authentication/groupfolder.zcml
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/groupfolder.zcml	2010-10-18 09:32:52 UTC (rev 117632)
+++ zope.app.authentication/trunk/src/zope/app/authentication/groupfolder.zcml	2010-10-18 09:40:31 UTC (rev 117633)
@@ -1,65 +1,47 @@
 <configure
-    xmlns="http://namespaces.zope.org/zope"
-    i18n_domain="zope"
-    >
+  xmlns="http://namespaces.zope.org/zope"
+  i18n_domain="zope"
+  >
 
+  <include package="zope.pluggableauth.plugins" file="groupfolder.zcml" />
+
   <class class=".groupfolder.GroupInformation">
     <implements
-        interface="zope.annotation.interfaces.IAttributeAnnotatable"
-        />
+      interface="zope.annotation.interfaces.IAttributeAnnotatable"
+    />
     <require
-        permission="zope.ManageServices"
-        interface=".groupfolder.IGroupInformation
-                   .groupfolder.IGroupContained"
-        set_schema=".groupfolder.IGroupInformation"
-        />
+      permission="zope.ManageServices"
+      interface=".groupfolder.IGroupInformation
+        .groupfolder.IGroupContained"
+      set_schema=".groupfolder.IGroupInformation"
+    />
   </class>
 
   <class class=".groupfolder.GroupFolder">
     <implements
-        interface=".groupfolder.IGroupFolder"
-        />
+      interface=".groupfolder.IGroupFolder"
+    />
     <require
-        permission="zope.ManageServices"
-        interface="zope.container.interfaces.IContainer
-                   zope.container.interfaces.INameChooser"
-        />
+      permission="zope.ManageServices"
+      interface="zope.container.interfaces.IContainer
+        zope.container.interfaces.INameChooser"
+    />
   </class>
 
-  <adapter
-      provides="zope.container.interfaces.INameChooser"
-      for=".groupfolder.IGroupFolder"
-      factory=".idpicker.IdPicker"
-      />
-
-  <subscriber
-      for=".interfaces.IPrincipalCreated"
-      handler=".groupfolder.specialGroups"
-      />
-
-  <subscriber
-      for=".interfaces.IPrincipalCreated"
-      handler=".groupfolder.setGroupsForPrincipal"
-      />
-
-  <subscriber
-      handler=".groupfolder.setMemberSubscriber"
-      />
-
   <include package=".browser" file="groupfolder.zcml" />
 
   <!-- Registering documentation with API doc -->
   <configure
-      xmlns:apidoc="http://namespaces.zope.org/apidoc"
-      xmlns:zcml="http://namespaces.zope.org/zcml"
-      zcml:condition="have apidoc">
+    xmlns:apidoc="http://namespaces.zope.org/apidoc"
+    xmlns:zcml="http://namespaces.zope.org/zcml"
+    zcml:condition="have apidoc">
 
     <apidoc:bookchapter
-        id="groupfolder"
-        title="Group Folders"
-        doc_path="groupfolder.txt"
-        parent="security/authentication"
-        />
+      id="groupfolder"
+      title="Group Folders"
+      doc_path="groupfolder.txt"
+      parent="security/authentication"
+    />
 
   </configure>
 

Modified: zope.app.authentication/trunk/src/zope/app/authentication/idpicker.py
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/idpicker.py	2010-10-18 09:32:52 UTC (rev 117632)
+++ zope.app.authentication/trunk/src/zope/app/authentication/idpicker.py	2010-10-18 09:40:31 UTC (rev 117633)
@@ -18,93 +18,5 @@
 """
 __docformat__ = 'restructuredtext'
 
-import re
-from zope.exceptions.interfaces import UserError
-from zope.container.contained import NameChooser
-from zope.app.authentication.i18n import ZopeMessageFactory as _
-
-ok = re.compile('[!-~]+$').match
-class IdPicker(NameChooser):
-    """Helper base class that picks principal ids.
-
-    Add numbers to ids given by users to make them unique.
-
-    The Id picker is a variation on the name chooser that picks numeric
-    ids when no name is given.
-
-      >>> from zope.app.authentication.idpicker import IdPicker
-      >>> IdPicker({}).chooseName('', None)
-      u'1'
-
-      >>> IdPicker({'1': 1}).chooseName('', None)
-      u'2'
-
-      >>> IdPicker({'2': 1}).chooseName('', None)
-      u'1'
-
-      >>> IdPicker({'1': 1}).chooseName('bob', None)
-      u'bob'
-
-      >>> IdPicker({'bob': 1}).chooseName('bob', None)
-      u'bob1'
-
-    """
-    def chooseName(self, name, object):
-        i = 0
-        name = unicode(name)
-        orig = name
-        while (not name) or (name in self.context):
-            i += 1
-            name = orig+str(i)
-
-        self.checkName(name, object)
-        return name
-
-    def checkName(self, name, object):
-        """Limit ids
-
-        Ids can only contain printable, non-space, 7-bit ASCII strings:
-
-        >>> from zope.app.authentication.idpicker import IdPicker
-        >>> IdPicker({}).checkName(u'1', None)
-        True
-
-        >>> IdPicker({}).checkName(u'bob', None)
-        True
-
-        >>> try:
-        ...     IdPicker({}).checkName(u'bob\xfa', None)
-        ... except UserError, e:
-        ...     print e
-        ...     # doctest: +NORMALIZE_WHITESPACE
-        Ids must contain only printable 7-bit non-space ASCII characters
-
-        >>> try:
-        ...     IdPicker({}).checkName(u'big bob', None)
-        ... except UserError, e:
-        ...     print e
-        ...     # doctest: +NORMALIZE_WHITESPACE
-        Ids must contain only printable 7-bit non-space ASCII characters
-
-        Ids also can't be over 100 characters long:
-
-        >>> IdPicker({}).checkName(u'x' * 100, None)
-        True
-
-        >>> IdPicker({}).checkName(u'x' * 101, None)
-        Traceback (most recent call last):
-        ...
-        UserError: Ids can't be more than 100 characters long.
-
-        """
-        NameChooser.checkName(self, name, object)
-        if not ok(name):
-            raise UserError(
-                _("Ids must contain only printable 7-bit non-space"
-                  " ASCII characters")
-                )
-        if len(name) > 100:
-            raise UserError(
-                _("Ids can't be more than 100 characters long.")
-                )
-        return True
+# BBB using zope.pluggableauth.plugins.idpicker
+from zope.pluggableauth.plugins.idpicker import IdPicker

Modified: zope.app.authentication/trunk/src/zope/app/authentication/interfaces.py
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/interfaces.py	2010-10-18 09:32:52 UTC (rev 117632)
+++ zope.app.authentication/trunk/src/zope/app/authentication/interfaces.py	2010-10-18 09:40:31 UTC (rev 117633)
@@ -27,108 +27,28 @@
 
 # BBB: using zope.pluggableauth
 from zope.pluggableauth.interfaces import (
-    IPlugin, IAuthenticatorPlugin, ICredentialsPlugin,
-    IPluggableAuthentication, IPrincipalInfo,
-    IFoundPrincipalFactory, IPrincipalFactory, IAuthenticatedPrincipalFactory,
-    IPrincipalCreated, IAuthenticatedPrincipalCreated,
-    AuthenticatedPrincipalCreated, IFoundPrincipalCreated,
-    FoundPrincipalCreated, IQueriableAuthenticator)
+    AuthenticatedPrincipalCreated,
+    FoundPrincipalCreated,
+    IAuthenticatedPrincipalCreated,
+    IAuthenticatedPrincipalFactory,
+    IAuthenticatorPlugin,
+    ICredentialsPlugin,
+    IFoundPrincipalCreated,
+    IFoundPrincipalFactory,
+    IGroupAdded,
+    IPluggableAuthentication,
+    IPlugin,
+    IPrincipal,
+    IPrincipalCreated,
+    IPrincipalFactory,
+    IPrincipalInfo,
+    IPrincipalsAddedToGroup,
+    IPrincipalsRemovedFromGroup,
+    IQueriableAuthenticator,
+    IQuerySchemaSearch,
+    )
 
-
-class IPrincipal(zope.security.interfaces.IGroupClosureAwarePrincipal):
-
-    groups = zope.schema.List(
-        title=_("Groups"),
-        description=_(
-            """ids of groups to which the principal directly belongs.
-
-            Plugins may append to this list.  Mutating the list only affects
-            the life of the principal object, and does not persist (so
-            persistently adding groups to a principal should be done by working
-            with a plugin that mutates this list every time the principal is
-            created, like the group folder in this package.)
-            """),
-        value_type=zope.schema.TextLine(),
-        required=False)
-
-
-class IQuerySchemaSearch(zope.interface.Interface):
-    """An interface for searching using schema-constrained input."""
-
-    schema = zope.interface.Attribute("""
-        The schema that constrains the input provided to the search method.
-
-        A mapping of name/value pairs for each field in this schema is used
-        as the query argument in the search method.
-        """)
-
-    def search(query, start=None, batch_size=None):
-        """Returns an iteration of principal IDs matching the query.
-
-        query is a mapping of name/value pairs for fields specified by the
-        schema.
-
-        If the start argument is provided, then it should be an
-        integer and the given number of initial items should be
-        skipped.
-
-        If the batch_size argument is provided, then it should be an
-        integer and no more than the given number of items should be
-        returned.
-        """
-
-
-class IGroupAdded(zope.interface.Interface):
-    """A group has been added."""
-
-    group = zope.interface.Attribute("""The group that was defined""")
-
-
-class GroupAdded:
-    """
-    >>> from zope.interface.verify import verifyObject
-    >>> event = GroupAdded("group")
-    >>> verifyObject(IGroupAdded, event)
-    True
-    """
-
-    zope.interface.implements(IGroupAdded)
-
-    def __init__(self, group):
-        self.group = group
-
-    def __repr__(self):
-        return "<GroupAdded %r>" % self.group.id
-
-
-class IPrincipalsAddedToGroup(zope.interface.Interface):
-    group_id = zope.interface.Attribute(
-        'the id of the group to which the principal was added')
-    principal_ids = zope.interface.Attribute(
-        'an iterable of one or more ids of principals added')
-
-
-class IPrincipalsRemovedFromGroup(zope.interface.Interface):
-    group_id = zope.interface.Attribute(
-        'the id of the group from which the principal was removed')
-    principal_ids = zope.interface.Attribute(
-        'an iterable of one or more ids of principals removed')
-
-
-class AbstractMembersChanged(object):
-
-    def __init__(self, principal_ids, group_id):
-        self.principal_ids = principal_ids
-        self.group_id = group_id
-
-    def __repr__(self):
-        return "<%s %r %r>" % (
-            self.__class__.__name__, sorted(self.principal_ids), self.group_id)
-
-
-class PrincipalsAddedToGroup(AbstractMembersChanged):
-    zope.interface.implements(IPrincipalsAddedToGroup)
-
-
-class PrincipalsRemovedFromGroup(AbstractMembersChanged):
-    zope.interface.implements(IPrincipalsRemovedFromGroup)
+# BBB: using zope.pluggableauth
+from zope.pluggableauth.plugins.groupfolder import (
+    GroupAdded,
+    )

Modified: zope.app.authentication/trunk/src/zope/app/authentication/principalfolder.py
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/principalfolder.py	2010-10-18 09:32:52 UTC (rev 117632)
+++ zope.app.authentication/trunk/src/zope/app/authentication/principalfolder.py	2010-10-18 09:40:31 UTC (rev 117633)
@@ -17,270 +17,20 @@
 """
 __docformat__ = "reStructuredText"
 
-from persistent import Persistent
-from zope.app.authentication.i18n import ZopeMessageFactory as _
-from zope.app.authentication.interfaces import IQuerySchemaSearch
-from zope.component import getUtility
-from zope.container.btree import BTreeContainer
-from zope.container.constraints import contains, containers
-from zope.container.contained import Contained
-from zope.container.interfaces import DuplicateIDError
-from zope.interface import implements, Interface
-from zope.password.interfaces import IPasswordManager
-from zope.schema import Text, TextLine, Password, Choice
-
 # BBB using zope.pluggableauth
 from zope.pluggableauth.interfaces import IAuthenticatorPlugin
 from zope.pluggableauth.factories import (
-    Principal, PrincipalInfo,
-    FoundPrincipalFactory, AuthenticatedPrincipalFactory)
-    
-
-class IInternalPrincipal(Interface):
-    """Principal information"""
-
-    login = TextLine(
-        title=_("Login"),
-        description=_("The Login/Username of the principal. "
-                      "This value can change."))
-
-    def setPassword(password, passwordManagerName=None):
-        pass
-
-    password = Password(
-        title=_("Password"),
-        description=_("The password for the principal."))
-
-    passwordManagerName = Choice(
-        title=_("Password Manager"),
-        vocabulary="Password Manager Names",
-        description=_("The password manager will be used"
-            " for encode/check the password"),
-        default="SSHA",
-        # TODO: The password manager name may be changed only
-        # if the password changed
-        readonly=True
-        )
-
-    title = TextLine(
-        title=_("Title"),
-        description=_("Provides a title for the principal."))
-
-    description = Text(
-        title=_("Description"),
-        description=_("Provides a description for the principal."),
-        required=False,
-        missing_value='',
-        default=u'')
-
-
-class IInternalPrincipalContainer(Interface):
-    """A container that contains internal principals."""
-
-    prefix = TextLine(
-        title=_("Prefix"),
-        description=_(
-        "Prefix to be added to all principal ids to assure "
-        "that all ids are unique within the authentication service"),
-        missing_value=u"",
-        default=u'',
-        readonly=True)
-
-    def getIdByLogin(login):
-        """Return the principal id currently associated with login.
-
-        The return value includes the container prefix, but does not
-        include the PAU prefix.
-
-        KeyError is raised if no principal is associated with login.
-
-        """
-
-    contains(IInternalPrincipal)
-
-
-class IInternalPrincipalContained(Interface):
-    """Principal information"""
-
-    containers(IInternalPrincipalContainer)
-
-
-class ISearchSchema(Interface):
-    """Search Interface for this Principal Provider"""
-
-    search = TextLine(
-        title=_("Search String"),
-        description=_("A Search String"),
-        required=False,
-        default=u'',
-        missing_value=u'')
-
-
-class InternalPrincipal(Persistent, Contained):
-    """An internal principal for Persistent Principal Folder."""
-
-    implements(IInternalPrincipal, IInternalPrincipalContained)
-
-    # If you're searching for self._passwordManagerName, or self._password
-    # probably you just need to evolve the database to new generation
-    # at /++etc++process/@@generations.html
-
-    # NOTE: All changes needs to be synchronized with the evolver at
-    # zope.app.zopeappgenerations.evolve2
-
-    def __init__(self, login, password, title, description=u'',
-            passwordManagerName="SSHA"):
-        self._login = login
-        self._passwordManagerName = passwordManagerName
-        self.password = password
-        self.title = title
-        self.description = description
-
-    def getPasswordManagerName(self):
-        return self._passwordManagerName
-
-    passwordManagerName = property(getPasswordManagerName)
-
-    def _getPasswordManager(self):
-        return getUtility(IPasswordManager, self.passwordManagerName)
-
-    def getPassword(self):
-        return self._password
-
-    def setPassword(self, password, passwordManagerName=None):
-        if passwordManagerName is not None:
-            self._passwordManagerName = passwordManagerName
-        passwordManager = self._getPasswordManager()
-        self._password = passwordManager.encodePassword(password)
-
-    password = property(getPassword, setPassword)
-
-    def checkPassword(self, password):
-        passwordManager = self._getPasswordManager()
-        return passwordManager.checkPassword(self.password, password)
-
-    def getLogin(self):
-        return self._login
-
-    def setLogin(self, login):
-        oldLogin = self._login
-        self._login = login
-        if self.__parent__ is not None:
-            try:
-                self.__parent__.notifyLoginChanged(oldLogin, self)
-            except ValueError:
-                self._login = oldLogin
-                raise
-
-    login = property(getLogin, setLogin)
-
-
-class PrincipalFolder(BTreeContainer):
-    """A Persistent Principal Folder and Authentication plugin.
-
-    See principalfolder.txt for details.
-    """
-
-    implements(IAuthenticatorPlugin,
-               IQuerySchemaSearch,
-               IInternalPrincipalContainer)
-
-    schema = ISearchSchema
-
-    def __init__(self, prefix=''):
-        self.prefix = unicode(prefix)
-        super(PrincipalFolder, self).__init__()
-        self.__id_by_login = self._newContainerData()
-
-    def notifyLoginChanged(self, oldLogin, principal):
-        """Notify the Container about changed login of a principal.
-
-        We need this, so that our second tree can be kept up-to-date.
-        """
-        # A user with the new login already exists
-        if principal.login in self.__id_by_login:
-            raise ValueError('Principal Login already taken!')
-
-        del self.__id_by_login[oldLogin]
-        self.__id_by_login[principal.login] = principal.__name__
-
-    def __setitem__(self, id, principal):
-        """Add principal information.
-
-        Create a Principal Folder
-
-            >>> pf = PrincipalFolder()
-
-        Create a principal with 1 as id
-        Add a login attr since __setitem__ is in need of one
-
-            >>> principal = Principal(1)
-            >>> principal.login = 1
-
-        Add the principal within the Principal Folder
-
-            >>> pf.__setitem__(u'1', principal)
-
-        Try to add another principal with the same id.
-        It should raise a DuplicateIDError
-
-            >>> try:
-            ...     pf.__setitem__(u'1', principal)
-            ... except DuplicateIDError, e:
-            ...     pass
-            >>>
-        """
-        # A user with the new login already exists
-        if principal.login in self.__id_by_login:
-            raise DuplicateIDError('Principal Login already taken!')
-
-        super(PrincipalFolder, self).__setitem__(id, principal)
-        self.__id_by_login[principal.login] = id
-
-    def __delitem__(self, id):
-        """Remove principal information."""
-        principal = self[id]
-        super(PrincipalFolder, self).__delitem__(id)
-        del self.__id_by_login[principal.login]
-
-    def authenticateCredentials(self, credentials):
-        """Return principal info if credentials can be authenticated
-        """
-        if not isinstance(credentials, dict):
-            return None
-        if not ('login' in credentials and 'password' in credentials):
-            return None
-        id = self.__id_by_login.get(credentials['login'])
-        if id is None:
-            return None
-        internal = self[id]
-        if not internal.checkPassword(credentials["password"]):
-            return None
-        return PrincipalInfo(self.prefix + id, internal.login, internal.title,
-                             internal.description)
-
-    def principalInfo(self, id):
-        if id.startswith(self.prefix):
-            internal = self.get(id[len(self.prefix):])
-            if internal is not None:
-                return PrincipalInfo(id, internal.login, internal.title,
-                                     internal.description)
-
-    def getIdByLogin(self, login):
-        return self.prefix + self.__id_by_login[login]
-
-    def search(self, query, start=None, batch_size=None):
-        """Search through this principal provider."""
-        search = query.get('search')
-        if search is None:
-            return
-        search = search.lower()
-        n = 1
-        for i, value in enumerate(self.values()):
-            if (search in value.title.lower() or
-                search in value.description.lower() or
-                search in value.login.lower()):
-                if not ((start is not None and i < start)
-                        or (batch_size is not None and n > batch_size)):
-                    n += 1
-                    yield self.prefix + value.__name__
+    AuthenticatedPrincipalFactory,
+    FoundPrincipalFactory,
+    Principal,
+    PrincipalInfo,
+    )
+# BBB using zope.pluggableauth.plugins.principalfolder
+from zope.pluggableauth.plugins.principalfolder import (
+    IInternalPrincipal,
+    IInternalPrincipalContained,
+    IInternalPrincipalContainer,
+    InternalPrincipal,
+    ISearchSchema,
+    PrincipalFolder,
+    )

Modified: zope.app.authentication/trunk/src/zope/app/authentication/principalfolder.zcml
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/principalfolder.zcml	2010-10-18 09:32:52 UTC (rev 117632)
+++ zope.app.authentication/trunk/src/zope/app/authentication/principalfolder.zcml	2010-10-18 09:40:31 UTC (rev 117633)
@@ -1,39 +1,29 @@
 <configure xmlns="http://namespaces.zope.org/zope" i18n_domain="zope">
 
-  <include package="zope.pluggableauth" file="principalfactories.zcml" />
+  <include package="zope.pluggableauth.plugins" file="principalfolder.zcml" />
 
   <class class=".principalfolder.InternalPrincipal">
     <require
-        permission="zope.ManageServices"
-        interface=".principalfolder.IInternalPrincipal"
-        set_schema=".principalfolder.IInternalPrincipal"
-        />
+      permission="zope.ManageServices"
+      interface=".principalfolder.IInternalPrincipal"
+      set_schema=".principalfolder.IInternalPrincipal"
+    />
   </class>
 
   <class class=".principalfolder.PrincipalFolder">
-
     <implements
-        interface="zope.annotation.interfaces.IAttributeAnnotatable"
-        />
-
+      interface="zope.annotation.interfaces.IAttributeAnnotatable"
+    />
     <require
-        permission="zope.ManageServices"
-        interface="zope.container.interfaces.IContainer"
-        />
-
+      permission="zope.ManageServices"
+      interface="zope.container.interfaces.IContainer"
+    />
     <require
-        permission="zope.ManageServices"
-        attributes="prefix"
-        />
-
+      permission="zope.ManageServices"
+      attributes="prefix"
+    />
   </class>
 
-  <adapter
-      provides="zope.container.interfaces.INameChooser"
-      for=".principalfolder.IInternalPrincipalContainer"
-      factory=".idpicker.IdPicker"
-      />
-
   <include package=".browser" file="principalfolder.zcml" />
 
   <!-- Registering documentation with API doc -->



More information about the checkins mailing list