[Checkins] SVN: zope.pluggableauth/trunk/src/zope/pluggableauth/ The modified module does no longer need the separate doctests.

Souheil CHELFOUH souheil at chelfouh.com
Sun Jan 24 13:42:15 EST 2010


Log message for revision 108444:
  The modified module does no longer need the separate doctests.
  Only the needed factories have been preserved.
  The PrincipalFolder and InternalPrincipal-related component have been terminated.
  

Changed:
  U   zope.pluggableauth/trunk/src/zope/pluggableauth/factories.py
  D   zope.pluggableauth/trunk/src/zope/pluggableauth/factories.txt
  U   zope.pluggableauth/trunk/src/zope/pluggableauth/interfaces.py

-=-
Modified: zope.pluggableauth/trunk/src/zope/pluggableauth/factories.py
===================================================================
--- zope.pluggableauth/trunk/src/zope/pluggableauth/factories.py	2010-01-24 18:36:39 UTC (rev 108443)
+++ zope.pluggableauth/trunk/src/zope/pluggableauth/factories.py	2010-01-24 18:42:15 UTC (rev 108444)
@@ -11,173 +11,20 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-"""ZODB-based Authentication Source
+"""Principals related factories
 
 $Id$
 """
 __docformat__ = "reStructuredText"
 
-from persistent import Persistent
-from zope import interface
 from zope import component
+from zope import interface
+from zope.authentication.interfaces import IAuthentication
 from zope.event import notify
-from zope.schema import Text, TextLine, Password, Choice
+from zope.pluggableauth import interfaces
 from zope.publisher.interfaces import IRequest
 
-from zope.authentication.interfaces import IAuthentication
-from zope.container.interfaces import DuplicateIDError
-from zope.container.contained import Contained
-from zope.container.constraints import contains, containers
-from zope.container.btree import BTreeContainer
-from zope.password.interfaces import IPasswordManager
-from zope.app.authentication.i18n import ZopeMessageFactory as _
 
-from zope.app.authentication import interfaces
-
-
-class IInternalPrincipal(interface.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.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.Interface):
-    """Principal information"""
-
-    containers(IInternalPrincipalContainer)
-
-
-class ISearchSchema(interface.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."""
-
-    interface.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 component.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 getPassword(self):
-        return self._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 PrincipalInfo(object):
     """An implementation of IPrincipalInfo used by the principal folder.
 
@@ -208,116 +55,6 @@
         return 'PrincipalInfo(%r)' % self.id
 
 
-class PrincipalFolder(BTreeContainer):
-    """A Persistent Principal Folder and Authentication plugin.
-
-    See principalfolder.txt for details.
-    """
-
-    interface.implements(interfaces.IAuthenticatorPlugin,
-                         interfaces.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__
-
 class Principal(object):
     """A group-aware implementation of zope.security.interfaces.IPrincipal.
 
@@ -440,6 +177,7 @@
                         group = principals.getPrincipal(group_id)
                         stack.append(iter(group.groups))
 
+
 class AuthenticatedPrincipalFactory(object):
     """Creates 'authenticated' principals.
 

Deleted: zope.pluggableauth/trunk/src/zope/pluggableauth/factories.txt
===================================================================
--- zope.pluggableauth/trunk/src/zope/pluggableauth/factories.txt	2010-01-24 18:36:39 UTC (rev 108443)
+++ zope.pluggableauth/trunk/src/zope/pluggableauth/factories.txt	2010-01-24 18:42:15 UTC (rev 108444)
@@ -1,170 +0,0 @@
-================
-Principal Folder
-================
-
-Principal folders contain principal-information objects that contain principal
-information. We create an internal principal using the `InternalPrincipal`
-class:
-
-  >>> from zope.app.authentication.principalfolder import InternalPrincipal
-  >>> p1 = InternalPrincipal('login1', '123', "Principal 1",
-  ...     passwordManagerName="SHA1")
-  >>> p2 = InternalPrincipal('login2', '456', "The Other One")
-
-and add them to a principal folder:
-
-  >>> from zope.app.authentication.principalfolder import PrincipalFolder
-  >>> principals = PrincipalFolder('principal.')
-  >>> principals['p1'] = p1
-  >>> principals['p2'] = p2
-
-Authentication
---------------
-
-Principal folders provide the `IAuthenticatorPlugin` interface. When we
-provide suitable credentials:
-
-  >>> from zope.testing.doctestunit import pprint
-  >>> principals.authenticateCredentials({'login': 'login1', 'password': '123'})
-  PrincipalInfo(u'principal.p1')
-
-We get back a principal id and supplementary information, including the
-principal title and description.  Note that the principal id is a concatenation
-of the principal-folder prefix and the name of the principal-information object
-within the folder.
-
-None is returned if the credentials are invalid:
-
-  >>> principals.authenticateCredentials({'login': 'login1',
-  ...                                     'password': '1234'})
-  >>> principals.authenticateCredentials(42)
-
-Search
-------
-
-Principal folders also provide the IQuerySchemaSearch interface.  This
-supports both finding principal information based on their ids:
-
-  >>> principals.principalInfo('principal.p1')
-  PrincipalInfo('principal.p1')
-
-  >>> principals.principalInfo('p1')
-
-and searching for principals based on a search string:
-
-  >>> list(principals.search({'search': 'other'}))
-  [u'principal.p2']
-
-  >>> list(principals.search({'search': 'OTHER'}))
-  [u'principal.p2']
-
-  >>> list(principals.search({'search': ''}))
-  [u'principal.p1', u'principal.p2']
-
-  >>> list(principals.search({'search': 'eek'}))
-  []
-
-  >>> list(principals.search({}))
-  []
-
-If there are a large number of matches:
-
-  >>> for i in range(20):
-  ...     i = str(i)
-  ...     p = InternalPrincipal('l'+i, i, "Dude "+i)
-  ...     principals[i] = p
-
-  >>> pprint(list(principals.search({'search': 'D'})))
-  [u'principal.0',
-   u'principal.1',
-   u'principal.10',
-   u'principal.11',
-   u'principal.12',
-   u'principal.13',
-   u'principal.14',
-   u'principal.15',
-   u'principal.16',
-   u'principal.17',
-   u'principal.18',
-   u'principal.19',
-   u'principal.2',
-   u'principal.3',
-   u'principal.4',
-   u'principal.5',
-   u'principal.6',
-   u'principal.7',
-   u'principal.8',
-   u'principal.9']
-
-We can use batching parameters to specify a subset of results:
-
-  >>> pprint(list(principals.search({'search': 'D'}, start=17)))
-  [u'principal.7',
-   u'principal.8',
-   u'principal.9']
-
-  >>> pprint(list(principals.search({'search': 'D'}, batch_size=5)))
-  [u'principal.0',
-   u'principal.1',
-   u'principal.10',
-   u'principal.11',
-   u'principal.12']
-
-  >>> pprint(list(principals.search({'search': 'D'}, start=5, batch_size=5)))
-  [u'principal.13',
-   u'principal.14',
-   u'principal.15',
-   u'principal.16',
-   u'principal.17']
-
-There is an additional method that allows requesting the principal id
-associated with a login id.  The method raises KeyError when there is
-no associated principal::
-
-  >>> principals.getIdByLogin("not-there")
-  Traceback (most recent call last):
-  KeyError: 'not-there'
-
-If there is a matching principal, the id is returned::
-
-  >>> principals.getIdByLogin("login1")
-  u'principal.p1'
-
-Changing credentials
---------------------
-
-Credentials can be changed by modifying principal-information objects:
-
-  >>> p1.login = 'bob'
-  >>> p1.password = 'eek'
-
-  >>> principals.authenticateCredentials({'login': 'bob', 'password': 'eek'})
-  PrincipalInfo(u'principal.p1')
-
-  >>> principals.authenticateCredentials({'login': 'login1',
-  ...                                     'password': 'eek'})
-
-  >>> principals.authenticateCredentials({'login': 'bob',
-  ...                                     'password': '123'})
-
-
-It is an error to try to pick a login name that is already taken:
-
-  >>> p1.login = 'login2'
-  Traceback (most recent call last):
-  ...
-  ValueError: Principal Login already taken!
-
-If such an attempt is made, the data are unchanged:
-
-  >>> principals.authenticateCredentials({'login': 'bob', 'password': 'eek'})
-  PrincipalInfo(u'principal.p1')
-
-Removing principals
--------------------
-
-Of course, if a principal is removed, we can no-longer authenticate it:
-
-  >>> del principals['p1']
-  >>> principals.authenticateCredentials({'login': 'bob',
-  ...                                     'password': 'eek'})

Modified: zope.pluggableauth/trunk/src/zope/pluggableauth/interfaces.py
===================================================================
--- zope.pluggableauth/trunk/src/zope/pluggableauth/interfaces.py	2010-01-24 18:36:39 UTC (rev 108443)
+++ zope.pluggableauth/trunk/src/zope/pluggableauth/interfaces.py	2010-01-24 18:42:15 UTC (rev 108444)
@@ -20,7 +20,6 @@
 import zope.interface
 from zope.i18nmessageid import MessageFactory
 from zope.authentication.interfaces import ILogout
-from zope.schema import Choice, List, TextLine
 from zope.container.constraints import contains, containers
 from zope.container.interfaces import IContainer
 



More information about the checkins mailing list