py3: fix conversion of text to bytes in LDIF parser

This commit is contained in:
Benjamin Dauvergne 2019-03-15 00:11:16 +01:00
parent 2989bad541
commit 6fcf32fabe
3 changed files with 27 additions and 14 deletions

View File

@ -2,7 +2,8 @@ import ldap
import ldif
from ldap.dn import dn2str
from ldaptools.utils import idict, str2dn, bytes2str_entry, str2bytes_entry
from ldaptools.utils import idict, str2dn, str2bytes_entry, bytes2str_entry
class AddError(Exception):
pass

View File

@ -1,5 +1,5 @@
import ldap.dn
from six import string_types
import six
# Copied from http://code.activestate.com/recipes/194371-case-insensitive-strings/
@ -76,17 +76,19 @@ class idict(dict):
dict.__init__(self)
self._keydict = {} # not self.__keydict because I want it to be easily accessible by subclasses
for entry in indict:
self[entry] = indict[entry] # not dict.__setitem__(self, entry, indict[entry]) becasue this causes errors (phantom entries) where indict has overlapping keys
# not dict.__setitem__(self, entry, indict[entry]) becasue this
# causes errors (phantom entries) where indict has overlapping keys
self[entry] = indict[entry]
def findkey(self, item):
"""A caseless way of checking if a key exists or not.
It returns None or the correct key."""
if not isinstance(item, string_types):
if not isinstance(item, six.string_types):
raise TypeError('Keywords for this object must be strings. You supplied %s' % type(item))
key = item.lower()
try:
return self._keydict[key]
except:
except Exception:
return None
def changekey(self, item):
@ -148,13 +150,13 @@ class idict(dict):
def has_key(self, item):
"""A case insensitive test for keys."""
if not isinstance(item, string_types):
if not isinstance(item, six.string_types):
return False # should never have a non-string key
return item.lower() in self._keydict # does the key exist
def __contains__(self, item):
"""A case insensitive __contains__."""
if not isinstance(item, string_types):
if not isinstance(item, six.string_types):
return False # should never have a non-string key
return item.lower() in self._keydict # does the key exist
@ -202,14 +204,14 @@ class idict(dict):
def __eq__(self, other):
for k in self:
if k not in other:
return False
return False
if self[k] != other[k]:
return False
return False
for k in other:
if k not in self:
return False
return False
if self[k] != other[k]:
return False
return False
return True
def __ne__(self, other):
@ -240,15 +242,23 @@ def str2dn(s):
return tuple(map(tuple, ldap.dn.str2dn(s)))
def decode_if_possible(s):
try:
return s.decode('utf-8')
except UnicodeDecodeError:
return s
def bytes2str_entry(entry):
str_entry = {}
for key, values in entry.items():
str_entry[key] = [v.decode('utf-8') if isinstance(v, bytes) else v for v in values]
str_entry[key] = [decode_if_possible(v) if isinstance(v, bytes) else v for v in values]
return str_entry
def str2bytes_entry(entry):
bytes_entry = {}
for key, values in entry.items():
bytes_entry[key] = [v.encode('utf-8') if isinstance(v, string_types) else v for v in values]
bytes_entry[key] = [v.encode('utf-8') if isinstance(v, six.text_type) else v for v in values]
return bytes_entry

View File

@ -9,9 +9,11 @@ from ldaptools.ldif_utils import ListLDIFParser
def test_ldifparser():
parser = ListLDIFParser(StringIO('''dn: o=orga
objectClass: organization
jpegPhoto:: E+o9UYDeUDNblBzchRD/1+2HMdI=
'''))
parser.parse()
assert len(list(parser)) == 1
assert list(parser)[0][0] == 'o=orga'
assert list(parser)[0][1] == {'objectClass': ['organization']}
assert list(parser)[0][1]['objectClass'] == ['organization']
assert list(parser)[0][1]['jpegPhoto']