Compare commits

...

3 commits

Author SHA1 Message Date
Benjamin Renard
e8de509346 Report: add methods to attach file/payload
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2022-05-27 19:59:47 +02:00
Benjamin Renard
5a7a46355c LdapClient.update_object: do not modify the provided changes parameter in case of renaming 2022-05-27 19:54:03 +02:00
Benjamin Renard
a36ce4070b LdapClient.add_object: ignore 'dn' attribute if provided 2022-05-27 19:52:59 +02:00
2 changed files with 28 additions and 11 deletions

View file

@ -705,6 +705,7 @@ class LdapClient:
attrs = dict( attrs = dict(
(attr, self.encode(values)) (attr, self.encode(values))
for attr, values in attrs.items() for attr, values in attrs.items()
if attr != 'dn'
) )
try: try:
if self._just_try: if self._just_try:
@ -729,11 +730,14 @@ class LdapClient:
:param rdn_attr: The LDAP object RDN attribute (to detect renaming, default: auto-detected) :param rdn_attr: The LDAP object RDN attribute (to detect renaming, default: auto-detected)
""" """
assert isinstance(changes, (list, tuple)) and len(changes) == 2 and isinstance(changes[0], dict) and isinstance(changes[1], dict), "changes parameter must be a result of get_changes() method (%s given)" % type(changes) assert isinstance(changes, (list, tuple)) and len(changes) == 2 and isinstance(changes[0], dict) and isinstance(changes[1], dict), "changes parameter must be a result of get_changes() method (%s given)" % type(changes)
# In case of RDN change, we need to modify passed changes, copy it to make it unchanged in
# this case
_changes = copy.deepcopy(changes)
if not rdn_attr: if not rdn_attr:
rdn_attr = ldap_obj['dn'].split('=')[0] rdn_attr = ldap_obj['dn'].split('=')[0]
log.debug('Auto-detected RDN attribute from DN: %s => %s', ldap_obj['dn'], rdn_attr) log.debug('Auto-detected RDN attribute from DN: %s => %s', ldap_obj['dn'], rdn_attr)
old_rdn_values = self.get_attr(changes[0], rdn_attr, all_values=True) old_rdn_values = self.get_attr(_changes[0], rdn_attr, all_values=True)
new_rdn_values = self.get_attr(changes[1], rdn_attr, all_values=True) new_rdn_values = self.get_attr(_changes[1], rdn_attr, all_values=True)
if old_rdn_values or new_rdn_values: if old_rdn_values or new_rdn_values:
if not new_rdn_values: if not new_rdn_values:
log.error( log.error(
@ -758,15 +762,15 @@ class LdapClient:
return False return False
# Remove RDN in changes list # Remove RDN in changes list
for attr in list(changes[0].keys()): for attr in list(_changes[0].keys()):
if attr.lower() == rdn_attr.lower(): if attr.lower() == rdn_attr.lower():
del changes[0][attr] del _changes[0][attr]
for attr in list(changes[1].keys()): for attr in list(_changes[1].keys()):
if attr.lower() == rdn_attr.lower(): if attr.lower() == rdn_attr.lower():
del changes[1][attr] del _changes[1][attr]
# Check that there are other changes # Check that there are other changes
if not changes[0] and not changes[1]: if not _changes[0] and not _changes[1]:
log.debug('%s: No other change after renaming', new_dn) log.debug('%s: No other change after renaming', new_dn)
return True return True
@ -782,14 +786,14 @@ class LdapClient:
assert self._conn or self.initialize() assert self._conn or self.initialize()
return self._conn.update_object( return self._conn.update_object(
ldap_obj['dn'], ldap_obj['dn'],
changes[0], _changes[0],
changes[1], _changes[1],
ignore_attrs=protected_attrs ignore_attrs=protected_attrs
) )
except LdapServerException: except LdapServerException:
log.error( log.error(
"An error occurred updating object %s in LDAP:\n%s\n -> \n%s\n\n", "An error occurred updating object %s in LDAP:\n%s\n -> \n%s\n\n",
ldap_obj['dn'], pretty_format_dict(changes[0]), pretty_format_dict(changes[1]), ldap_obj['dn'], pretty_format_dict(_changes[0]), pretty_format_dict(_changes[1]),
exc_info=True exc_info=True
) )
return False return False

View file

@ -33,6 +33,8 @@ class Report(ConfigurableObject): # pylint: disable=useless-object-inheritance
def __init__(self, email_client=None, initialize=True, **kwargs): def __init__(self, email_client=None, initialize=True, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
self.email_client = email_client self.email_client = email_client
self._attachment_files = []
self._attachment_payloads = []
if initialize: if initialize:
self.initialize() self.initialize()
@ -84,6 +86,14 @@ class Report(ConfigurableObject): # pylint: disable=useless-object-inheritance
""" Read the report content """ """ Read the report content """
return "".join(self.content) return "".join(self.content)
def add_attachment_file(self, filepath):
""" Add attachment file """
self._attachment_files.append(filepath)
def add_attachment_payload(self, payload):
""" Add attachment payload """
self._attachment_payloads.append(payload)
def send(self, subject=None, rcpt_to=None, email_client=None, just_try=False): def send(self, subject=None, rcpt_to=None, email_client=None, just_try=False):
""" Send report using an EmailClient """ """ Send report using an EmailClient """
if rcpt_to is None: if rcpt_to is None:
@ -102,7 +112,10 @@ class Report(ConfigurableObject): # pylint: disable=useless-object-inheritance
if not content: if not content:
log.debug('Report is empty, do not send it') log.debug('Report is empty, do not send it')
return True return True
msg = email_client.forge_message(rcpt_to, subject=subject, text_body=content) msg = email_client.forge_message(
rcpt_to, subject=subject, text_body=content,
attachment_files=self._attachment_files,
attachment_payloads=self._attachment_payloads)
if email_client.send(rcpt_to, msg=msg, just_try=just_try): if email_client.send(rcpt_to, msg=msg, just_try=just_try):
log.debug('Report sent to %s', rcpt_to) log.debug('Report sent to %s', rcpt_to)
return True return True