From: Frank Brehm Date: Thu, 28 Mar 2024 15:43:14 +0000 (+0100) Subject: Integrating smtp_actions in class PostfixLogchainInfo. X-Git-Url: https://git.uhu-banane.net/?a=commitdiff_plain;h=1f3f42269cf119dae822226c2561d56fdf9944d1;p=pixelpark%2Fpp-admin-tools.git Integrating smtp_actions in class PostfixLogchainInfo. --- diff --git a/lib/pp_admintools/postfix_chain.py b/lib/pp_admintools/postfix_chain.py index ffef626..dca8fc0 100644 --- a/lib/pp_admintools/postfix_chain.py +++ b/lib/pp_admintools/postfix_chain.py @@ -14,14 +14,12 @@ import datetime import ipaddress import logging import re -from collections import OrderedDict +from collections.abc import Sequence # Third party modules -from fb_tools.common import is_sequence from fb_tools.common import pp from fb_tools.errors import InvalidMailAddressError from fb_tools.mailaddress import MailAddress -from fb_tools.mailaddress import MailAddressList from fb_tools.obj import FbGenericBaseObject # Own modules @@ -33,7 +31,7 @@ from .xlate import XLATOR _ = XLATOR.gettext ngettext = XLATOR.ngettext -__version__ = '0.7.0' +__version__ = '0.7.1' LOG = logging.getLogger(__name__) @@ -615,7 +613,7 @@ class SmtpAction(FbGenericBaseObject): @rtype: dict """ if exportable: - res = OrderedDict() + res = {} else: res = super(SmtpAction, self).as_dict(short=short) @@ -755,15 +753,15 @@ class PostfixLogchainInfo(FbGenericBaseObject): ) # ------------------------------------------------------------------------- - def __init__(self, to_addresses=[], **kwargs): + def __init__(self, smtp_actions=None, **kwargs): """Initialize this object.""" for attr in self.attributes: priv_name = '_' + attr setattr(self, priv_name, None) - self.to_addresses = MailAddressList() - if to_addresses: - self.set_to_addresses(to_addresses) + self.smtp_actions = [] + if smtp_actions: + self.set_smtp_actions(smtp_actions) for attr in kwargs.keys(): if attr not in self.attributes: @@ -773,26 +771,37 @@ class PostfixLogchainInfo(FbGenericBaseObject): setattr(self, attr, kwargs[attr]) # ------------------------------------------------------------------------- - def set_to_addresses(self, addresses): - """Set the array with all TO addresses of the mail after address resolution.""" - self.to_addresses = [] - if addresses is None: + def set_smtp_actions(self, smtp_actions): + """Set the array with all SMTP actions of Postfix after address resolution.""" + self.smtp_actions = [] + if smtp_actions is None: return - if isinstance(addresses, MailAddressList): - self.to_addresses = copy.copy(addresses) - return - - if not is_sequence(addresses): - addresses = [addresses] + if not isinstance(smtp_actions, (Sequence, tuple)): + smtp_actions = [smtp_actions] - for addr in addresses: - self.to_addresses.append(addr) + for action in smtp_actions: + self.add_smtp_action(action) # ------------------------------------------------------------------------- - def add_to_address(self, address): - """Append the given mail address to the list of TO addresses.""" - self.to_addresses.append(address) + def add_smtp_action(self, action): + """Append the given SmtpAction to the list of TO smtp_actions.""" + if action is None: + msg = _('You may not append a None value as a SmtpAction to the list smtp_actions.') + raise TypeError(msg) + + if isinstance(action, SmtpAction): + self.smtp_actions.append(action) + return + + if isinstance(action, dict): + smtp_action = SmtpAction(**action) + self.smtp_actions.append(smtp_action) + return + + msg = _('Wrong type {c!r} for creating a {w} object from: {a!r}').format( + c=action.__class__.__name__, w='SmtpAction', a=action) + raise TypeError(msg) # ----------------------------------------------------------- @property @@ -1362,7 +1371,7 @@ class PostfixLogchainInfo(FbGenericBaseObject): @rtype: dict """ if exportable: - res = OrderedDict() + res = {} else: res = super(PostfixLogchainInfo, self).as_dict(short=short) @@ -1386,12 +1395,16 @@ class PostfixLogchainInfo(FbGenericBaseObject): # Catch all res[attrib] = value + res['smtp_actions'] = None if exportable: - res['to_addresses'] = None - if self.to_addresses: - res['to_addresses'] = self.to_addresses.as_list(as_str=True) + if self.smtp_actions: + res['smtp_actions'] = [] + for action in self.smtp_actions: + res['smtp_actions'].append(action.as_dict(exportable=True)) else: - res['to_addresses'] = copy.copy(self.to_addresses) + res['smtp_actions'] = [] + for action in self.smtp_actions: + res['smtp_actions'].append(action.as_dict(short=short)) # Non init properties if not exportable: diff --git a/test/test_20_postfix_chain.py b/test/test_20_postfix_chain.py index d75e7a8..77a3c37 100755 --- a/test/test_20_postfix_chain.py +++ b/test/test_20_postfix_chain.py @@ -130,6 +130,7 @@ class TestPostfixChain(PpAdminToolsTestcase): re_postfix_id = re.compile(r'^(?P[0-9a-f]+):\s+', re.IGNORECASE) re_tls_line = re.compile(r'Trusted\s+TLS\s+connection\s+established', re.IGNORECASE) + re_host_said = re.compile(r'i^\s*host\s+\S+\s+said: \d', re.IGNORECASE) maillog = self.logfile if 'MAILLOG' in os.environ: @@ -162,10 +163,17 @@ class TestPostfixChain(PpAdminToolsTestcase): continue m_id = re_postfix_id.match(message) + postfix_id = None if m_id: - # postfix_id = m_id['id'].upper() + postfix_id = m_id['id'].upper() message = re_postfix_id.sub('', message) + if not postfix_id: + continue + + if re_host_said.match(message): + continue + i += 1 action = SmtpAction.from_log_entry( timestamp=timestamp, pid=pid, message=message, @@ -194,6 +202,40 @@ class TestPostfixChain(PpAdminToolsTestcase): '@sparkassen-finanzportal.de>?=' ) + smtp_action1 = { + 'date': '2024-03-15T03:46:59.821790+00:00', + 'delay_total': 1.5, + 'dsn': '2.6.0', + 'message': ( + '250 2.6.0 <=?UTF-8?Q?<175f6f376cac747b4f23caa8de25ec41@example-customer01.de>?=> ' + '[InternalId=9740985831629, Hostname=AS4P15MB1453.EURP195.PROD.OUTLOOK.COM] 30253 ' + 'bytes in 0.177, 166.044 KB/sec Queued mail for delivery -> 250 2.1.5'), + 'relay': 'mailprovider08.com[104.47.14.33]:25', + 'remote_id': '9740985831629', + 'smtp_pid': '7621', + 'status': 'sent', + 'time_before_queue': 0.44, + 'time_conn_setup': 0.17, + 'time_in_queue': 0.1, + 'time_xmission': 0.8, + 'to_address': 'ahlam_lar@mailprovider09.com', + } + smtp_action2 = { + 'date': '2024-03-15T03:47:05.123456+00:00', + 'delay_total': 2.8, + 'dsn': '2.0.0', + 'message': '250 OK id=1rkxb6-00037T-0f', + 'relay': 'webmail.vgw.de[80.151.72.120]:25', + 'remote_id': '1rkxb6-00037T-0f', + 'smtp_pid': '20679', + 'status': 'sent', + 'time_before_queue': 0.44, + 'time_conn_setup': 0.36, + 'time_in_queue': 0.09, + 'time_xmission': 1.9, + 'to_address': 'arik@vgw.de', + } + chain = PostfixLogchainInfo( client_host='mail.uhu-banane.de', client_addr='188.34.187.246', @@ -216,9 +258,10 @@ class TestPostfixChain(PpAdminToolsTestcase): tls_cipher='ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)', size=12345, nr_rcpt=1, + smtp_actions=[smtp_action1], ) - chain.add_to_address('frank.brehm@pixelpark.com') - chain.add_to_address('thomas.dalichow@pixelpark.com') + chain.add_smtp_action(smtp_action2) + LOG.debug('PostfixLogchainInfo %r: {!r}'.format(chain)) LOG.debug('PostfixLogchainInfo %s:\n{}'.format(chain)) LOG.debug('PostfixLogchainInfo as_dict():\n{}'.format(pp(chain.as_dict())))