ldappr/ldappr/ldapprobject.py

82 lines
2.9 KiB
Python
Raw Normal View History

2014-09-14 17:24:19 +04:00
import ldap
import ldif
from ldap.cidict import cidict
2018-04-26 12:51:29 +03:00
from io import StringIO
2018-04-26 17:06:52 +03:00
from uuid import UUID
2014-09-23 16:51:24 +04:00
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)
"""
2018-04-26 14:26:59 +03:00
if key.lower() in self.data:
return self.data[key.lower()]
2014-09-23 16:51:24 +04:00
return []
2014-09-14 17:24:19 +04:00
class LdapprObject(object):
"""\
The LdapprObject is used to handle search results from the Connection
class. It's a representation of a single object in the LDAP Directory.
"""
2018-04-26 17:06:52 +03:00
guid = None
2014-09-14 17:24:19 +04:00
def __init__(self, result, conn):
"""The class is initialized with a tuple: (dn, {attributes}), and the
2015-02-08 22:06:49 +03:00
existing connection
2014-09-14 17:24:19 +04:00
"""
(self.dn, self.attributes) = result
2014-09-23 16:51:24 +04:00
self.attrs = CustomCidict(self.attributes)
2018-04-26 17:27:06 +03:00
if 'objectguid' in [x.lower() for x in list(self.attrs.keys())]:
2018-04-26 17:06:52 +03:00
self.guid = str(UUID(bytes=self.attrs['objectguid'][0]))
2014-09-14 17:24:19 +04:00
self.conn = conn
def __str__(self):
"""Pretty prints all attributes with values."""
2018-04-26 12:51:29 +03:00
col_width = max(len(key) for key in list(self.attrs.keys()))
2014-09-14 17:24:19 +04:00
pretty_string = '{attr:{width}} : {value}\n'.format(
2014-09-23 16:51:24 +04:00
attr='dn', width=col_width, value=self.dn)
2018-04-26 17:27:06 +03:00
for key, value in list(self.attrs.items()):
if len(str(value[0])) > 80: # hack to 'detect' binary attrs
value = ['binary']
2014-09-14 17:24:19 +04:00
for single_value in value:
pretty_string += '{attr:{width}} : {value}\n'.format(
attr=self._case(key), width=col_width, value=single_value)
key = ''
return pretty_string
def _case(self, attr):
"""Transforms an attribute to correct case (e.g. gIvEnNaMe becomes
givenName). If attr is unknown nothing is transformed.
:param attr: may be incorrectly cased
:return: attr in proper case
"""
try:
2018-04-26 12:51:29 +03:00
index = [x.lower() for x in list(self.attrs.keys())].index(attr.lower())
return list(self.attrs.keys())[index]
2014-09-14 17:24:19 +04:00
except:
return attr
def to_ldif(self):
"""Makes LDIF of ldappr object."""
out = StringIO()
ldif_out = ldif.LDIFWriter(out)
ldif_out.unparse(self.dn, self.attributes)
return out.getvalue()
def set_value(self, attr, value):
attr = self._case(attr)
self.conn.modify_s(self.dn, [(ldap.MOD_REPLACE, attr, value)])
self.attrs[attr] = [value]
def add_value(self, attr, value):
attr = self._case(attr)
self.conn.modify_s(self.dn, [(ldap.MOD_ADD, attr, value)])
self.attrs[attr].append(value)
def remove_value(self, attr, value):
attr = self._case(attr)
self.conn.modify_s(self.dn, [(ldap.MOD_DELETE, attr, value)])
if value in self.attrs[attr]:
self.attrs[attr].remove(value)