[Zope-Checkins] CVS: ZODB3/ZEO/tests - testAuth.py:1.3 auth_plaintext.py:1.2 zeoserver.py:1.18 testZEO.py:1.72 testMonitor.py:1.6 ConnectionTests.py:1.26
Jeremy Hylton
jeremy@zope.com
Fri, 30 May 2003 15:21:27 -0400
Update of /cvs-repository/ZODB3/ZEO/tests
In directory cvs.zope.org:/tmp/cvs-serv25334/ZEO/tests
Modified Files:
zeoserver.py testZEO.py testMonitor.py ConnectionTests.py
Added Files:
testAuth.py auth_plaintext.py
Log Message:
Merge ZODB3-auth-branch and bump a few version numbers.
After the merge, I made several Python 2.1 compatibility changes for
the auth code.
=== ZODB3/ZEO/tests/testAuth.py 1.2 => 1.3 ===
--- /dev/null Fri May 30 15:21:27 2003
+++ ZODB3/ZEO/tests/testAuth.py Fri May 30 15:20:56 2003
@@ -0,0 +1,111 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# 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.
+# 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 suite for AuthZEO."""
+
+import os
+import tempfile
+import time
+import unittest
+
+from ThreadedAsync import LoopCallback
+from ZEO.ClientStorage import ClientStorage
+from ZEO.StorageServer import StorageServer
+from ZEO.tests.ConnectionTests import CommonSetupTearDown
+
+from ZODB.FileStorage import FileStorage
+from ZODB.tests.StorageTestBase import removefs
+
+class AuthTest(CommonSetupTearDown):
+ __super_getServerConfig = CommonSetupTearDown.getServerConfig
+ __super_setUp = CommonSetupTearDown.setUp
+ __super_tearDown = CommonSetupTearDown.tearDown
+
+ realm = None
+
+ def setUp(self):
+ self.pwfile = tempfile.mktemp()
+ if self.realm:
+ self.pwdb = self.dbclass(self.pwfile, self.realm)
+ else:
+ self.pwdb = self.dbclass(self.pwfile)
+ self.pwdb.add_user("foo", "bar")
+ self.pwdb.save()
+ self.__super_setUp()
+
+ def tearDown(self):
+ self.__super_tearDown()
+ os.remove(self.pwfile)
+
+ def getConfig(self, path, create, read_only):
+ return "<mappingstorage 1/>"
+
+ def getServerConfig(self, addr, ro_svr):
+ zconf = self.__super_getServerConfig(addr, ro_svr)
+ zconf.authentication_protocol = self.protocol
+ zconf.authentication_database = self.pwfile
+ zconf.authentication_realm = self.realm
+ return zconf
+
+ def wait(self):
+ for i in range(25):
+ if self._storage.test_connection:
+ return
+ time.sleep(0.1)
+ self.fail("Timed out waiting for client to authenticate")
+
+ def testOK(self):
+ # Sleep for 0.2 seconds to give the server some time to start up
+ # seems to be needed before and after creating the storage
+ self._storage = self.openClientStorage(wait=0, username="foo",
+ password="bar", realm=self.realm)
+ self.wait()
+
+ self.assert_(self._storage._connection)
+ self._storage._connection.poll()
+ self.assert_(self._storage.is_connected())
+
+ def testNOK(self):
+ self._storage = self.openClientStorage(wait=0, username="foo",
+ password="noogie",
+ realm=self.realm)
+ self.wait()
+ # If the test established a connection, then it failed.
+ self.failIf(self._storage._connection)
+
+class PlainTextAuth(AuthTest):
+ import ZEO.tests.auth_plaintext
+ protocol = "plaintext"
+ database = "authdb.sha"
+ dbclass = ZEO.tests.auth_plaintext.Database
+ realm = "Plaintext Realm"
+
+class DigestAuth(AuthTest):
+ import ZEO.auth.auth_digest
+ protocol = "digest"
+ database = "authdb.digest"
+ dbclass = ZEO.auth.auth_digest.DigestDatabase
+ realm = "Digest Realm"
+
+test_classes = [PlainTextAuth, DigestAuth]
+
+def test_suite():
+ suite = unittest.TestSuite()
+ for klass in test_classes:
+ sub = unittest.makeSuite(klass)
+ suite.addTest(sub)
+ return suite
+
+if __name__ == "__main__":
+ unittest.main(defaultTest='test_suite')
+
=== ZODB3/ZEO/tests/auth_plaintext.py 1.1 => 1.2 ===
--- /dev/null Fri May 30 15:21:27 2003
+++ ZODB3/ZEO/tests/auth_plaintext.py Fri May 30 15:20:56 2003
@@ -0,0 +1,44 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# 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.
+# 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
+#
+##############################################################################
+"""Implements plaintext password authentication. The password is stored in
+an SHA hash in the Database. The client sends over the plaintext
+password, and the SHA hashing is done on the server side.
+
+This mechanism offers *no network security at all*; the only security
+is provided by not storing plaintext passwords on disk. (See the
+auth_srp module for a secure mechanism)"""
+
+import sha
+
+from ZEO.StorageServer import ZEOStorage
+from ZEO.auth import register_module
+from ZEO.auth.base import Client, Database
+
+class StorageClass(ZEOStorage):
+ def auth(self, username, password):
+ try:
+ dbpw = self.database.get_password(username)
+ except LookupError:
+ return 0
+
+ password = sha.new(password).hexdigest()
+ return self.finish_auth(dbpw == password)
+
+class PlaintextClient(Client):
+ extensions = ["auth"]
+
+ def start(self, username, realm, password):
+ return self.stub.auth(username, password)
+
+register_module("plaintext", StorageClass, PlaintextClient, Database)
=== ZODB3/ZEO/tests/zeoserver.py 1.17 => 1.18 ===
--- ZODB3/ZEO/tests/zeoserver.py:1.17 Fri May 30 11:08:40 2003
+++ ZODB3/ZEO/tests/zeoserver.py Fri May 30 15:20:56 2003
@@ -26,9 +26,8 @@
import ZConfig.Context
import zLOG
-import ZEO.StorageServer
+from ZEO.StorageServer import StorageServer
from ZEO.runzeo import ZEOOptions
-from ZODB.config import storageFromURL
def cleanup(storage):
@@ -152,6 +151,10 @@
zo.realize(["-C", configfile])
zeo_port = int(zo.address[1])
+ # XXX a hack
+ if zo.auth_protocol == "plaintext":
+ import ZEO.tests.auth_plaintext
+
# Open the config file and let ZConfig parse the data there. Then remove
# the config file, otherwise we'll leave turds.
# The rest of the args are hostname, portnum
@@ -163,14 +166,17 @@
mon_addr = None
if zo.monitor_address:
mon_addr = zo.monitor_address.address
- server = ZEO.StorageServer.StorageServer(
+ server = StorageServer(
zo.address,
{"1": storage},
read_only=zo.read_only,
invalidation_queue_size=zo.invalidation_queue_size,
transaction_timeout=zo.transaction_timeout,
- monitor_address=mon_addr)
-
+ monitor_address=mon_addr,
+ auth_protocol=zo.auth_protocol,
+ auth_filename=zo.auth_database,
+ auth_realm=zo.auth_realm)
+
try:
log(label, 'creating the test server, keep: %s', keep)
t = ZEOTestServer(test_addr, server, keep)
=== ZODB3/ZEO/tests/testZEO.py 1.71 => 1.72 ===
--- ZODB3/ZEO/tests/testZEO.py:1.71 Fri May 30 14:31:16 2003
+++ ZODB3/ZEO/tests/testZEO.py Fri May 30 15:20:56 2003
@@ -39,8 +39,7 @@
MTStorage, ReadOnlyStorage
from ZEO.ClientStorage import ClientStorage
-from ZEO.tests import forker, Cache
-from ZEO.tests import CommitLockTests, ThreadTests
+from ZEO.tests import forker, Cache, CommitLockTests, ThreadTests
class DummyDB:
def invalidate(self, *args):
=== ZODB3/ZEO/tests/testMonitor.py 1.5 => 1.6 ===
=== ZODB3/ZEO/tests/ConnectionTests.py 1.25 => 1.26 ===
--- ZODB3/ZEO/tests/ConnectionTests.py:1.25 Thu May 29 15:18:18 2003
+++ ZODB3/ZEO/tests/ConnectionTests.py Fri May 30 15:20:56 2003
@@ -41,6 +41,8 @@
class TestClientStorage(ClientStorage):
+ test_connection = 0
+
def verify_cache(self, stub):
self.end_verify = threading.Event()
self.verify_result = ClientStorage.verify_cache(self, stub)
@@ -49,6 +51,12 @@
ClientStorage.endVerify(self)
self.end_verify.set()
+ def testConnection(self, conn):
+ try:
+ return ClientStorage.testConnection(self, conn)
+ finally:
+ self.test_connection = 1
+
class DummyDB:
def invalidate(self, *args, **kwargs):
pass
@@ -113,38 +121,45 @@
# port+1 is also used, so only draw even port numbers
return 'localhost', random.randrange(25000, 30000, 2)
- def getConfig(self):
+ def getConfig(self, path, create, read_only):
raise NotImplementedError
def openClientStorage(self, cache='', cache_size=200000, wait=1,
- read_only=0, read_only_fallback=0):
- base = TestClientStorage(self.addr,
- client=cache,
- cache_size=cache_size,
- wait=wait,
- min_disconnect_poll=0.1,
- read_only=read_only,
- read_only_fallback=read_only_fallback)
- storage = base
+ read_only=0, read_only_fallback=0,
+ username=None, password=None, realm=None):
+ storage = TestClientStorage(self.addr,
+ client=cache,
+ cache_size=cache_size,
+ wait=wait,
+ min_disconnect_poll=0.1,
+ read_only=read_only,
+ read_only_fallback=read_only_fallback,
+ username=username,
+ password=password,
+ realm=realm)
storage.registerDB(DummyDB(), None)
return storage
- def startServer(self, create=1, index=0, read_only=0, ro_svr=0):
- addr = self.addr[index]
- zLOG.LOG("testZEO", zLOG.INFO,
- "startServer(create=%d, index=%d, read_only=%d) @ %s" %
- (create, index, read_only, addr))
- path = "%s.%d" % (self.file, index)
- sconf = self.getConfig(path, create, read_only)
+ def getServerConfig(self, addr, ro_svr):
zconf = forker.ZEOConfig(addr)
if ro_svr:
zconf.read_only = 1
if self.monitor:
- zconf.monitor_address = ("", 42000)
+ zconf.monitor_address = ("", 42000)
if self.invq:
zconf.invalidation_queue_size = self.invq
if self.timeout:
zconf.transaction_timeout = self.timeout
+ return zconf
+
+ def startServer(self, create=1, index=0, read_only=0, ro_svr=0):
+ addr = self.addr[index]
+ zLOG.LOG("testZEO", zLOG.INFO,
+ "startServer(create=%d, index=%d, read_only=%d) @ %s" %
+ (create, index, read_only, addr))
+ path = "%s.%d" % (self.file, index)
+ sconf = self.getConfig(path, create, read_only)
+ zconf = self.getServerConfig(addr, ro_svr)
zeoport, adminaddr, pid, path = forker.start_zeo_server(sconf, zconf,
addr[1],
self.keep)
@@ -448,7 +463,6 @@
self._storage = self.openClientStorage()
self._dostore()
-
# Test case for multiple storages participating in a single
# transaction. This is not really a connection test, but it needs