Source code for ldaptor.protocols.ldap.ldif
"""
Support for writing a set of directory entries as LDIF.
You probably want to use this only indirectly, as in
str(LDAPEntry(...)).
TODO support writing modify operations
TODO support reading modify operations
TODO implement rest of syntax from RFC2849
"""
# RFC2849: The LDAP Data Interchange Format (LDIF) - Technical Specification
import base64
from ldaptor._encoder import to_bytes
[docs]def base64_encode(s):
return b"".join(base64.encodebytes(s).split(b"\n")) + b"\n"
[docs]def attributeAsLDIF_base64(attribute, value):
return b"%s:: %s" % (attribute, base64_encode(value))
[docs]def containsNonprintable(s):
for i in range(len(s)):
c = s[i : i + 1]
if ord(c) > 127 or c == b"\0" or c == b"\n" or c == b"\r":
return True
return False
[docs]def attributeAsLDIF(attribute, value):
attribute = to_bytes(attribute)
value = to_bytes(value)
if (
value.startswith(b"\0")
or value.startswith(b"\n")
or value.startswith(b"\r")
or value.startswith(b" ")
or value.startswith(b":")
or value.startswith(b"<")
or value.endswith(b" ")
or containsNonprintable(value)
):
return attributeAsLDIF_base64(attribute, value)
else:
return b"%s: %s\n" % (attribute, value)
[docs]def asLDIF(dn, attributes):
s = b"dn: %s\n" % to_bytes(dn)
for k, vs in attributes:
for v in vs:
s = s + attributeAsLDIF(k, v)
s = s + b"\n"
return s
def _header():
return b"version: 1\n\n"
[docs]def manyAsLDIF(objects):
s = [_header()]
for dn, attributes in objects:
s.append(asLDIF(dn, attributes))
return b"".join(s)