diff --git a/CHANGES.rst b/CHANGES.rst new file mode 100644 index 0000000..f786671 --- /dev/null +++ b/CHANGES.rst @@ -0,0 +1,24 @@ +Changelog +--------------- + +0.1.5 ++++++ + +- Override of cidicts __getitem__ so that user.attrs['nonexistent'] won't raise an exception, but instead returns an empty list + +0.1.2 ++++++ + +- README.md to README.rst (pypi should show a nice README as well) + +0.1.1 ++++++ + +- fixed pretty print of binary attribute +- fixed ldap.get sizelimit=1 exception for now +- added try catch to api + +0.1 ++++ + +- Initial version, have to start somewhere \ No newline at end of file diff --git a/CHANGES.txt b/CHANGES.txt deleted file mode 100644 index 53bde43..0000000 --- a/CHANGES.txt +++ /dev/null @@ -1,5 +0,0 @@ -0.1 - initial version -0.1.1 - fixed pretty print of binary attribute - - fixed ldap.get sizelimit=1 exception for now - - added try catch to api -0.1.2 - README.md to README.rst \ No newline at end of file diff --git a/MANIFEST.in b/MANIFEST.in index c20c677..a28d3dc 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,4 @@ -include CHANGES.txt +include CHANGES.rst include LICENSE.txt include MANIFEST.in include README.rst \ No newline at end of file diff --git a/ldappr/connection.py b/ldappr/connection.py index b6f84be..8226d99 100644 --- a/ldappr/connection.py +++ b/ldappr/connection.py @@ -22,7 +22,7 @@ class Connection(object): # TODO: use the escape_filter_chars() and filter_format() functions """Get list of objects that match the search_filter :param search_filter: filter to find the objects - :return: list of LdapperObjects + :return: list of LdapperObjects (or empty list) """ result = self.conn.search_s(self.search_base, ldap.SCOPE_SUBTREE, search_filter) diff --git a/ldappr/ldapprobject.py b/ldappr/ldapprobject.py index 1e6d64f..df0ba6c 100644 --- a/ldappr/ldapprobject.py +++ b/ldappr/ldapprobject.py @@ -2,6 +2,17 @@ import ldap import ldif from ldap.cidict import cidict from StringIO import StringIO +from string import lower + + +class CustomCidict(cidict): + def __getitem__(self, key): + """Override of the __getitem__ method to return an empty list if a key + does not exist (instead of raising an exception) + """ + if lower(key) in self.data: + return self.data[lower(key)] + return [] class LdapprObject(object): @@ -14,14 +25,14 @@ class LdapprObject(object): existing connection. """ (self.dn, self.attributes) = result - self.attrs = cidict(self.attributes) + self.attrs = CustomCidict(self.attributes) self.conn = conn def __str__(self): """Pretty prints all attributes with values.""" col_width = max(len(key) for key in self.attrs.keys()) pretty_string = '{attr:{width}} : {value}\n'.format( - attr='dn', width=col_width, value=self.dn) + attr='dn', width=col_width, value=self.dn) for key, value in self.attrs.iteritems(): if len(str(value[0])) > 80: # hack to 'detect' binary attrs value = ['binary'] diff --git a/ldappr/test/test_ldappr.py b/ldappr/test/test_ldappr.py index 1bab8d8..4bbc041 100644 --- a/ldappr/test/test_ldappr.py +++ b/ldappr/test/test_ldappr.py @@ -41,21 +41,15 @@ class TestLdappr(unittest.TestCase): ldap = connect_to(self.server, port=self.ldap_port) ldap.close() - # def test_server_down(self): - # with self.assertRaises(ldap.SERVER_DOWN): - # connect_to('wrong_server', self.bind_dn, self.password, - # port=self.ldap_port) - # - # def test_invalid_credentials(self): - # with self.assertRaises(ldap.INVALID_CREDENTIALS): - # connect_to(self.server, self.bind_dn, 'wrong_password', - # port=self.ldap_port) - def test_get_attributes_from_ldapper_object(self): user = self.ldap.get('cn=jdoe') self.assertEqual(user.attrs['givenname'], ['John']) self.assertEqual(user.attrs['gIvEnNaMe'], ['John']) + def test_get_nonexisting_attribute_ldapper_object(self): + user = self.ldap.get('cn=jdoe') + self.assertEqual(user.attrs['nonexisting'], []) + def test_search_instead_of_get(self): self.assertNotEqual(self.ldap.search('cn=jdoe'), [])