def test_keys(): """ Test LDAPEntry's keys method. """ entry = LDAPEntry("cn=test") entry["cn"] = "test" entry["sn"] = "Test" assert set(entry.keys()) == set(["dn", "cn", "sn"]) assert set(entry.keys(exclude_dn=True)) == set(["cn", "sn"])
def test_modify_and_rename(self): """ Test modifying and renaming LDAP entry. """ with (yield from self.client.connect(True)) 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 from conn.search(newname, 0) if res: yield from res[0].delete() try: yield from conn.add(entry) except bonsai.errors.AlreadyExists: yield from conn.delete(entry.dn) yield from conn.add(entry) except: self.fail("Unexpected error.") entry['sn'] = "async_test2" yield from entry.modify() yield from entry.rename(newname) res = yield from conn.search(entry.dn, 0, attrlist=['sn']) self.assertEqual(entry['sn'], res[0]['sn']) res = yield from conn.search(oldname, 0) self.assertEqual(res, []) yield from conn.delete(entry.dn)
def test_modify_and_rename(gclient, basedn): """ Test modifying and renaming LDAP entry. """ with gclient.connect(True) as conn: entry = LDAPEntry("cn=async_test,%s" % basedn) entry["objectclass"] = [ "top", "inetOrgPerson", "person", "organizationalPerson", ] entry["sn"] = "async_test" oldname = "cn=async_test,%s" % basedn newname = "cn=async_test2,%s" % basedn res = conn.search(newname, 0) if res: res[0].delete() try: conn.add(entry) except bonsai.errors.AlreadyExists: conn.delete(entry.dn) conn.add(entry) except: pytest.fail("Unexpected error.") entry["sn"] = "async_test2" entry.modify() entry.rename(newname) res = conn.search(entry.dn, 0, attrlist=["sn"]) assert entry["sn"] == res[0]["sn"] res = conn.search(oldname, 0) assert res == [] conn.delete(entry.dn)
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)
def test_write_entries(): """ Test writing multiple entries into the same output. """ ent0 = LDAPEntry("cn=test0") ent0["cn"] = "test0" ent1 = LDAPEntry("cn=test1") ent1["cn"] = "test1" entries = (ent0, ent1) with StringIO() as out: ldif = LDIFWriter(out) ldif.write_entries(entries, write_version=False) content = out.getvalue() assert "dn: {0}".format(ent0.dn) in content assert "dn: {0}".format(ent1.dn) in content assert "cn: {0}".format(ent0["cn"][0]) in content assert "cn: {0}".format(ent1["cn"][0]) in content assert "version" not in content with StringIO() as out: ldif = LDIFWriter(out) ldif.write_entries(entries) content = out.getvalue() assert "dn: {0}".format(ent0.dn) in content assert "dn: {0}".format(ent1.dn) in content assert "version: 1" == content.split("\n")[0]
def test_sync_operations(self): """ Test LDAPEntry's add, modify and delete synchronous operations. """ entry = LDAPEntry("cn=test,%s" % self.basedn) self.client.set_credentials(*self.creds) with self.client.connect() as conn: entry['sn'] = 'test' self.assertRaises(bonsai.ObjectClassViolation, lambda: conn.add(entry)) entry['objectclass'] = ['top', 'inetOrgPerson', 'person', 'organizationalPerson'] try: conn.add(entry) except bonsai.AlreadyExists: conn.delete(entry.dn) conn.add(entry) except: self.fail("Adding LDAPEntry to the server is failed.") entry['sn'] = "Test_modify" try: entry.modify() except: self.fail("Modify failed.") obj = conn.search("cn=test,%s" % self.basedn, 0)[0] self.assertEqual(entry['sn'], obj['sn']) try: entry.delete() except: self.fail("Delete failed.")
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)
def test_clear(self): """ Test LDAPEntry's clear method. """ entry = LDAPEntry("cn=test") entry['sn'] = ['test1', 'test2'] entry['gn'] = ['test3'] entry.clear() self.assertDictEqual(entry, {}) self.assertEqual(entry.dn, "cn=test")
def test_clear(): """ Test LDAPEntry's clear method. """ entry = LDAPEntry("cn=test") entry["sn"] = ["test1", "test2"] entry["gn"] = ["test3"] entry.clear() assert entry == {"dn": LDAPDN("cn=test")} assert entry.dn == "cn=test"
def test_equal(self): """ Test equality check. """ entry1 = LDAPEntry("cn=test") entry2 = LDAPEntry("cn=test") entry3 = LDAPEntry("cn=test1") self.assertTrue(entry1 == entry2) self.assertFalse(entry1 == entry3) self.assertTrue(entry1 == dict()) self.assertFalse(entry1 == 2)
def test_connection(self): """ Test set and get connection object form LDAPEntry. """ entry = LDAPEntry("cn=test,%s" % self.basedn) conn = self.client.connect() entry.connection = conn self.assertEqual(entry.connection, conn) def invalid_assign(): entry.connection = "string" self.assertRaises(TypeError, invalid_assign)
def test_dn_attr(basedn): """ Test LDAPEntry's DN attribute. """ entry = LDAPEntry("cn=test,%s" % basedn) entry.dn = "cn=test" assert str(entry.dn) == "cn=test" with pytest.raises(TypeError): del entry.dn with pytest.raises(TypeError): entry["dn"] = 5
def test_equal(): """ Test equality check. """ entry1 = LDAPEntry("cn=test") entry2 = LDAPEntry("cn=test") entry3 = LDAPEntry("cn=test1") assert entry1 == entry2 assert not (entry1 == entry3) assert entry1 == {"dn": LDAPDN("cn=test")} assert not (entry1 == 2)
def test_popitem(): """ Test LDAPEntry's popitem method. """ entry = LDAPEntry("cn=test") entry["test"] = "test" entry["test2"] = "test" item = entry.popitem() assert len(item) == 2 assert item[0] not in entry entry[item[0]] = item[1] assert entry[item[0]] == item[1]
def test_popitem(self): """ Test LDAPEntry's popitem method. """ entry = LDAPEntry("cn=test") entry['test'] = "test" entry['test2'] = 'test' item = entry.popitem() self.assertEqual(len(item), 2) self.assertNotIn(item[0], entry) entry[item[0]] = item[1] self.assertEqual(entry[item[0]], item[1])
def test_special_char(client, basedn): """ Test adding entry with special character in its DN. """ with client.connect() as conn: entry = LDAPEntry(r"cn=test\, *\+withspec,%s" % basedn) entry["objectclass"] = ["top", "inetOrgPerson"] entry["sn"] = "Test,*special" conn.add(entry) result = conn.search(basedn, 1) entry.delete() assert entry.dn in [res.dn for res in result]
def test_dn_attr(self): """ Test LDAPEntry's DN attribute. """ entry = LDAPEntry("cn=test,%s" % self.basedn) def remove_dn(): del entry.dn def set_dn(): entry['dn'] = 5 entry.dn = "cn=test" self.assertEqual(str(entry.dn), "cn=test") self.assertRaises(TypeError, remove_dn) self.assertRaises(TypeError, set_dn)
def test_unicode(client, basedn): """ Test adding entry with special character in its DN. """ with client.connect() as conn: dname = "cn=test_µčབྷñ,%s" % basedn entry = LDAPEntry(dname) entry["objectclass"] = ["top", "inetOrgPerson"] entry["sn"] = "unicode_µčབྷñ" conn.add(entry) result = conn.search(dname, 0) entry.delete() assert dname in [res.dn for res in result]
def test_set_get(): """ Test LDAPEntry's SetItem, GetItem and get methods. """ entry = LDAPEntry("cn=test") entry["sn"] = "Test" assert entry == {"dn": LDAPDN("cn=test"), "sn": ["Test"]} entry["givenname"] = "Test" assert entry.get("None") is None assert entry.get("GivenName") == entry["givenNAME"] del entry["sn"] with pytest.raises(KeyError): _ = entry["sn"]
def test_connection(client, basedn): """ Test set and get connection object from LDAPEntry. """ entry = LDAPEntry("cn=test,%s" % basedn) with pytest.raises(ValueError): _ = entry.connection conn = client.connect() entry.connection = conn assert entry.connection == conn with pytest.raises(TypeError): entry.connection = "string" with pytest.raises(TypeError): del entry.connection
def test_set_get(self): """ Test LDAPEntry's SetItem, GetItem and get methods. """ entry = LDAPEntry("cn=test") entry['sn'] = 'Test' self.assertDictEqual(entry, {'sn': ['Test']}, "LDAPEntry set is failed.") entry['givenname'] = 'Test' self.assertEqual(entry.get("None"), None, "LDAPEntry get is failed.") self.assertListEqual(entry.get("GivenName"), entry['givenNAME'], "LDAPEntry get is failed.") del entry['sn'] self.assertRaises(KeyError, lambda: entry['sn'])
def test_special_char(self): """ Test adding entry with special character in its DN. """ self.client.set_credentials(*self.creds) conn = self.client.connect() entry = LDAPEntry("cn=test\, *\+withspec,%s" % self.basedn) entry['objectclass'] = ['top', 'inetOrgPerson'] entry['sn'] = "Test,*special" conn.add(entry) result = conn.search(self.basedn, 1) entry.delete() conn.close() self.assertIn(entry.dn, [res.dn for res in result])
def test_update(): """ Test updating LDAPEntry object. """ entry = LDAPEntry("cn=test") entry.update({"GivenName": "test2", "mail": "test@mail"}) entry.update([("sn", "test")]) with pytest.raises(ValueError): entry.update([("sn", "test", 1)]) entry.update(uidnumber=1, gidnumber=1) assert entry["mail"] == ["test@mail"] assert entry["givenname"] == ["test2"] assert entry["sn"][0] == "test" assert entry["uidnumber"] == [1] assert entry["gidnumber"] == [1]
def test_rename(self): """ Test LDAPEntry's rename LDAP operation. """ entry = LDAPEntry("cn=test,%s" % self.basedn) self.client.set_credentials(*self.creds) with self.client.connect() as conn: self._add_for_renaming(conn, entry) entry.rename("cn=test2,%s" % self.basedn) self.assertEqual(str(entry.dn), "cn=test2,%s" % self.basedn) obj = conn.search("cn=test,%s" % self.basedn, 0) self.assertEqual(obj, []) obj = conn.search("cn=test2,%s" % self.basedn, 0)[0] self.assertEqual(entry.dn, obj.dn) entry.delete()
def test_unicode(self): """ Test adding entry with special character in its DN. """ self.client.set_credentials(*self.creds) conn = self.client.connect() dname = "cn=test_µčབྷñ,%s" % self.basedn entry = LDAPEntry(dname) entry['objectclass'] = ['top', 'inetOrgPerson'] entry['sn'] = "unicode_µčབྷñ" conn.add(entry) result = conn.search(dname, 0) entry.delete() conn.close() self.assertIn(dname, [res.dn for res in result])
def test_set_get(self): """ Test LDAPEntry's SetItem, GetItem and get methods. """ entry = LDAPEntry("cn=test") entry['sn'] = 'Test' self.assertDictEqual(entry, {'sn' : ['Test']}, "LDAPEntry set is failed.") entry['givenname'] = 'Test' self.assertEqual(entry.get("None"), None, "LDAPEntry get is failed.") self.assertListEqual(entry.get("GivenName"), entry['givenNAME'], "LDAPEntry get is failed.") del entry['sn'] self.assertRaises(KeyError, lambda: entry['sn'])
def test_rename_error(self): """ Test LDAPEntry's rename error handling. """ dname = bonsai.LDAPDN("cn=test,%s" % self.basedn) entry = LDAPEntry(dname) self.client.set_credentials(*self.creds) with self.client.connect() as conn: self._add_for_renaming(conn, entry) try: newdn = bonsai.LDAPDN("cn=test2,ou=invalid,%s" % self.basedn) entry.rename(newdn) except bonsai.LDAPError: self.assertEqual(entry.dn, dname) finally: conn.delete(dname)
def test_write_changes(): """ Test writing LDIF changes of an LDAP Entry. """ ent = LDAPEntry("cn=test") ent["cn"] = "test" ent["sn"] = ["sntest1", "sntest2"] ent.change_attribute("givenName", LDAPModOp.REPLACE, "test") ent.change_attribute("uidNumber", LDAPModOp.DELETE, 0) ent.change_attribute("gidNumber", LDAPModOp.DELETE) with StringIO() as out: ldif = LDIFWriter(out) ldif.write_changes(ent) content = out.getvalue() lines = content.split("\n") assert "dn: {0}".format(ent.dn) == lines.pop(0) # First line. assert "changetype: modify" == lines.pop(0) # Second line. assert "add: cn" in lines assert "cn: {0}".format(ent["cn"][0]) == lines[lines.index("add: cn") + 1] assert "add: sn" in lines assert set(ent["sn"]) == {lin.split("sn: ")[1] for lin in lines if "sn: " in lin} assert "replace: givenName" in lines assert ( "givenName: {0}".format(ent["givenName"][0]) == lines[lines.index("replace: givenName") + 1] ) assert "delete: uidNumber" in lines assert "uidNumber: 0" == lines[lines.index("delete: uidNumber") + 1] assert "delete: gidNumber" in lines # Remove the key entirely. assert "-" == lines[lines.index("delete: gidNumber") + 1]
def test_binary(client, basedn): """ Test adding binary data. """ curdir = os.path.abspath(os.path.dirname(__file__)) conn = client.connect() dname = "cn=binary,%s" % basedn entry = LDAPEntry(dname) entry["objectclass"] = ["top", "inetOrgPerson"] entry["sn"] = "binary_test" with open("%s/testenv/test.jpeg" % curdir, "rb") as image: entry["jpegPhoto"] = image.read() conn.add(entry) result = conn.search(dname, 0) entry.delete() conn.close() assert "jpegPhoto" in result[0].keys() assert result[0]["jpegphoto"][0] == entry["jpegphoto"][0]
def test_modify_referrals(self): """ Test modifying an LDAP referral with ManageDdsIT control. """ refdn = bonsai.LDAPDN("o=invalid-ref,ou=nerdherd,dc=bonsai,dc=test") newref = "ldap://invalid.host/cn=nobody" cli = LDAPClient(self.client.url) cli.set_credentials(*self.creds) cli.managedsait = True with cli.connect() as conn: entry = LDAPEntry(refdn, conn) entry.change_attribute("ref", LDAPModOp.ADD, newref) entry.modify() res = conn.search(refdn, 0, attrlist=['ref'])[0] self.assertEqual(len(res['ref']), 3) self.assertIn(newref, res['ref']) entry.change_attribute("ref", LDAPModOp.DELETE, newref) entry.modify()
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)
def test_modify_referrals(client): """ Test modifying an LDAP referral with ManageDdsIT control. """ refdn = bonsai.LDAPDN("o=invalid-ref,ou=nerdherd,dc=bonsai,dc=test") newref = "ldap://invalid.host/cn=nobody" cli = LDAPClient(client.url) cli.set_credentials(client.mechanism, **client.credentials) cli.managedsait = True with cli.connect() as conn: entry = LDAPEntry(refdn, conn) entry.change_attribute("ref", LDAPModOp.ADD, newref) entry.modify() res = conn.search(refdn, 0, attrlist=["ref"])[0] assert len(res["ref"]) == 3 assert newref in res["ref"] entry.change_attribute("ref", LDAPModOp.DELETE, newref) entry.modify()
async def test_obj_err(client, basedn): """ Test object class violation error. """ entry = LDAPEntry("cn=async_test,%s" % basedn) entry["cn"] = ["async_test"] with pytest.raises(bonsai.errors.ObjectClassViolation): async with client.connect(True) as conn: await conn.add(entry)
async def test_modify_and_rename(client, basedn): """ Test modifying and renaming LDAP entry. """ async with client.connect(True) as conn: entry = LDAPEntry("cn=async_test,%s" % basedn) entry["objectclass"] = [ "top", "inetOrgPerson", "person", "organizationalPerson", ] entry["sn"] = "async_test" oldname = "cn=async_test,%s" % basedn newname = "cn=async_test2,%s" % basedn res = await conn.search(newname, 0) if res: await res[0].delete() try: await conn.add(entry) except bonsai.errors.AlreadyExists: await conn.delete(entry.dn) await conn.add(entry) except: pytest.fail("Unexpected error.") entry["sn"] = "async_test2" await entry.modify() await entry.rename(newname) res = await conn.search(entry.dn, 0, attrlist=["sn"]) assert entry["sn"] == res[0]["sn"] res = await conn.search(oldname, 0) assert res == [] await conn.delete(entry.dn)
def test_write_entry(): """ Test serialising an LDAP entry. """ ent = LDAPEntry("cn=test") ent["cn"] = "test" ent["jpegPhoto"] = b"1223122130008283938282931232" ent["sn"] = "test😊" ent["sn"].append(" test2") with StringIO() as out: ldif = LDIFWriter(out, max_length=32) ldif.write_entry(ent) content = out.getvalue() contlines = content.split("\n") surnames = { b64decode(line.split(":: ")[1]).decode("UTF-8") for line in contlines if "sn" in line } jpeg_lines = [] for idx, line in enumerate(contlines): if "jpegPhoto::" in line: jpeg_lines.append(line.split(" ")[1]) jpeg_lines.append(contlines[idx + 1][1:]) jpegPhoto = b64decode("".join(jpeg_lines)) assert all(len(line) <= 32 for line in contlines) assert "dn: {0}".format(ent.dn) == contlines[0] assert "cn: {0}\n".format(ent["cn"][0]) in content assert content.count("sn:: ") == 2 assert surnames == set(ent["sn"]) assert content.count("jpegPhoto:: ") == 1 assert jpegPhoto == ent["jpegPhoto"][0]
def test_binary(self): """ Test adding binary data. """ curdir = os.path.abspath(os.path.dirname(__file__)) self.client.set_credentials(*self.creds) conn = self.client.connect() dname = "cn=binary,%s" % self.basedn entry = LDAPEntry(dname) entry['objectclass'] = ['top', 'inetOrgPerson'] entry['sn'] = "binary_test" with open('%s/testenv/test.jpeg' % curdir, 'rb') as image: entry['jpegPhoto'] = image.read() conn.add(entry) result = conn.search(dname, 0) entry.delete() conn.close() self.assertIn("jpegPhoto", result[0].keys()) self.assertEqual(result[0]['jpegphoto'][0], entry['jpegphoto'][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)
def test_update(self): """ Test updating LDAPEntry object. """ entry = LDAPEntry("cn=test") entry.update({"GivenName": "test2", "mail" : "test@mail"}) entry.update([("sn", "test")]) entry.update(uidnumber=1, gidnumber=1) self.assertEqual(entry['mail'], ['test@mail']) self.assertEqual(entry['givenname'], ['test2']) self.assertEqual(entry['sn'][0], 'test') self.assertEqual(entry['uidnumber'], [1]) self.assertEqual(entry['gidnumber'], [1])
def test_clear_attribute_changes(): """ Test clear_attribute_changes method. """ user_dn = "cn=sam,ou=nerdherd,dc=bonsai,dc=test" entry = LDAPEntry(user_dn) entry.change_attribute("uidNumber", 0, 4) assert entry["uidNumber"].added == [4] entry.change_attribute("uidNumber", 1, 4) assert entry["uidNumber"].deleted == [4] entry.clear_attribute_changes("uidNumber") assert entry["uidNumber"].status == 0 assert entry["uidNumber"].added == [] assert entry["uidNumber"].deleted == []
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