[Checkins] SVN: zope.publisher/trunk/ Move zope.publisher-specific ILoginPassword implementations into this package, thus making it dependent on zope.authentication.

Dan Korostelev nadako at gmail.com
Fri Mar 13 06:40:57 EDT 2009


Log message for revision 98028:
  Move zope.publisher-specific ILoginPassword implementations into this package, thus making it dependent on zope.authentication.

Changed:
  U   zope.publisher/trunk/CHANGES.txt
  U   zope.publisher/trunk/buildout.cfg
  U   zope.publisher/trunk/setup.py
  U   zope.publisher/trunk/src/zope/publisher/configure.zcml
  U   zope.publisher/trunk/src/zope/publisher/ftp.py
  U   zope.publisher/trunk/src/zope/publisher/http.py
  A   zope.publisher/trunk/src/zope/publisher/tests/test_basicauthadapter.py
  A   zope.publisher/trunk/src/zope/publisher/tests/test_ftpauth.py

-=-
Modified: zope.publisher/trunk/CHANGES.txt
===================================================================
--- zope.publisher/trunk/CHANGES.txt	2009-03-13 10:31:44 UTC (rev 98027)
+++ zope.publisher/trunk/CHANGES.txt	2009-03-13 10:40:56 UTC (rev 98028)
@@ -8,6 +8,13 @@
   ``zope.publisher.interfaces.logginginfo.ILoggingInfo``. It was moved
   from ``zope.app.security`` as a part of refactoring process. 
 
+- Add adapters from HTTP and FTP request to ``zope.authentication.ILoginPassword``
+  interface. They are moved from ``zope.app.security`` as a part of refactoring
+  process. This change adds a dependency on the ``zope.authentication`` package,
+  but it's okay, since it's a tiny contract definition-only package.
+
+  See http://mail.zope.org/pipermail/zope-dev/2009-March/035325.html for reasoning.
+
 3.6.1 (2009-03-09)
 ------------------
 

Modified: zope.publisher/trunk/buildout.cfg
===================================================================
--- zope.publisher/trunk/buildout.cfg	2009-03-13 10:31:44 UTC (rev 98027)
+++ zope.publisher/trunk/buildout.cfg	2009-03-13 10:40:56 UTC (rev 98028)
@@ -1,5 +1,5 @@
 [buildout]
-develop = .
+develop = . ../zope.authentication
 parts = test
 
 [test]

Modified: zope.publisher/trunk/setup.py
===================================================================
--- zope.publisher/trunk/setup.py	2009-03-13 10:31:44 UTC (rev 98027)
+++ zope.publisher/trunk/setup.py	2009-03-13 10:40:56 UTC (rev 98028)
@@ -41,6 +41,7 @@
 
       namespace_packages=['zope',],
       install_requires=['setuptools',
+                        'zope.authentication',
                         'zope.component',
                         'zope.event',
                         'zope.exceptions',

Modified: zope.publisher/trunk/src/zope/publisher/configure.zcml
===================================================================
--- zope.publisher/trunk/src/zope/publisher/configure.zcml	2009-03-13 10:31:44 UTC (rev 98027)
+++ zope.publisher/trunk/src/zope/publisher/configure.zcml	2009-03-13 10:40:56 UTC (rev 98028)
@@ -37,6 +37,18 @@
       for="zope.security.interfaces.IPrincipal"
       />
 
+  <adapter
+      factory=".http.BasicAuthAdapter"
+      provides="zope.authentication.interfaces.ILoginPassword"
+      for=".interfaces.http.IHTTPCredentials"
+      />
+
+  <adapter
+      factory=".ftp.FTPAuth"
+      provides="zope.authentication.interfaces.ILoginPassword"
+      for=".interfaces.ftp.IFTPCredentials"
+      />
+
   <apidoc:bookchapter
       zcml:condition="have apidoc"
       id="zopepublisherhttpresults.txt"

Modified: zope.publisher/trunk/src/zope/publisher/ftp.py
===================================================================
--- zope.publisher/trunk/src/zope/publisher/ftp.py	2009-03-13 10:31:44 UTC (rev 98027)
+++ zope.publisher/trunk/src/zope/publisher/ftp.py	2009-03-13 10:40:56 UTC (rev 98028)
@@ -15,10 +15,13 @@
 
 $Id$
 """
+from zope.authentication.loginpassword import LoginPassword
+from zope.component import adapts
 from zope.interface import implements
 from zope.publisher.interfaces.ftp import IFTPCredentials, IFTPRequest
 from zope.publisher.base import BaseResponse, BaseRequest
 
+
 class FTPResponse(BaseResponse):
     __slots__ = '_exc', # Saved exception
 
@@ -34,6 +37,7 @@
     def handleException(self, exc_info):
         self._exc = exc_info
 
+
 class FTPRequest(BaseRequest):
     implements(IFTPCredentials, IFTPRequest)
 
@@ -66,3 +70,24 @@
     def unauthorized(self, challenge):
         'See IFTPCredentials'
 
+
+class FTPAuth(LoginPassword):
+    """ILoginPassword adapter for handling common FTP authentication."""
+
+    # This was moved from zope.app.security as a part of refactoring process,
+    # see http://mail.zope.org/pipermail/zope-dev/2009-March/035325.html for
+    # the reasoning.
+
+    adapts(IFTPCredentials)
+
+    def __init__(self, request):
+        self.__request = request
+        lpw = request._authUserPW()
+        if lpw is None:
+            login, password = None, None
+        else:
+            login, password = lpw
+        super(FTPAuth, self).__init__(login, password)
+
+    def needLogin(self, realm):
+        self.__request.unauthorized("Did not work")

Modified: zope.publisher/trunk/src/zope/publisher/http.py
===================================================================
--- zope.publisher/trunk/src/zope/publisher/http.py	2009-03-13 10:31:44 UTC (rev 98027)
+++ zope.publisher/trunk/src/zope/publisher/http.py	2009-03-13 10:40:56 UTC (rev 98028)
@@ -44,6 +44,7 @@
 from zope.i18n.interfaces import IUserPreferredCharsets
 from zope.i18n.interfaces import IUserPreferredLanguages
 from zope.i18n.locales import locales, LoadLocaleError
+from zope.authentication.loginpassword import LoginPassword
 
 from zope.publisher import contenttype
 from zope.publisher.base import BaseRequest, BaseResponse
@@ -1009,3 +1010,26 @@
 
     def __iter__(self):
         return iter(self.body)
+
+
+class BasicAuthAdapter(LoginPassword):
+    """ILoginPassword adapter for handling HTTP Basic authentication"""
+
+    # This was moved from zope.app.security as a part of refactoring process,
+    # see http://mail.zope.org/pipermail/zope-dev/2009-March/035325.html for
+    # the reasoning.
+
+    component.adapts(IHTTPCredentials)
+
+    def __init__(self, request):
+        self.__request = request
+        # TODO base64 decoding should be done here, not in request
+        lpw = request._authUserPW()
+        if lpw is None:
+            login, password = None, None
+        else:
+            login, password = lpw
+        super(BasicAuthAdapter, self).__init__(login, password)
+
+    def needLogin(self, realm):
+        self.__request.unauthorized('basic realm="%s"' % realm)

Copied: zope.publisher/trunk/src/zope/publisher/tests/test_basicauthadapter.py (from rev 98020, zope.authentication/trunk/src/zope/authentication/tests/test_basicauthadapter.py)
===================================================================
--- zope.publisher/trunk/src/zope/publisher/tests/test_basicauthadapter.py	                        (rev 0)
+++ zope.publisher/trunk/src/zope/publisher/tests/test_basicauthadapter.py	2009-03-13 10:40:56 UTC (rev 98028)
@@ -0,0 +1,58 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 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.
+#
+##############################################################################
+"""Test Basic Authentication Adapter
+
+$Id$
+"""
+import unittest
+
+from zope.publisher.http import BasicAuthAdapter
+
+class Request(object):
+
+    def __init__(self, lpw):
+        self.lpw = lpw
+
+    def _authUserPW(self):
+        return self.lpw
+
+    challenge = None
+    def unauthorized(self, challenge):
+        self.challenge = challenge
+
+
+class Test(unittest.TestCase):
+
+    def testBasicAuthAdapter(self):
+        r = Request(None)
+        a = BasicAuthAdapter(r)
+        self.assertEqual(a.getLogin(), None)
+        self.assertEqual(a.getPassword(), None)
+        r = Request(("tim", "123"))
+        a = BasicAuthAdapter(r)
+        self.assertEqual(a.getLogin(), "tim")
+        self.assertEqual(a.getPassword(), "123")
+
+    def testUnauthorized(self):
+        r = Request(None)
+        a = BasicAuthAdapter(r)
+        a.needLogin("tim")
+        self.assertEqual(r.challenge, 'basic realm="tim"')
+
+def test_suite():
+    loader=unittest.TestLoader()
+    return loader.loadTestsFromTestCase(Test)
+
+if __name__=='__main__':
+    unittest.TextTestRunner().run(test_suite())

Copied: zope.publisher/trunk/src/zope/publisher/tests/test_ftpauth.py (from rev 98020, zope.authentication/trunk/src/zope/authentication/tests/test_ftpauth.py)
===================================================================
--- zope.publisher/trunk/src/zope/publisher/tests/test_ftpauth.py	                        (rev 0)
+++ zope.publisher/trunk/src/zope/publisher/tests/test_ftpauth.py	2009-03-13 10:40:56 UTC (rev 98028)
@@ -0,0 +1,63 @@
+##############################################################################
+#
+# Copyright (c) 2003 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.
+#
+##############################################################################
+"""FTP Authentication Test
+
+$Id$
+"""
+from unittest import TestCase, TestSuite, main, makeSuite
+from zope.publisher.interfaces.ftp import IFTPCredentials
+from zope.interface import implements
+
+from zope.publisher.ftp import FTPAuth
+
+class FTPCredentials(object):
+    __doc__ = IFTPCredentials.__doc__
+
+    implements(IFTPCredentials)
+
+    def __init__(self, credentials):
+        self.credentials = credentials
+
+    def _authUserPW(self):
+        return self.credentials
+
+    unauth = 0
+    def unauthorized(self, challenge):
+        self.unauth += 1
+
+
+class Test(TestCase):
+
+    def test(self):
+        request = FTPCredentials(('bob', '123'))
+        auth = FTPAuth(request)
+        self.assertEqual(auth.getLogin(), 'bob')
+        self.assertEqual(auth.getPassword(), '123')
+
+        unauth = request.unauth
+        auth.needLogin('xxx')
+        self.assertEqual(request.unauth, unauth+1)
+
+        request = FTPCredentials(None)
+        auth = FTPAuth(request)
+        self.assertEqual(auth.getLogin(), None)
+        self.assertEqual(auth.getPassword(), None)
+
+def test_suite():
+    return TestSuite((
+        makeSuite(Test),
+        ))
+
+if __name__=='__main__':
+    main(defaultTest='test_suite')



More information about the Checkins mailing list