[Zope3-checkins] SVN: Zope3/trunk/ Merged the hdima-password-managers branch.

Dmitry Vasiliev dima at hlabs.spb.ru
Fri Oct 28 06:14:24 EDT 2005


Log message for revision 39687:
  Merged the hdima-password-managers branch.
    
  For details see doc/CHANGES.txt and
  http://www.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/PasswordManagers
  

Changed:
  A   Zope3/trunk/bin/zpasswd
  U   Zope3/trunk/doc/CHANGES.txt
  U   Zope3/trunk/src/bugtracker/tests/test_vocabularies.py
  U   Zope3/trunk/src/zope/app/authentication/browser/ftests.py
  U   Zope3/trunk/src/zope/app/authentication/browser/groupfolder.txt
  U   Zope3/trunk/src/zope/app/authentication/browser/pau_prefix_and_searching.txt
  U   Zope3/trunk/src/zope/app/authentication/browser/principalfolder.txt
  U   Zope3/trunk/src/zope/app/authentication/browser/principalfolder.zcml
  U   Zope3/trunk/src/zope/app/authentication/browser/special-groups.txt
  U   Zope3/trunk/src/zope/app/authentication/configure.zcml
  U   Zope3/trunk/src/zope/app/authentication/interfaces.py
  A   Zope3/trunk/src/zope/app/authentication/password.py
  A   Zope3/trunk/src/zope/app/authentication/password.zcml
  A   Zope3/trunk/src/zope/app/authentication/placelesssetup.py
  U   Zope3/trunk/src/zope/app/authentication/principalfolder.py
  U   Zope3/trunk/src/zope/app/authentication/principalfolder.txt
  U   Zope3/trunk/src/zope/app/authentication/tests.py
  U   Zope3/trunk/src/zope/app/security/globalprincipals.txt
  U   Zope3/trunk/src/zope/app/security/metaconfigure.py
  U   Zope3/trunk/src/zope/app/security/metadirectives.py
  U   Zope3/trunk/src/zope/app/security/principalregistry.py
  _U  Zope3/trunk/src/zope/app/security/tests/module.py
  _U  Zope3/trunk/src/zope/app/security/tests/modulehookup.py
  U   Zope3/trunk/src/zope/app/security/tests/principal.zcml
  U   Zope3/trunk/src/zope/app/security/tests/test_adapter.py
  _U  Zope3/trunk/src/zope/app/security/tests/test_basicauthadapter.py
  _U  Zope3/trunk/src/zope/app/security/tests/test_loginpassword.py
  U   Zope3/trunk/src/zope/app/security/tests/test_logout.py
  _U  Zope3/trunk/src/zope/app/security/tests/test_vocabulary.py
  UU  Zope3/trunk/src/zope/app/server/mkzopeinstance.py
  A   Zope3/trunk/src/zope/app/server/tests/site.zcml
  _U  Zope3/trunk/src/zope/app/server/tests/test_accesslog.py
  UU  Zope3/trunk/src/zope/app/server/tests/test_mkzopeinstance.py
  A   Zope3/trunk/src/zope/app/server/tests/test_zpasswd.py
  A   Zope3/trunk/src/zope/app/server/zpasswd.py
  U   Zope3/trunk/src/zope/app/testing/placelesssetup.py
  UU  Zope3/trunk/src/zope/app/zopeappgenerations/__init__.py
  UU  Zope3/trunk/src/zope/app/zopeappgenerations/evolve1.py
  A   Zope3/trunk/src/zope/app/zopeappgenerations/evolve2.py
  A   Zope3/trunk/zopeskel/bin/zpasswd.in
  U   Zope3/trunk/zopeskel/etc/principals.zcml.in

-=-
Copied: Zope3/trunk/bin/zpasswd (from rev 39669, Zope3/branches/hdima-password-managers/bin/zpasswd)

Modified: Zope3/trunk/doc/CHANGES.txt
===================================================================
--- Zope3/trunk/doc/CHANGES.txt	2005-10-28 08:14:45 UTC (rev 39686)
+++ Zope3/trunk/doc/CHANGES.txt	2005-10-28 10:14:24 UTC (rev 39687)
@@ -10,6 +10,23 @@
 
     New features
 
+      - Implemented the password managers proposal. Main idea beside the
+        proposal is a standard way to implement password encoders/checkers, see
+        zope.app.authentication.interfaces.IPasswordManager for details.
+
+        + Added basic password managers: Plain Text, MD5, SHA1.
+
+        + Support for password managers added for ZCML principals and
+          principals saved in local PrincipalFolers.
+
+        + Added bin/zpasswd command line script which helps to create ZCML
+          principals.
+
+        + Password managers support integrated into bin/mkzopeinstance.
+
+        + New database generation created for convert local principals to new
+          format.
+
       - Implemented the language namespace proposal. Now you can override
         the browser preferred language through the URL, like this:
 

Modified: Zope3/trunk/src/bugtracker/tests/test_vocabularies.py
===================================================================
--- Zope3/trunk/src/bugtracker/tests/test_vocabularies.py	2005-10-28 08:14:45 UTC (rev 39686)
+++ Zope3/trunk/src/bugtracker/tests/test_vocabularies.py	2005-10-28 10:14:24 UTC (rev 39687)
@@ -169,9 +169,10 @@
         self.assertEqual(self.term.title, 'bar')
 
 
-class UserTermTest(unittest.TestCase):
+class UserTermTest(PlacelessSetup, unittest.TestCase):
 
     def setUp(self):
+        PlacelessSetup.setUp(self)
         principal = Principal('0', 'Stephan', 'blah', 'srichter', 'Nothing')
         self.term = UserTerm(principal)
 

Modified: Zope3/trunk/src/zope/app/authentication/browser/ftests.py
===================================================================
--- Zope3/trunk/src/zope/app/authentication/browser/ftests.py	2005-10-28 08:14:45 UTC (rev 39686)
+++ Zope3/trunk/src/zope/app/authentication/browser/ftests.py	2005-10-28 10:14:24 UTC (rev 39687)
@@ -31,6 +31,7 @@
 
 from zope.app.exception.interfaces import UserError
 
+
 class FunkTest(functional.BrowserTestCase):
 
     def test_copypaste_duplicated_id_object(self):
@@ -111,6 +112,7 @@
             # test failed !
             self.asserEqual(1, 0)
 
+
 def test_suite():
     return unittest.TestSuite((
         functional.FunctionalDocFileSuite('principalfolder.txt'),

Modified: Zope3/trunk/src/zope/app/authentication/browser/groupfolder.txt
===================================================================
--- Zope3/trunk/src/zope/app/authentication/browser/groupfolder.txt	2005-10-28 08:14:45 UTC (rev 39686)
+++ Zope3/trunk/src/zope/app/authentication/browser/groupfolder.txt	2005-10-28 10:14:24 UTC (rev 39687)
@@ -153,6 +153,10 @@
   ...
   ... bob
   ... -----------------------------5110544421083023415453147877
+  ... Content-Disposition: form-data; name="field.passwordManagerName"
+  ...
+  ... Plain Text
+  ... -----------------------------5110544421083023415453147877
   ... Content-Disposition: form-data; name="field.password"
   ...
   ... 123
@@ -192,6 +196,10 @@
   ...
   ... bill
   ... -----------------------------5110544421083023415453147877
+  ... Content-Disposition: form-data; name="field.passwordManagerName"
+  ...
+  ... Plain Text
+  ... -----------------------------5110544421083023415453147877
   ... Content-Disposition: form-data; name="field.password"
   ...
   ... 123
@@ -231,6 +239,10 @@
   ...
   ... betty
   ... -----------------------------5110544421083023415453147877
+  ... Content-Disposition: form-data; name="field.passwordManagerName"
+  ...
+  ... Plain Text
+  ... -----------------------------5110544421083023415453147877
   ... Content-Disposition: form-data; name="field.password"
   ...
   ... 123
@@ -270,6 +282,10 @@
   ...
   ... sally
   ... -----------------------------5110544421083023415453147877
+  ... Content-Disposition: form-data; name="field.passwordManagerName"
+  ...
+  ... Plain Text
+  ... -----------------------------5110544421083023415453147877
   ... Content-Disposition: form-data; name="field.password"
   ...
   ... 123
@@ -308,6 +324,10 @@
   ...
   ... george
   ... -----------------------------5110544421083023415453147877
+  ... Content-Disposition: form-data; name="field.passwordManagerName"
+  ...
+  ... Plain Text
+  ... -----------------------------5110544421083023415453147877
   ... Content-Disposition: form-data; name="field.password"
   ...
   ... 123
@@ -346,6 +366,10 @@
   ...
   ... mike
   ... -----------------------------5110544421083023415453147877
+  ... Content-Disposition: form-data; name="field.passwordManagerName"
+  ...
+  ... Plain Text
+  ... -----------------------------5110544421083023415453147877
   ... Content-Disposition: form-data; name="field.password"
   ...
   ... 123
@@ -384,6 +408,10 @@
   ...
   ... mary
   ... -----------------------------5110544421083023415453147877
+  ... Content-Disposition: form-data; name="field.passwordManagerName"
+  ...
+  ... Plain Text
+  ... -----------------------------5110544421083023415453147877
   ... Content-Disposition: form-data; name="field.password"
   ...
   ... 123

Modified: Zope3/trunk/src/zope/app/authentication/browser/pau_prefix_and_searching.txt
===================================================================
--- Zope3/trunk/src/zope/app/authentication/browser/pau_prefix_and_searching.txt	2005-10-28 08:14:45 UTC (rev 39686)
+++ Zope3/trunk/src/zope/app/authentication/browser/pau_prefix_and_searching.txt	2005-10-28 10:14:24 UTC (rev 39687)
@@ -134,6 +134,10 @@
   ...
   ... bob
   ... -----------------------------300171485226567
+  ... Content-Disposition: form-data; name="field.passwordManagerName"
+  ...
+  ... Plain Text
+  ... -----------------------------300171485226567
   ... Content-Disposition: form-data; name="field.password"
   ...
   ... bob

Modified: Zope3/trunk/src/zope/app/authentication/browser/principalfolder.txt
===================================================================
--- Zope3/trunk/src/zope/app/authentication/browser/principalfolder.txt	2005-10-28 08:14:45 UTC (rev 39686)
+++ Zope3/trunk/src/zope/app/authentication/browser/principalfolder.txt	2005-10-28 10:14:24 UTC (rev 39687)
@@ -176,6 +176,10 @@
   ... 
   ... bob
   ... -----------------------------5110544421083023415453147877
+  ... Content-Disposition: form-data; name="field.passwordManagerName"
+  ... 
+  ... SHA1
+  ... -----------------------------5110544421083023415453147877
   ... Content-Disposition: form-data; name="field.password"
   ... 
   ... bob

Modified: Zope3/trunk/src/zope/app/authentication/browser/principalfolder.zcml
===================================================================
--- Zope3/trunk/src/zope/app/authentication/browser/principalfolder.zcml	2005-10-28 08:14:45 UTC (rev 39686)
+++ Zope3/trunk/src/zope/app/authentication/browser/principalfolder.zcml	2005-10-28 10:14:24 UTC (rev 39687)
@@ -24,7 +24,8 @@
       label="Add Principal Information"
       content_factory="..principalfolder.InternalPrincipal"
       arguments="login password title"
-      keyword_arguments="description"
+      keyword_arguments="passwordManagerName description"
+      fields="login passwordManagerName password title description"
       name="AddPrincipalInformation.html"
       permission="zope.ManageServices"
       />
@@ -40,7 +41,7 @@
       schema="..principalfolder.IInternalPrincipal"
       label="Change Internal Principal"
       name="edit.html"
-      fields="login password title description"
+      fields="login passwordManagerName password title description"
       permission="zope.ManageServices"
       menu="zmi_views" title="Edit" />
 

Modified: Zope3/trunk/src/zope/app/authentication/browser/special-groups.txt
===================================================================
--- Zope3/trunk/src/zope/app/authentication/browser/special-groups.txt	2005-10-28 08:14:45 UTC (rev 39686)
+++ Zope3/trunk/src/zope/app/authentication/browser/special-groups.txt	2005-10-28 10:14:24 UTC (rev 39687)
@@ -145,6 +145,10 @@
   ... 
   ... bob
   ... -----------------------------5110544421083023415453147877
+  ... Content-Disposition: form-data; name="field.passwordManagerName"
+  ... 
+  ... Plain Text
+  ... -----------------------------5110544421083023415453147877
   ... Content-Disposition: form-data; name="field.password"
   ... 
   ... bob

Modified: Zope3/trunk/src/zope/app/authentication/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/authentication/configure.zcml	2005-10-28 08:14:45 UTC (rev 39686)
+++ Zope3/trunk/src/zope/app/authentication/configure.zcml	2005-10-28 10:14:24 UTC (rev 39687)
@@ -61,6 +61,7 @@
 
   </configure>
 
+  <include file="password.zcml" />
   <include file="session.zcml" />
   <include file="httpplugins.zcml" />
   <include file="principalfolder.zcml" />

Modified: Zope3/trunk/src/zope/app/authentication/interfaces.py
===================================================================
--- Zope3/trunk/src/zope/app/authentication/interfaces.py	2005-10-28 08:14:45 UTC (rev 39686)
+++ Zope3/trunk/src/zope/app/authentication/interfaces.py	2005-10-28 10:14:24 UTC (rev 39687)
@@ -115,6 +115,15 @@
         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."""
 

Copied: Zope3/trunk/src/zope/app/authentication/password.py (from rev 39669, Zope3/branches/hdima-password-managers/src/zope/app/authentication/password.py)

Copied: Zope3/trunk/src/zope/app/authentication/password.zcml (from rev 39669, Zope3/branches/hdima-password-managers/src/zope/app/authentication/password.zcml)

Copied: Zope3/trunk/src/zope/app/authentication/placelesssetup.py (from rev 39669, Zope3/branches/hdima-password-managers/src/zope/app/authentication/placelesssetup.py)

Modified: Zope3/trunk/src/zope/app/authentication/principalfolder.py
===================================================================
--- Zope3/trunk/src/zope/app/authentication/principalfolder.py	2005-10-28 08:14:45 UTC (rev 39686)
+++ Zope3/trunk/src/zope/app/authentication/principalfolder.py	2005-10-28 10:14:24 UTC (rev 39687)
@@ -21,10 +21,11 @@
 from zope import interface
 from zope import component
 from zope.event import notify
-from zope.schema import Text, TextLine, Password
+from zope.schema import Text, TextLine, Password, Choice
 from zope.publisher.interfaces import IRequest
 from zope.security.interfaces import IGroupAwarePrincipal
 
+from zope.app import zapi
 from zope.app.container.interfaces import DuplicateIDError
 from zope.app.container.contained import Contained
 from zope.app.container.constraints import contains, containers
@@ -42,10 +43,24 @@
         description=_("The Login/Username of the principal. "
                       "This value can change."))
 
+    def setPassword(password, passwordManagerName=None):
+        pass
+
     password = Password(
-        title=_(u"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="Plain Text",
+        # 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."))
@@ -95,12 +110,41 @@
 
     interface.implements(IInternalPrincipal, IInternalPrincipalContained)
 
-    def __init__(self, login, password, title, description=u''):
+    def __init__(self, login, password, title, description=u'',
+            passwordManagerName="Plain Text"):
         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 zapi.getUtility(
+            interfaces.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
 
@@ -226,7 +270,7 @@
         if id is None:
             return None
         internal = self[id]
-        if internal.password != credentials['password']:
+        if not internal.checkPassword(credentials["password"]):
             return None
         return PrincipalInfo(self.prefix + id, internal.login, internal.title,
                              internal.description)

Modified: Zope3/trunk/src/zope/app/authentication/principalfolder.txt
===================================================================
--- Zope3/trunk/src/zope/app/authentication/principalfolder.txt	2005-10-28 08:14:45 UTC (rev 39686)
+++ Zope3/trunk/src/zope/app/authentication/principalfolder.txt	2005-10-28 10:14:24 UTC (rev 39687)
@@ -7,7 +7,8 @@
 class:
 
   >>> from zope.app.authentication.principalfolder import InternalPrincipal
-  >>> p1 = InternalPrincipal('login1', '123', "Principal 1")
+  >>> p1 = InternalPrincipal('login1', '123', "Principal 1",
+  ...     passwordManagerName="SHA1")
   >>> p2 = InternalPrincipal('login2', '456', "The Other One")
 
 and add then in map fashion to a principal folder:
@@ -25,7 +26,7 @@
   >>> 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

Modified: Zope3/trunk/src/zope/app/authentication/tests.py
===================================================================
--- Zope3/trunk/src/zope/app/authentication/tests.py	2005-10-28 08:14:45 UTC (rev 39686)
+++ Zope3/trunk/src/zope/app/authentication/tests.py	2005-10-28 10:14:24 UTC (rev 39687)
@@ -40,6 +40,7 @@
 from zope.publisher import base
 from zope.app.authentication.session import SessionCredentialsPlugin
 
+
 class TestClientId(object):
     implements(IClientId)
     def __new__(cls, request):
@@ -93,13 +94,17 @@
 
         self.assertEqual(plugin.logout(base.TestRequest('/')), False)
 
+
 def test_suite():
     return unittest.TestSuite((
         doctest.DocTestSuite('zope.app.authentication.interfaces'),
+        doctest.DocTestSuite('zope.app.authentication.password'),
         doctest.DocTestSuite('zope.app.authentication.generic'),
         doctest.DocTestSuite('zope.app.authentication.httpplugins'),
         doctest.DocTestSuite('zope.app.authentication.ftpplugins'),
-        doctest.DocFileSuite('principalfolder.txt'),
+        doctest.DocFileSuite('principalfolder.txt',
+                             setUp=placelesssetup.setUp,
+                             tearDown=placelesssetup.tearDown),
         doctest.DocTestSuite('zope.app.authentication.principalfolder',
                              setUp=placelesssetup.setUp,
                              tearDown=placelesssetup.tearDown),

Modified: Zope3/trunk/src/zope/app/security/globalprincipals.txt
===================================================================
--- Zope3/trunk/src/zope/app/security/globalprincipals.txt	2005-10-28 08:14:45 UTC (rev 39686)
+++ Zope3/trunk/src/zope/app/security/globalprincipals.txt	2005-10-28 10:14:24 UTC (rev 39687)
@@ -19,7 +19,8 @@
     ...         title="Manager"
     ...         description="System Manager"
     ...         login="admin"
-    ...         password="123"
+    ...         password_manager="SHA1"
+    ...         password="40bd001563085fc35165329ea1ff5c5ecbdbbeef"
     ...         />
     ...
     ...    </configure>

Modified: Zope3/trunk/src/zope/app/security/metaconfigure.py
===================================================================
--- Zope3/trunk/src/zope/app/security/metaconfigure.py	2005-10-28 08:14:45 UTC (rev 39686)
+++ Zope3/trunk/src/zope/app/security/metaconfigure.py	2005-10-28 10:14:24 UTC (rev 39687)
@@ -28,6 +28,7 @@
 from zope.app.security import principalregistry
 from zope.app.security import interfaces
 
+
 def securityPolicy(_context, component):
 
     _context.action(
@@ -104,11 +105,12 @@
     if group is not None:
         _everybodyGroup(group.id)
 
-def principal(_context, id, title, login, password, description=''):
+def principal(_context, id, title, login,
+        password, description='', password_manager="Plain Text"):
     _context.action(
         discriminator = ('principal', id),
         callable = principalregistry.principalRegistry.definePrincipal,
-        args = (id, title, description, login, password) )
+        args = (id, title, description, login, password, password_manager) )
     _context.action(discriminator = None, callable = _principal, args = ())
 
 

Modified: Zope3/trunk/src/zope/app/security/metadirectives.py
===================================================================
--- Zope3/trunk/src/zope/app/security/metadirectives.py	2005-10-28 08:14:45 UTC (rev 39686)
+++ Zope3/trunk/src/zope/app/security/metadirectives.py	2005-10-28 10:14:24 UTC (rev 39687)
@@ -21,6 +21,7 @@
 from zope.schema import InterfaceField, Id, TextLine
 from fields import Permission
 
+
 class ISecurityPolicyDirective(Interface):
     """Defines the security policy that will be used for Zope."""
 
@@ -69,7 +70,7 @@
     directly in the attributes attribute or any names defined by
     interfaces listed in the interface attribute.  
     """
-    
+
     permission = Permission(
         title=u"Permission ID",
         description=u"The id of the permission to require.")
@@ -77,7 +78,7 @@
 
 class IBaseDefineDirective(Interface):
     """Define a new security object."""
-    
+
     id = Id(
         title=u"Id",
         description=u"Id as which this object will be known and used.",
@@ -99,7 +100,7 @@
 
 class IBasePrincipalDirective(Interface):
     """Base interface for principal definition directives."""
-    
+
     id = Id(
         title=u"Id",
         description=u"Id as which this object will be known and used.",
@@ -128,6 +129,13 @@
         description=u"Specifies the Principal's Password.",
         required=True)
 
+    password_manager = TextLine(
+        title=u"Password Manager Name",
+        description=(u"Name of the password manager will be used"
+            " for encode/check the password"),
+        default=u"Plain Text"
+        )
+
 class IDefineUnauthenticatedPrincipalDirective(IBasePrincipalDirective):
     """Define a new unauthenticated principal."""
 
@@ -147,7 +155,7 @@
         title=u"Original permission",
         description=u"Original permission id to redefine.",
         required=True)
-    
+
     to = Permission(
         title=u"Substituted permission",
         description=u"Substituted permission id.",

Modified: Zope3/trunk/src/zope/app/security/principalregistry.py
===================================================================
--- Zope3/trunk/src/zope/app/security/principalregistry.py	2005-10-28 08:14:45 UTC (rev 39686)
+++ Zope3/trunk/src/zope/app/security/principalregistry.py	2005-10-28 10:14:24 UTC (rev 39687)
@@ -16,12 +16,15 @@
 $Id$
 """
 from zope.interface import implements
+
+from zope.app.authentication.interfaces import IPasswordManager
 from zope.app.security.interfaces import PrincipalLookupError
 from zope.app import zapi
 from zope.security.interfaces import IPrincipal, IGroupAwarePrincipal
 from zope.app.security import interfaces
 from zope.app.container.contained import Contained, contained
 
+
 class DuplicateLogin(Exception): pass
 class DuplicateId(Exception): pass
 
@@ -92,7 +95,7 @@
         self.__principalsByLogin = {}
 
     def definePrincipal(self, principal, title, description='',
-                        login='', password=''):
+            login='', password='', passwordManagerName='Plain Text'):
         id=principal
         if login in self.__principalsByLogin:
             raise DuplicateLogin(login)
@@ -100,7 +103,8 @@
         if id in self.__principalsById or id == self.__defaultid:
             raise DuplicateId(id)
 
-        p = Principal(id, title, description, login, password)
+        p = Principal(id, title, description,
+            login, password, passwordManagerName)
         p = contained(p, self, id)
 
         self.__principalsByLogin[login] = p
@@ -144,16 +148,22 @@
 
     implements(IGroupAwarePrincipal)
 
-    def __init__(self, id, title, description, login, pw):
+    def __init__(self, id, title, description, login,
+            pw, pwManagerName="Plain Text"):
         super(Principal, self).__init__(id, title, description)
         self.__login = login
+        self.__pwManagerName = pwManagerName
         self.__pw = pw
 
+    def __getPasswordManager(self):
+        return zapi.getUtility(IPasswordManager, self.__pwManagerName)
+
     def getLogin(self):
         return self.__login
 
     def validate(self, pw):
-        return pw == self.__pw
+        pwManager = self.__getPasswordManager()
+        return pwManager.checkPassword(self.__pw, pw)
 
 
 class UnauthenticatedPrincipal(PrincipalBase):


Property changes on: Zope3/trunk/src/zope/app/security/tests/module.py
___________________________________________________________________
Name: svn:keywords
   + Id


Property changes on: Zope3/trunk/src/zope/app/security/tests/modulehookup.py
___________________________________________________________________
Name: svn:keywords
   + Id

Modified: Zope3/trunk/src/zope/app/security/tests/principal.zcml
===================================================================
--- Zope3/trunk/src/zope/app/security/tests/principal.zcml	2005-10-28 08:14:45 UTC (rev 39686)
+++ Zope3/trunk/src/zope/app/security/tests/principal.zcml	2005-10-28 10:14:24 UTC (rev 39687)
@@ -5,16 +5,21 @@
 
   <include package="zope.app.security" file="meta.zcml"/>
 
-  <principal 
+  <principal
       id="zope.p1"
       title="Sir Tim Peters"
       description="Tim Peters"
-      login="tim" password="123" />
+      login="tim"
+      password_manager="SHA1"
+      password="40bd001563085fc35165329ea1ff5c5ecbdbbeef"
+      />
 
-  <principal 
+  <principal
       id="zope.p2"
       title="Sir Jim Fulton"
       description="Jim Fulton"
-      login="jim" password="123" />
- 
+      login="jim"
+      password="123"
+      />
+
 </configure>

Modified: Zope3/trunk/src/zope/app/security/tests/test_adapter.py
===================================================================
--- Zope3/trunk/src/zope/app/security/tests/test_adapter.py	2005-10-28 08:14:45 UTC (rev 39686)
+++ Zope3/trunk/src/zope/app/security/tests/test_adapter.py	2005-10-28 10:14:24 UTC (rev 39687)
@@ -4,7 +4,7 @@
 # All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
@@ -17,11 +17,12 @@
 import unittest
 from zope.testing.doctestunit import DocTestSuite
 
+
 def test_suite():
     return unittest.TestSuite((
         DocTestSuite('zope.app.security.adapter'),
         ))
 
+
 if __name__ == '__main__':
     unittest.main(defaultTest='test_suite')
-


Property changes on: Zope3/trunk/src/zope/app/security/tests/test_basicauthadapter.py
___________________________________________________________________
Name: svn:keywords
   + Id


Property changes on: Zope3/trunk/src/zope/app/security/tests/test_loginpassword.py
___________________________________________________________________
Name: svn:keywords
   + Id

Modified: Zope3/trunk/src/zope/app/security/tests/test_logout.py
===================================================================
--- Zope3/trunk/src/zope/app/security/tests/test_logout.py	2005-10-28 08:14:45 UTC (rev 39686)
+++ Zope3/trunk/src/zope/app/security/tests/test_logout.py	2005-10-28 10:14:24 UTC (rev 39687)
@@ -1,3 +1,19 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
 import unittest
 
 from zope.testing import doctest
@@ -8,6 +24,7 @@
 from zope.app.testing import placelesssetup
 from zope.app.security import interfaces
 
+
 def test_suite():
     return unittest.TestSuite((
         doctest.DocFileSuite(
@@ -23,5 +40,6 @@
             ),
         ))
 
+
 if __name__ == '__main__':
     unittest.main(defaultTest='test_suite')


Property changes on: Zope3/trunk/src/zope/app/security/tests/test_vocabulary.py
___________________________________________________________________
Name: svn:keywords
   + Id

Modified: Zope3/trunk/src/zope/app/server/mkzopeinstance.py
===================================================================
--- Zope3/trunk/src/zope/app/server/mkzopeinstance.py	2005-10-28 08:14:45 UTC (rev 39686)
+++ Zope3/trunk/src/zope/app/server/mkzopeinstance.py	2005-10-28 10:14:24 UTC (rev 39687)
@@ -29,6 +29,7 @@
 
 import zope
 
+from zope.app.authentication import password
 from zope.app.applicationcontrol import zopeversion
 
 
@@ -100,8 +101,11 @@
 
         if not options.username:
             options.username = self.get_username()
+        (options.password_manager,
+            password_manager) = self.get_password_manager()
         if not options.password:
             options.password = self.get_password()
+        options.password = password_manager.encodePassword(options.password)
 
         # now create the instance!
         self.copy_skeleton()
@@ -151,6 +155,34 @@
             sys.exit(1)
         return password
 
+    def get_password_manager(self):
+        if self.options.password_manager:
+            for name, manager in password.managers:
+                if name == self.options.password_manager:
+                    return (name, manager)
+            print >>sys.stderr, "Unknown password manager!"
+            sys.exit(1)
+
+        self.print_message(PASSWORD_MANAGER_MESSAGE)
+        for i, (name, manager) in enumerate(password.managers):
+            print "% i. %s" % (i + 1, name)
+        print
+        self.need_blank_line = True
+        while 1:
+            password_manager = self.read_input_line(
+                "Password Manager Number [1]: ")
+            if not password_manager:
+                index = 0
+                break
+            elif password_manager.isdigit():
+                index = int(password_manager)
+                if index > 0 and index <= len(password.managers):
+                    index -= 1
+                    break
+            print >>sys.stderr, "You must select a password manager"
+        print "%r password manager selected" % password.managers[index][0] 
+        return password.managers[index]
+
     def print_message(self, message):
         if self.need_blank_line:
             print
@@ -165,11 +197,12 @@
         zope_init = os.path.abspath(zope.__file__)
         software_home = os.path.dirname(os.path.dirname(zope_init))
         self.replacements = [
-            ("<<USERNAME>>",      options.username),
-            ("<<PASSWORD>>",      options.password),
-            ("<<PYTHON>>",        sys.executable),
+            ("<<USERNAME>>", options.username),
+            ("<<PASSWORD>>", options.password),
+            ("<<PASSWORD_MANAGER>>", options.password_manager),
+            ("<<PYTHON>>", sys.executable),
             ("<<INSTANCE_HOME>>", options.destination),
-            ("<<ZOPE_HOME>>",     zope_home),
+            ("<<ZOPE_HOME>>", zope_home),
             ("<<SOFTWARE_HOME>>", software_home),
             ]
         self.copytree(self.options.skeleton, self.options.destination)
@@ -224,7 +257,12 @@
 Please provide a password for the initial administrator account.
 """
 
+PASSWORD_MANAGER_MESSAGE = """\
+Please select a password manager which will be used for encode the password of
+the initial administrator account.
+"""
 
+
 def parse_args(argv, from_checkout=False):
     """Parse the command line, returning an object representing the input."""
     path, prog = os.path.split(os.path.realpath(argv[0]))
@@ -236,6 +274,10 @@
                  help="the dir in which the instance home should be created")
     p.add_option("-s", "--skelsrc", dest="skeleton", metavar="DIR",
                  help="template skeleton directory")
+    p.add_option("-m", "--password-manager",
+                 dest="password_manager", metavar="NAME",
+                 help=("set the name of the password manager"
+                       " to be used for encode the password"))
     p.add_option("-u", "--user", dest="username", metavar="USER:PASSWORD",
                  help="set the user name and password of the initial user")
     options, args = p.parse_args(argv[1:])


Property changes on: Zope3/trunk/src/zope/app/server/mkzopeinstance.py
___________________________________________________________________
Name: svn:keywords
   + Id

Copied: Zope3/trunk/src/zope/app/server/tests/site.zcml (from rev 39669, Zope3/branches/hdima-password-managers/src/zope/app/server/tests/site.zcml)


Property changes on: Zope3/trunk/src/zope/app/server/tests/test_accesslog.py
___________________________________________________________________
Name: svn:keywords
   + Id

Modified: Zope3/trunk/src/zope/app/server/tests/test_mkzopeinstance.py
===================================================================
--- Zope3/trunk/src/zope/app/server/tests/test_mkzopeinstance.py	2005-10-28 08:14:45 UTC (rev 39686)
+++ Zope3/trunk/src/zope/app/server/tests/test_mkzopeinstance.py	2005-10-28 10:14:24 UTC (rev 39687)
@@ -128,6 +128,18 @@
         self.assertEqual(options.username, "User")
         self.assertEqual(options.password, "Pass")
 
+    def test_without_password_manager(self):
+        options = self.parse_args([])
+        self.assertEqual(options.password_manager, None)
+
+    def test_password_manager_short(self):
+        options = self.parse_args(["-m", "Manager"])
+        self.assertEqual(options.password_manager, "Manager")
+
+    def test_password_manager_long(self):
+        options = self.parse_args(["--password-manager", "Manager"])
+        self.assertEqual(options.password_manager, "Manager")
+
     def test_junk_positional_arg(self):
         try:
             self.parse_args(["junk"])
@@ -216,6 +228,32 @@
         self.failUnless(self.stdout.getvalue())
         self.failUnless(app.all_input_consumed())
 
+    def test_get_password_manager(self):
+        options = self.createOptions()
+        options.password_manager = None
+        app = ControlledInputApplication(options, ["3"])
+        name, pwm = app.get_password_manager()
+        self.assertEqual(name, "SHA1")
+        self.assertEqual(pwm.encodePassword("foo"),
+            "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33")
+        self.failIf(self.stderr.getvalue())
+        self.failUnless(self.stdout.getvalue())
+        self.failUnless(app.all_input_consumed())
+
+    def test_get_wrong_password_manager(self):
+        options = self.createOptions()
+        options.password_manager = "Unknown"
+        app = ControlledInputApplication(options, [])
+        try:
+            app.get_password_manager()
+        except SystemExit, e:
+            self.assertEqual(e.code, 1)
+        else:
+            self.fail("expected SystemExit")
+        self.failUnless(self.stderr.getvalue())
+        self.failIf(self.stdout.getvalue())
+        self.failUnless(app.all_input_consumed())
+
     def test_get_password(self):
         options = self.createOptions()
         app = ControlledInputApplication(options, ["foo", "foo"])
@@ -303,6 +341,7 @@
 class Options(object):
 
     username = "[test-username]"
+    password_manager = "Plain Text"
     password = "[test-password]"
     destination = None
     version = "[test-version]"


Property changes on: Zope3/trunk/src/zope/app/server/tests/test_mkzopeinstance.py
___________________________________________________________________
Name: svn:keywords
   + Id

Copied: Zope3/trunk/src/zope/app/server/tests/test_zpasswd.py (from rev 39669, Zope3/branches/hdima-password-managers/src/zope/app/server/tests/test_zpasswd.py)

Copied: Zope3/trunk/src/zope/app/server/zpasswd.py (from rev 39669, Zope3/branches/hdima-password-managers/src/zope/app/server/zpasswd.py)

Modified: Zope3/trunk/src/zope/app/testing/placelesssetup.py
===================================================================
--- Zope3/trunk/src/zope/app/testing/placelesssetup.py	2005-10-28 08:14:45 UTC (rev 39686)
+++ Zope3/trunk/src/zope/app/testing/placelesssetup.py	2005-10-28 10:14:24 UTC (rev 39687)
@@ -25,6 +25,8 @@
     import PlacelessSetup as I18nPlacelessSetup
 from zope.app.container.tests.placelesssetup \
     import PlacelessSetup as ContainerPlacelessSetup
+from zope.app.authentication.placelesssetup \
+    import PlacelessSetup as AuthenticationPlacelessSetup
 from zope.app.security._protections import protect
 from zope.app.traversing.browser.interfaces import IAbsoluteURL
 from zope.app.traversing.browser.absoluteurl import AbsoluteURL
@@ -32,7 +34,8 @@
 class PlacelessSetup(CAPlacelessSetup,
                      EventPlacelessSetup,
                      I18nPlacelessSetup,
-                     ContainerPlacelessSetup
+                     ContainerPlacelessSetup,
+                     AuthenticationPlacelessSetup
                      ):
 
     def setUp(self, doctesttest=None):
@@ -40,6 +43,7 @@
         ContainerPlacelessSetup.setUp(self)
         EventPlacelessSetup.setUp(self)
         I18nPlacelessSetup.setUp(self)
+        AuthenticationPlacelessSetup.setUp(self)
         # Register app-specific security declarations
         protect()
 

Modified: Zope3/trunk/src/zope/app/zopeappgenerations/__init__.py
===================================================================
--- Zope3/trunk/src/zope/app/zopeappgenerations/__init__.py	2005-10-28 08:14:45 UTC (rev 39686)
+++ Zope3/trunk/src/zope/app/zopeappgenerations/__init__.py	2005-10-28 10:14:24 UTC (rev 39687)
@@ -24,7 +24,7 @@
 
 ZopeAppSchemaManager = SchemaManager(
     minimum_generation=0,
-    generation=1,
+    generation=2,
     package_name=key)
 
 


Property changes on: Zope3/trunk/src/zope/app/zopeappgenerations/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id

Modified: Zope3/trunk/src/zope/app/zopeappgenerations/evolve1.py
===================================================================
--- Zope3/trunk/src/zope/app/zopeappgenerations/evolve1.py	2005-10-28 08:14:45 UTC (rev 39686)
+++ Zope3/trunk/src/zope/app/zopeappgenerations/evolve1.py	2005-10-28 10:14:24 UTC (rev 39687)
@@ -55,7 +55,7 @@
       the component's path. Now it stores the component directly. All
       registrations are updated to this new format.
 
-    - Conerts all service registrations to utility registrations providing
+    - Converts all service registrations to utility registrations providing
       IService, which is the method used to simulate the old service API.
 
     - Remove 'RegistrationManager' object from all site management folders.


Property changes on: Zope3/trunk/src/zope/app/zopeappgenerations/evolve1.py
___________________________________________________________________
Name: svn:keywords
   + Id

Copied: Zope3/trunk/src/zope/app/zopeappgenerations/evolve2.py (from rev 39669, Zope3/branches/hdima-password-managers/src/zope/app/zopeappgenerations/evolve2.py)

Copied: Zope3/trunk/zopeskel/bin/zpasswd.in (from rev 39669, Zope3/branches/hdima-password-managers/zopeskel/bin/zpasswd.in)

Modified: Zope3/trunk/zopeskel/etc/principals.zcml.in
===================================================================
--- Zope3/trunk/zopeskel/etc/principals.zcml.in	2005-10-28 08:14:45 UTC (rev 39686)
+++ Zope3/trunk/zopeskel/etc/principals.zcml.in	2005-10-28 10:14:24 UTC (rev 39687)
@@ -27,6 +27,7 @@
     id="zope.manager"
     title="Manager"
     login="<<USERNAME>>"
+    password_manager="<<PASSWORD_MANAGER>>"
     password="<<PASSWORD>>"
     />
 



More information about the Zope3-Checkins mailing list