[Checkins] SVN: zope.app.authentication/trunk/ Use the new zope.password package.

Dan Korostelev nadako at gmail.com
Fri Mar 6 07:40:59 EST 2009


Log message for revision 97567:
  Use the new zope.password package.

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/interfaces.py
  U   zope.app.authentication/trunk/src/zope/app/authentication/password.py
  U   zope.app.authentication/trunk/src/zope/app/authentication/password.zcml
  U   zope.app.authentication/trunk/src/zope/app/authentication/placelesssetup.py
  U   zope.app.authentication/trunk/src/zope/app/authentication/principalfolder.py

-=-
Modified: zope.app.authentication/trunk/CHANGES.txt
===================================================================
--- zope.app.authentication/trunk/CHANGES.txt	2009-03-06 12:23:42 UTC (rev 97566)
+++ zope.app.authentication/trunk/CHANGES.txt	2009-03-06 12:40:59 UTC (rev 97567)
@@ -5,7 +5,8 @@
 3.5.0a3 (unreleased)
 --------------------
 
-- ...
+* Split password manager functionality off to the new ``zope.password``
+  package. Backward-compatibility imports are left in place.
 
 3.5.0a2 (2009-02-01)
 --------------------

Modified: zope.app.authentication/trunk/buildout.cfg
===================================================================
--- zope.app.authentication/trunk/buildout.cfg	2009-03-06 12:23:42 UTC (rev 97566)
+++ zope.app.authentication/trunk/buildout.cfg	2009-03-06 12:40:59 UTC (rev 97567)
@@ -1,5 +1,5 @@
 [buildout]
-develop = .
+develop = . ../zope.password
 parts = test
 
 [test]

Modified: zope.app.authentication/trunk/setup.py
===================================================================
--- zope.app.authentication/trunk/setup.py	2009-03-06 12:23:42 UTC (rev 97566)
+++ zope.app.authentication/trunk/setup.py	2009-03-06 12:40:59 UTC (rev 97567)
@@ -73,6 +73,7 @@
                         'zope.i18nmessageid',
                         'zope.interface',
                         'zope.location',
+                        'zope.password',
                         'zope.publisher',
                         'zope.schema',
                         'zope.security',

Modified: zope.app.authentication/trunk/src/zope/app/authentication/interfaces.py
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/interfaces.py	2009-03-06 12:23:42 UTC (rev 97566)
+++ zope.app.authentication/trunk/src/zope/app/authentication/interfaces.py	2009-03-06 12:40:59 UTC (rev 97567)
@@ -25,6 +25,8 @@
 from zope.container.constraints import contains, containers
 from zope.container.interfaces import IContainer
 
+# BBB: the password managers were moved into zope.password package.
+from zope.password.interfaces import IPasswordManager
 
 class IPlugin(zope.interface.Interface):
     """A plugin for a pluggable authentication component."""
@@ -146,15 +148,7 @@
         If the plugin cannot find information for the id, returns None.
         """
 
-class IPasswordManager(zope.interface.Interface):
-    """Password manager."""
 
-    def encodePassword(password):
-        """Return encoded data for the password."""
-
-    def checkPassword(storedPassword, password):
-        """Return whether the password coincide with the storedPassword."""
-
 class IPrincipalInfo(zope.interface.Interface):
     """Minimal information about a principal."""
 

Modified: zope.app.authentication/trunk/src/zope/app/authentication/password.py
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/password.py	2009-03-06 12:23:42 UTC (rev 97566)
+++ zope.app.authentication/trunk/src/zope/app/authentication/password.py	2009-03-06 12:40:59 UTC (rev 97567)
@@ -17,217 +17,17 @@
 """
 __docformat__ = 'restructuredtext'
 
-try:
-    from hashlib import md5, sha1
-except ImportError:
-    # Python 2.4
-    from md5 import new as md5
-    from sha import new as sha1
-
-from base64 import urlsafe_b64encode
-from base64 import urlsafe_b64decode
-from os import urandom
-from random import randint
-from codecs import getencoder
-
-from zope.interface import implements, classProvides
-from zope.schema.interfaces import IVocabularyFactory
 from zope.app.component.vocabulary import UtilityVocabulary
 
-from zope.app.authentication.interfaces import IPasswordManager
+# BBB: the password managers were moved into zope.password package.
+from zope.password.password import (
+    PlainTextPasswordManager,
+    MD5PasswordManager,
+    SHA1PasswordManager,
+    SSHAPasswordManager
+    )
+from zope.password.interfaces import IPasswordManager
 
-
-_encoder = getencoder("utf-8")
-
-
-class PlainTextPasswordManager(object):
-    """Plain text password manager.
-
-    >>> from zope.interface.verify import verifyObject
-
-    >>> manager = PlainTextPasswordManager()
-    >>> verifyObject(IPasswordManager, manager)
-    True
-
-    >>> password = u"right \N{CYRILLIC CAPITAL LETTER A}"
-    >>> encoded = manager.encodePassword(password)
-    >>> encoded
-    u'right \u0410'
-    >>> manager.checkPassword(encoded, password)
-    True
-    >>> manager.checkPassword(encoded, password + u"wrong")
-    False
-    """
-
-    implements(IPasswordManager)
-
-    def encodePassword(self, password):
-        return password
-
-    def checkPassword(self, storedPassword, password):
-        return storedPassword == self.encodePassword(password)
-
-
-class MD5PasswordManager(PlainTextPasswordManager):
-    """MD5 password manager.
-
-    Note: use of salt in this password manager is purely
-    cosmetical. Use SSHA if you want increased security.
-    
-    >>> from zope.interface.verify import verifyObject
-
-    >>> manager = MD5PasswordManager()
-    >>> verifyObject(IPasswordManager, manager)
-    True
-
-    >>> password = u"right \N{CYRILLIC CAPITAL LETTER A}"
-    >>> encoded = manager.encodePassword(password, salt="")
-    >>> encoded
-    '{MD5}86dddccec45db4599f1ac00018e54139'
-    >>> manager.checkPassword(encoded, password)
-    True
-    >>> manager.checkPassword(encoded, password + u"wrong")
-    False
-
-    >>> encoded = manager.encodePassword(password)
-    >>> encoded[-32:]
-    '86dddccec45db4599f1ac00018e54139'
-    >>> manager.checkPassword(encoded, password)
-    True
-    >>> manager.checkPassword(encoded, password + u"wrong")
-    False
-
-    >>> manager.encodePassword(password) != manager.encodePassword(password)
-    True
-    """
-
-    implements(IPasswordManager)
-
-    def encodePassword(self, password, salt=None):
-        if salt is None:
-            salt = "%08x" % randint(0, 0xffffffff)
-        return '{MD5}%s%s' % (salt, md5(_encoder(password)[0]).hexdigest())
-
-    def checkPassword(self, storedPassword, password):
-        if storedPassword.startswith('{MD5}'):
-            salt = storedPassword[5:-32]
-            return storedPassword == self.encodePassword(password, salt)
-        salt = storedPassword[:-32]
-        return storedPassword == self.encodePassword(password, salt)[5:]
-
-
-class SHA1PasswordManager(PlainTextPasswordManager):
-    """SHA1 password manager.
-
-    Note: use of salt in this password manager is purely
-    cosmetical. Use SSHA if you want increased security.
-    
-    >>> from zope.interface.verify import verifyObject
-
-    >>> manager = SHA1PasswordManager()
-    >>> verifyObject(IPasswordManager, manager)
-    True
-
-    >>> password = u"right \N{CYRILLIC CAPITAL LETTER A}"
-    >>> encoded = manager.encodePassword(password, salt="")
-    >>> encoded
-    '{SHA1}04b4eec7154c5f3a2ec6d2956fb80b80dc737402'
-    >>> manager.checkPassword(encoded, password)
-    True
-    >>> manager.checkPassword(encoded, password + u"wrong")
-    False
-
-    >>> encoded = manager.encodePassword(password)
-    >>> encoded[-40:]
-    '04b4eec7154c5f3a2ec6d2956fb80b80dc737402'
-    >>> manager.checkPassword(encoded, password)
-    True
-    >>> manager.checkPassword(encoded, password + u"wrong")
-    False
-
-    >>> manager.encodePassword(password) != manager.encodePassword(password)
-    True
-    """
-
-    implements(IPasswordManager)
-
-    def encodePassword(self, password, salt=None):
-        if salt is None:
-            salt = "%08x" % randint(0, 0xffffffff)
-        return '{SHA1}%s%s' % (salt, sha1(_encoder(password)[0]).hexdigest())
-
-    def checkPassword(self, storedPassword, password):
-        if storedPassword.startswith('{SHA1}'):
-            salt = storedPassword[6:-40]
-            return storedPassword == self.encodePassword(password, salt)
-        salt = storedPassword[:-40]
-        return storedPassword == self.encodePassword(password, salt)[6:]
-
-class SSHAPasswordManager(PlainTextPasswordManager):
-    """SSHA password manager.
-
-    SSHA is basically SHA1-encoding which also incorporates a salt
-    into the encoded string. This way, stored passwords are more
-    robust against dictionary attacks of attackers that could get
-    access to lists of encoded passwords.
-
-    SSHA is regularly used in LDAP databases and we should be
-    compatible with passwords used there.
-    
-    >>> from zope.interface.verify import verifyObject
-
-    >>> manager = SSHAPasswordManager()
-    >>> verifyObject(IPasswordManager, manager)
-    True
-
-    >>> password = u"right \N{CYRILLIC CAPITAL LETTER A}"
-    >>> encoded = manager.encodePassword(password, salt="")
-    >>> encoded
-    '{SSHA}BLTuxxVMXzouxtKVb7gLgNxzdAI='
-
-    >>> manager.checkPassword(encoded, password)
-    True
-    >>> manager.checkPassword(encoded, password + u"wrong")
-    False
-
-    Using the `slappasswd` utility to encode ``secret``, we get
-    ``{SSHA}J4mrr3NQHXzLVaT0h9TuEWoJOrxeQ5lv`` as seeded hash.
-
-    Our password manager generates the same value when seeded with the
-    same salt, so we can be sure, our output is compatible with
-    standard LDAP tools that also use SSHA::
-    
-    >>> from base64 import urlsafe_b64decode
-    >>> salt = urlsafe_b64decode('XkOZbw==')
-    >>> encoded = manager.encodePassword('secret', salt)
-    >>> encoded
-    '{SSHA}J4mrr3NQHXzLVaT0h9TuEWoJOrxeQ5lv'
-    
-    >>> encoded = manager.encodePassword(password)
-    >>> manager.checkPassword(encoded, password)
-    True
-    >>> manager.checkPassword(encoded, password + u"wrong")
-    False
-
-    >>> manager.encodePassword(password) != manager.encodePassword(password)
-    True
-    """
-
-    implements(IPasswordManager)
-
-    def encodePassword(self, password, salt=None):
-        if salt is None:
-            salt = urandom(4)
-        hash = sha1(_encoder(password)[0])
-        hash.update(salt)
-        return '{SSHA}' + urlsafe_b64encode(
-            hash.digest() + salt)
-
-    def checkPassword(self, storedPassword, password):
-        byte_string = urlsafe_b64decode(storedPassword[6:])
-        salt = byte_string[20:]
-        return storedPassword == self.encodePassword(password, salt)
-
 # Simple registry used by mkzopeinstance script
 managers = [
     ("Plain Text", PlainTextPasswordManager()), # default
@@ -240,6 +40,5 @@
 class PasswordManagerNamesVocabulary(UtilityVocabulary):
     """Vocabulary of password managers."""
 
-    classProvides(IVocabularyFactory)
     interface = IPasswordManager
     nameOnly = True

Modified: zope.app.authentication/trunk/src/zope/app/authentication/password.zcml
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/password.zcml	2009-03-06 12:23:42 UTC (rev 97566)
+++ zope.app.authentication/trunk/src/zope/app/authentication/password.zcml	2009-03-06 12:40:59 UTC (rev 97567)
@@ -1,47 +1,11 @@
-<configure
-    xmlns="http://namespaces.zope.org/zope"
-    i18n_domain="zope"
-    >
+<configure xmlns="http://namespaces.zope.org/zope">
 
+  <include package="zope.password" />
+
   <utility
       component=".password.PasswordManagerNamesVocabulary"
+      provides="zope.schema.interfaces.IVocabularyFactory"
       name="Password Manager Names"
       />
 
-  <class class=".password.PlainTextPasswordManager">
-    <allow interface=".interfaces.IPasswordManager" />
-  </class>
-
-  <utility
-      name="Plain Text"
-      provides=".interfaces.IPasswordManager"
-      factory=".password.PlainTextPasswordManager"
-      />
-
-  <class class=".password.MD5PasswordManager">
-    <allow interface=".interfaces.IPasswordManager" />
-  </class>
-
-  <utility
-      name="MD5"
-      provides=".interfaces.IPasswordManager"
-      factory=".password.MD5PasswordManager"
-      />
-
-  <class class=".password.SHA1PasswordManager">
-    <allow interface=".interfaces.IPasswordManager" />
-  </class>
-
-  <utility
-      name="SHA1"
-      provides=".interfaces.IPasswordManager"
-      factory=".password.SHA1PasswordManager"
-      />
-
-  <utility
-      name="SSHA"
-      provides=".interfaces.IPasswordManager"
-      factory=".password.SSHAPasswordManager"
-      />
-
 </configure>

Modified: zope.app.authentication/trunk/src/zope/app/authentication/placelesssetup.py
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/placelesssetup.py	2009-03-06 12:23:42 UTC (rev 97566)
+++ zope.app.authentication/trunk/src/zope/app/authentication/placelesssetup.py	2009-03-06 12:40:59 UTC (rev 97567)
@@ -17,19 +17,10 @@
 """
 __docformat__ = "reStructuredText"
 
-from zope.app.testing import ztapi
-from zope.app.authentication.interfaces import IPasswordManager
-from zope.app.authentication.password import PlainTextPasswordManager
-from zope.app.authentication.password import MD5PasswordManager
-from zope.app.authentication.password import SHA1PasswordManager
-from zope.app.authentication.password import SSHAPasswordManager
+# BBB: the password managers were moved to zope.password package
+from zope.password.testing import setUpPasswordManagers
 
-
 class PlacelessSetup(object):
 
     def setUp(self):
-        ztapi.provideUtility(IPasswordManager, PlainTextPasswordManager(),
-            "Plain Text")
-        ztapi.provideUtility(IPasswordManager, MD5PasswordManager(), "MD5")
-        ztapi.provideUtility(IPasswordManager, SHA1PasswordManager(), "SHA1")
-        ztapi.provideUtility(IPasswordManager, SSHAPasswordManager(), "SSHA")
+        setUpPasswordManagers()

Modified: zope.app.authentication/trunk/src/zope/app/authentication/principalfolder.py
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/principalfolder.py	2009-03-06 12:23:42 UTC (rev 97566)
+++ zope.app.authentication/trunk/src/zope/app/authentication/principalfolder.py	2009-03-06 12:40:59 UTC (rev 97567)
@@ -28,6 +28,7 @@
 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.security.interfaces import IAuthentication
 
@@ -141,7 +142,7 @@
 
     def _getPasswordManager(self):
         return component.getUtility(
-            interfaces.IPasswordManager, self.passwordManagerName)
+            IPasswordManager, self.passwordManagerName)
 
     def getPassword(self):
         return self._password



More information about the Checkins mailing list