def gclient(): """ Get an LDAPClient with GeventLDAPConnection async class. """ cfg = get_config() url = "ldap://%s:%s/%s?%s?%s" % ( cfg["SERVER"]["hostip"], cfg["SERVER"]["port"], cfg["SERVER"]["basedn"], cfg["SERVER"]["search_attr"], cfg["SERVER"]["search_scope"], ) cli = LDAPClient(url) cli.set_credentials("SIMPLE", user=cfg["SIMPLEAUTH"]["user"], password=cfg["SIMPLEAUTH"]["password"]) cli.set_async_connection_class(GeventLDAPConnection) return cli
def gclient(): """ Get an LDAPClient with GeventLDAPConnection async class. """ cfg = get_config() url = "ldap://%s:%s/%s?%s?%s" % ( cfg["SERVER"]["hostip"], cfg["SERVER"]["port"], cfg["SERVER"]["basedn"], cfg["SERVER"]["search_attr"], cfg["SERVER"]["search_scope"], ) cli = LDAPClient(url) cli.set_credentials( "SIMPLE", user=cfg["SIMPLEAUTH"]["user"], password=cfg["SIMPLEAUTH"]["password"] ) cli.set_async_connection_class(GeventLDAPConnection) return cli
class TornadoLDAPConnectionTest(TestCaseClass): """ Test TornadoLDAPConnection object. """ def setUp(self): """ Set LDAP URL and open connection. """ curdir = os.path.abspath(os.path.dirname(__file__)) self.cfg = configparser.ConfigParser() self.cfg.read(os.path.join(curdir, 'test.ini')) self.url = "ldap://%s:%s/%s?%s?%s" % (self.cfg["SERVER"]["hostip"], \ self.cfg["SERVER"]["port"], \ self.cfg["SERVER"]["basedn"], \ self.cfg["SERVER"]["search_attr"], \ self.cfg["SERVER"]["search_scope"]) self.basedn = self.cfg["SERVER"]["basedn"] self.ipaddr = self.cfg["SERVER"]["hostip"] self.client = LDAPClient(self.url) self.client.set_credentials("SIMPLE", (self.cfg["SIMPLEAUTH"]["user"], self.cfg["SIMPLEAUTH"]["password"])) self.client.set_async_connection_class(TornadoLDAPConnection) self.io_loop = self.get_new_ioloop() @gen_test(timeout=20.0) def test_connection(self): conn = yield self.client.connect(True, ioloop=self.io_loop) self.assertIsNotNone(conn) self.assertFalse(conn.closed) conn.close() @gen_test(timeout=20.0) def test_search(self): with (yield self.client.connect(True, ioloop=self.io_loop)) as conn: res = yield conn.search() self.assertIsNotNone(res) @gen_test(timeout=20.0) def test_add_and_delete(self): with (yield self.client.connect(True, ioloop=self.io_loop)) as conn: entry = LDAPEntry("cn=async_test,%s" % self.basedn) entry['objectclass'] = ['top', 'inetOrgPerson', 'person', 'organizationalPerson'] entry['sn'] = "async_test" try: yield conn.add(entry) except bonsai.errors.AlreadyExists: yield conn.delete(entry.dn) yield conn.add(entry) except: self.fail("Unexcepected error.") res = yield conn.search() self.assertIn(entry, res) yield entry.delete() res = yield conn.search() self.assertNotIn(entry, res) @gen_test(timeout=20.0) def test_recursive_delete(self): org1 = bonsai.LDAPEntry("ou=testusers,%s" % self.basedn) org1.update({"objectclass" : ['organizationalUnit', 'top'], "ou" : "testusers"}) org2 = bonsai.LDAPEntry("ou=tops,ou=testusers,%s" % self.basedn) org2.update({"objectclass" : ['organizationalUnit', 'top'], "ou" : "tops"}) entry = bonsai.LDAPEntry("cn=tester,ou=tops,ou=testusers,%s" % self.basedn) entry.update({"objectclass" : ["top", "inetorgperson"], "cn" : "tester", "sn" : "example"}) try: with (yield self.client.connect(True, timeout=10.0, ioloop=self.io_loop)) as conn: yield conn.add(org1) yield conn.add(org2) yield conn.add(entry) try: yield conn.delete(org1.dn) except bonsai.LDAPError as exc: self.assertIsInstance(exc, bonsai.errors.NotAllowedOnNonleaf) yield conn.delete(org1.dn, recursive=True) res = yield conn.search(org1.dn, 2) self.assertListEqual(res, []) except bonsai.LDAPError as err: self.fail("Recursive delete is failed: %s" % err) @gen_test(timeout=20.0) def test_modify_and_rename(self): with (yield self.client.connect(True, ioloop=self.io_loop)) as conn: entry = LDAPEntry("cn=async_test,%s" % self.basedn) entry['objectclass'] = ['top', 'inetOrgPerson', 'person', 'organizationalPerson'] entry['sn'] = "async_test" oldname = "cn=async_test,%s" % self.basedn newname = "cn=async_test2,%s" % self.basedn res = yield conn.search(newname, 0) if res: yield res[0].delete() try: yield conn.add(entry) except bonsai.errors.AlreadyExists: yield conn.delete(entry.dn) yield conn.add(entry) except: self.fail("Unexcepected error.") entry['sn'] = "async_test2" yield entry.modify() yield entry.rename(newname) res = yield conn.search(entry.dn, 0, attrlist=['sn']) self.assertEqual(entry['sn'], res[0]['sn']) res = yield conn.search(oldname, 0) self.assertEqual(res, []) yield conn.delete(entry.dn) @gen_test(timeout=20.0) def test_obj_err(self): entry = LDAPEntry("cn=async_test,%s" % self.basedn) entry['cn'] = ['async_test'] try: with (yield self.client.connect(True,ioloop=self.io_loop)) as conn: yield conn.add(entry) except bonsai.errors.ObjectClassViolation: return except Exception as exc: self.fail("test_obj_err failed with %s" % exc) self.fail("test_obj_err failed without the right exception.") @gen_test(timeout=20.0) def test_whoami(self): """ Test whoami. """ with (yield self.client.connect(True, ioloop=self.io_loop)) as conn: obj = yield conn.whoami() expected_res = ["dn:%s" % self.cfg["SIMPLEAUTH"]["user"], self.cfg["SIMPLEAUTH"]["adusername"]] self.assertIn(obj, expected_res) @gen_test(timeout=12.0) def test_connection_timeout(self): import xmlrpc.client as rpc proxy = rpc.ServerProxy("http://%s:%d/" % (self.ipaddr, 8000)) proxy.set_delay(6.0) time.sleep(3.0) try: conn = yield self.client.connect(True, ioloop=self.io_loop, timeout=8.0) except Exception as exc: self.assertIsInstance(exc, gen.TimeoutError) else: self.fail("Failed to receive TimeoutError.") finally: proxy.remove_delay() @gen_test(timeout=18.0) def test_search_timeout(self): import xmlrpc.client as rpc with (yield self.client.connect(True, ioloop=self.io_loop)) as conn: proxy = rpc.ServerProxy("http://%s:%d/" % (self.ipaddr, 8000)) proxy.set_delay(5.1) time.sleep(3.0) try: res = yield conn.search(timeout=4.0) except Exception as exc: self.assertIsInstance(exc, gen.TimeoutError) else: self.fail("Failed to receive TimeoutError.") finally: proxy.remove_delay()
class TornadoLDAPConnectionTest(TestCaseClass): """ Test TornadoLDAPConnection object. """ def setUp(self): """ Set LDAP URL and open connection. """ self.cfg = get_config() self.url = "ldap://%s:%s/%s?%s?%s" % ( self.cfg["SERVER"]["hostip"], self.cfg["SERVER"]["port"], self.cfg["SERVER"]["basedn"], self.cfg["SERVER"]["search_attr"], self.cfg["SERVER"]["search_scope"], ) self.basedn = self.cfg["SERVER"]["basedn"] self.ipaddr = self.cfg["SERVER"]["hostip"] self.client = LDAPClient(self.url) self.client.set_credentials( "SIMPLE", user=self.cfg["SIMPLEAUTH"]["user"], password=self.cfg["SIMPLEAUTH"]["password"], ) self.client.set_async_connection_class(TornadoLDAPConnection) self.io_loop = self.get_new_ioloop() @gen_test(timeout=20.0) def test_connection(self): """ Test opening a connection. """ conn = yield self.client.connect(True, ioloop=self.io_loop) assert conn is not None assert not conn.closed conn.close() @gen_test(timeout=20.0) def test_search(self): """ Test search. """ with (yield self.client.connect(True, ioloop=self.io_loop)) as conn: res = yield conn.search() assert res is not None @gen_test(timeout=20.0) def test_add_and_delete(self): """ Test addding and deleting an LDAP entry. """ with (yield self.client.connect(True, ioloop=self.io_loop)) as conn: entry = LDAPEntry("cn=async_test,%s" % self.basedn) entry["objectclass"] = [ "top", "inetOrgPerson", "person", "organizationalPerson", ] entry["sn"] = "async_test" try: yield conn.add(entry) except bonsai.errors.AlreadyExists: yield conn.delete(entry.dn) yield conn.add(entry) except: self.fail("Unexpected error.") res = yield conn.search() assert entry in res yield entry.delete() res = yield conn.search() assert entry not in res @gen_test(timeout=20.0) def test_recursive_delete(self): """ Test removing a subtree recursively. """ org1 = bonsai.LDAPEntry("ou=testusers,%s" % self.basedn) org1.update({"objectclass": ["organizationalUnit", "top"], "ou": "testusers"}) org2 = bonsai.LDAPEntry("ou=tops,ou=testusers,%s" % self.basedn) org2.update({"objectclass": ["organizationalUnit", "top"], "ou": "tops"}) entry = bonsai.LDAPEntry("cn=tester,ou=tops,ou=testusers,%s" % self.basedn) entry.update( {"objectclass": ["top", "inetorgperson"], "cn": "tester", "sn": "example"} ) try: with ( yield self.client.connect(True, timeout=10.0, ioloop=self.io_loop) ) as conn: yield conn.add(org1) yield conn.add(org2) yield conn.add(entry) with pytest.raises(bonsai.errors.NotAllowedOnNonleaf): yield conn.delete(org1.dn) yield conn.delete(org1.dn, recursive=True) res = yield conn.search(org1.dn, 2) assert res == [] except bonsai.LDAPError as err: self.fail("Recursive delete is failed: %s" % err) @gen_test(timeout=20.0) def test_modify_and_rename(self): """ Test modifying and renaming an LDAP entry. """ with (yield self.client.connect(True, ioloop=self.io_loop)) as conn: entry = LDAPEntry("cn=async_test,%s" % self.basedn) entry["objectclass"] = [ "top", "inetOrgPerson", "person", "organizationalPerson", ] entry["sn"] = "async_test" oldname = "cn=async_test,%s" % self.basedn newname = "cn=async_test2,%s" % self.basedn res = yield conn.search(newname, 0) if res: yield res[0].delete() try: yield conn.add(entry) except bonsai.errors.AlreadyExists: yield conn.delete(entry.dn) yield conn.add(entry) except: self.fail("Unexpected error.") entry["sn"] = "async_test2" yield entry.modify() yield entry.rename(newname) res = yield conn.search(entry.dn, 0, attrlist=["sn"]) assert entry["sn"] == res[0]["sn"] res = yield conn.search(oldname, 0) assert res == [] yield conn.delete(entry.dn) @gen_test(timeout=20.0) def test_obj_err(self): """ Test object class violation error. """ entry = LDAPEntry("cn=async_test,%s" % self.basedn) entry["cn"] = ["async_test"] with (yield self.client.connect(True, ioloop=self.io_loop)) as conn: with pytest.raises(bonsai.errors.ObjectClassViolation): yield conn.add(entry) @gen_test(timeout=20.0) def test_whoami(self): """ Test whoami. """ with (yield self.client.connect(True, ioloop=self.io_loop)) as conn: obj = yield conn.whoami() expected_res = [ "dn:%s" % self.cfg["SIMPLEAUTH"]["user"], self.cfg["SIMPLEAUTH"]["adusername"], ] assert obj in expected_res @gen_test(timeout=12.0) def test_connection_timeout(self): """ Test connection timeout. """ with network_delay(7.0): with pytest.raises(gen.TimeoutError): yield self.client.connect(True, ioloop=self.io_loop, timeout=8.0) @gen_test(timeout=18.0) def test_search_timeout(self): """ Test search timeout. """ with (yield self.client.connect(True, ioloop=self.io_loop)) as conn: with network_delay(7.0): with pytest.raises(gen.TimeoutError): yield conn.search(timeout=3.0) @pytest.mark.skipif( sys.version_info.minor < 5, reason="No __aiter__ and __anext__ methods under 3.5.", ) @gen_test(timeout=20.0) def test_paged_search(self): """ Test paged search. """ search_dn = "ou=nerdherd,%s" % self.basedn with (yield self.client.connect(True, ioloop=self.io_loop)) as conn: # To keep compatibility with 3.4 it does not uses async for, # but its while loop equivalent. res_iter = yield conn.paged_search(search_dn, 1, page_size=3) res_iter = type(res_iter).__aiter__(res_iter) cnt = 0 while True: try: res = yield type(res_iter).__anext__(res_iter) assert isinstance(res, LDAPEntry) cnt += 1 except StopAsyncIteration: break assert cnt == 6
class TornadoLDAPConnectionTest(TestCaseClass): """ Test TornadoLDAPConnection object. """ def setUp(self): """ Set LDAP URL and open connection. """ curdir = os.path.abspath(os.path.dirname(__file__)) self.cfg = configparser.ConfigParser() self.cfg.read(os.path.join(curdir, 'test.ini')) self.url = "ldap://%s:%s/%s?%s?%s" % ( self.cfg["SERVER"]["hostip"], self.cfg["SERVER"]["port"], self.cfg["SERVER"]["basedn"], self.cfg["SERVER"]["search_attr"], self.cfg["SERVER"]["search_scope"]) self.basedn = self.cfg["SERVER"]["basedn"] self.ipaddr = self.cfg["SERVER"]["hostip"] self.client = LDAPClient(self.url) self.client.set_credentials("SIMPLE", (self.cfg["SIMPLEAUTH"]["user"], self.cfg["SIMPLEAUTH"]["password"])) self.client.set_async_connection_class(TornadoLDAPConnection) self.io_loop = self.get_new_ioloop() @gen_test(timeout=20.0) def test_connection(self): """ Test opening a connection. """ conn = yield self.client.connect(True, ioloop=self.io_loop) self.assertIsNotNone(conn) self.assertFalse(conn.closed) conn.close() @gen_test(timeout=20.0) def test_search(self): """ Test search. """ with (yield self.client.connect(True, ioloop=self.io_loop)) as conn: res = yield conn.search() self.assertIsNotNone(res) @gen_test(timeout=20.0) def test_add_and_delete(self): """ Test addding and deleting an LDAP entry. """ with (yield self.client.connect(True, ioloop=self.io_loop)) as conn: entry = LDAPEntry("cn=async_test,%s" % self.basedn) entry['objectclass'] = [ 'top', 'inetOrgPerson', 'person', 'organizationalPerson' ] entry['sn'] = "async_test" try: yield conn.add(entry) except bonsai.errors.AlreadyExists: yield conn.delete(entry.dn) yield conn.add(entry) except: self.fail("Unexpected error.") res = yield conn.search() self.assertIn(entry, res) yield entry.delete() res = yield conn.search() self.assertNotIn(entry, res) @gen_test(timeout=20.0) def test_recursive_delete(self): """ Test removing a subtree recursively. """ org1 = bonsai.LDAPEntry("ou=testusers,%s" % self.basedn) org1.update({ "objectclass": ['organizationalUnit', 'top'], "ou": "testusers" }) org2 = bonsai.LDAPEntry("ou=tops,ou=testusers,%s" % self.basedn) org2.update({ "objectclass": ['organizationalUnit', 'top'], "ou": "tops" }) entry = bonsai.LDAPEntry("cn=tester,ou=tops,ou=testusers,%s" % self.basedn) entry.update({ "objectclass": ["top", "inetorgperson"], "cn": "tester", "sn": "example" }) try: with (yield self.client.connect(True, timeout=10.0, ioloop=self.io_loop)) as conn: yield conn.add(org1) yield conn.add(org2) yield conn.add(entry) try: yield conn.delete(org1.dn) except bonsai.LDAPError as exc: self.assertIsInstance(exc, bonsai.errors.NotAllowedOnNonleaf) yield conn.delete(org1.dn, recursive=True) res = yield conn.search(org1.dn, 2) self.assertListEqual(res, []) except bonsai.LDAPError as err: self.fail("Recursive delete is failed: %s" % err) @gen_test(timeout=20.0) def test_modify_and_rename(self): """ Test modifying and renaming an LDAP entry. """ with (yield self.client.connect(True, ioloop=self.io_loop)) as conn: entry = LDAPEntry("cn=async_test,%s" % self.basedn) entry['objectclass'] = [ 'top', 'inetOrgPerson', 'person', 'organizationalPerson' ] entry['sn'] = "async_test" oldname = "cn=async_test,%s" % self.basedn newname = "cn=async_test2,%s" % self.basedn res = yield conn.search(newname, 0) if res: yield res[0].delete() try: yield conn.add(entry) except bonsai.errors.AlreadyExists: yield conn.delete(entry.dn) yield conn.add(entry) except: self.fail("Unexpected error.") entry['sn'] = "async_test2" yield entry.modify() yield entry.rename(newname) res = yield conn.search(entry.dn, 0, attrlist=['sn']) self.assertEqual(entry['sn'], res[0]['sn']) res = yield conn.search(oldname, 0) self.assertEqual(res, []) yield conn.delete(entry.dn) @gen_test(timeout=20.0) def test_obj_err(self): """ Test object class violation error. """ entry = LDAPEntry("cn=async_test,%s" % self.basedn) entry['cn'] = ['async_test'] try: with (yield self.client.connect(True, ioloop=self.io_loop)) as conn: yield conn.add(entry) except bonsai.errors.ObjectClassViolation: return except Exception as exc: self.fail("test_obj_err failed with %s" % exc) self.fail("test_obj_err failed without the right exception.") @gen_test(timeout=20.0) def test_whoami(self): """ Test whoami. """ with (yield self.client.connect(True, ioloop=self.io_loop)) as conn: obj = yield conn.whoami() expected_res = [ "dn:%s" % self.cfg["SIMPLEAUTH"]["user"], self.cfg["SIMPLEAUTH"]["adusername"] ] self.assertIn(obj, expected_res) @gen_test(timeout=12.0) def test_connection_timeout(self): """ Test connection timeout. """ import xmlrpc.client as rpc proxy = rpc.ServerProxy("http://%s:%d/" % (self.ipaddr, 8000)) proxy.set_delay(7.0) time.sleep(3.0) try: yield self.client.connect(True, ioloop=self.io_loop, timeout=8.0) except Exception as exc: self.assertIsInstance(exc, gen.TimeoutError) else: self.fail("Failed to receive TimeoutError.") finally: proxy.remove_delay() @gen_test(timeout=18.0) def test_search_timeout(self): """ Test search timeout. """ import xmlrpc.client as rpc with (yield self.client.connect(True, ioloop=self.io_loop)) as conn: proxy = rpc.ServerProxy("http://%s:%d/" % (self.ipaddr, 8000)) proxy.set_delay(7.0) time.sleep(3.0) try: yield conn.search(timeout=4.0) except Exception as exc: self.assertIsInstance(exc, gen.TimeoutError) else: self.fail("Failed to receive TimeoutError.") finally: proxy.remove_delay() @gen_test(timeout=20.0) def test_paged_search(self): """ Test paged search. """ if sys.version_info.minor < 5: self.skipTest("No __aiter__ and __anext__ methods under 3.5.") search_dn = "ou=nerdherd,%s" % self.basedn with (yield self.client.connect(True, ioloop=self.io_loop)) as conn: # To keep compatibility with 3.4 it does not uses async for, # but its while loop equivalent. res_iter = yield conn.search(search_dn, 1, page_size=3) res_iter = type(res_iter).__aiter__(res_iter) cnt = 0 while True: try: res = yield type(res_iter).__anext__(res_iter) self.assertIsInstance(res, LDAPEntry) cnt += 1 except StopAsyncIteration: break self.assertEqual(cnt, 6)
class TornadoLDAPConnectionTest(TestCaseClass): """ Test TornadoLDAPConnection object. """ def setUp(self): """ Set LDAP URL and open connection. """ curdir = os.path.abspath(os.path.dirname(__file__)) self.cfg = configparser.ConfigParser() self.cfg.read(os.path.join(curdir, 'test.ini')) self.url = "ldap://%s:%s/%s?%s?%s" % (self.cfg["SERVER"]["hostip"], \ self.cfg["SERVER"]["port"], \ self.cfg["SERVER"]["basedn"], \ self.cfg["SERVER"]["search_attr"], \ self.cfg["SERVER"]["search_scope"]) self.basedn = self.cfg["SERVER"]["basedn"] self.client = LDAPClient(self.url) self.client.set_credentials("SIMPLE", (self.cfg["SIMPLEAUTH"]["user"], self.cfg["SIMPLEAUTH"]["password"])) self.client.set_async_connection_class(TornadoLDAPConnection) self.io_loop = self.get_new_ioloop() @gen_test def test_connection(self): conn = yield self.client.connect(True, ioloop=self.io_loop) self.assertIsNotNone(conn) self.assertFalse(conn.closed) conn.close() @gen_test def test_search(self): with (yield self.client.connect(True, ioloop=self.io_loop)) as conn: res = yield conn.search() self.assertIsNotNone(res) @gen_test def test_add_and_delete(self): with (yield self.client.connect(True, ioloop=self.io_loop)) as conn: entry = LDAPEntry("cn=async_test,%s" % self.basedn) entry['objectclass'] = [ 'top', 'inetOrgPerson', 'person', 'organizationalPerson' ] entry['sn'] = "async_test" try: yield conn.add(entry) except bonsai.errors.AlreadyExists: yield conn.delete(entry.dn) yield conn.add(entry) except: self.fail("Unexcepected error.") res = yield conn.search() self.assertIn(entry, res) yield entry.delete() res = yield conn.search() self.assertNotIn(entry, res) @gen_test def test_modify_and_rename(self): with (yield self.client.connect(True, ioloop=self.io_loop)) as conn: entry = LDAPEntry("cn=async_test,%s" % self.basedn) entry['objectclass'] = [ 'top', 'inetOrgPerson', 'person', 'organizationalPerson' ] entry['sn'] = "async_test" oldname = "cn=async_test,%s" % self.basedn newname = "cn=async_test2,%s" % self.basedn res = yield conn.search(newname, 0) if res: yield res[0].delete() try: yield conn.add(entry) except bonsai.errors.AlreadyExists: yield conn.delete(entry.dn) yield conn.add(entry) except: self.fail("Unexcepected error.") entry['sn'] = "async_test2" yield entry.modify() yield entry.rename(newname) res = yield conn.search(entry.dn, 0, attrlist=['sn']) self.assertEqual(entry['sn'], res[0]['sn']) res = yield conn.search(oldname, 0) self.assertEqual(res, []) yield conn.delete(entry.dn) @gen_test def test_obj_err(self): entry = LDAPEntry("cn=async_test,%s" % self.basedn) entry['objectclass'] = [ 'top', 'inetOrgPerson', 'person', 'organizationalPerson' ] try: with (yield self.client.connect(True, ioloop=self.io_loop)) as conn: yield conn.add(entry) except bonsai.errors.ObjectClassViolation: return except Exception as exc: self.fail("test_obj_err failed with %s" % exc) self.fail("test_obj_err failed without the right exception.") @gen_test def test_whoami(self): """ Test whoami. """ with (yield self.client.connect(True, ioloop=self.io_loop)) as conn: obj = yield conn.whoami() expected_res = "dn:%s" % self.cfg["SIMPLEAUTH"]["user"] self.assertEqual(obj, expected_res)