diff --git a/docker/utils/rootfs/opt/app-root/src/generatemail.py b/docker/utils/rootfs/opt/app-root/src/generatemail.py index b80b9927..79977ac8 100755 --- a/docker/utils/rootfs/opt/app-root/src/generatemail.py +++ b/docker/utils/rootfs/opt/app-root/src/generatemail.py @@ -1,362 +1,361 @@ #!/bin/env python3 """ Generate a bunch of dummy messages in a folder. ./generate.py --clear --type=contact --count 1000 --username admin@kolab-vanilla.alma8.local --password W3lcom32@ph3lia --host localhost --port 9993 Contacts """ -from datetime import datetime, timedelta -import pytz +from datetime import datetime, timedelta, UTC import random import argparse import glob import os import imaplib mailtemplate = ''' Return-Path: Received: from imapb010.mykolab.com ([unix socket]) by imapb010.mykolab.com (Cyrus 2.5.10-49-g2e214b4-Kolab-2.5.10-8.1.el7.kolab_14) with LMTPA; Wed, 09 Aug 2017 18:37:01 +0200 X-Sieve: CMU Sieve 2.4 Received: from int-mx002.mykolab.com (unknown [10.9.13.2]) by imapb010.mykolab.com (Postfix) with ESMTPS id 0A93910A25047 for ; Wed, 9 Aug 2017 18:37:01 +0200 (CEST) Received: from int-subm002.mykolab.com (unknown [10.9.37.2]) by int-mx002.mykolab.com (Postfix) with ESMTPS id EC06AF6E for ; Wed, 9 Aug 2017 18:37:00 +0200 (CEST) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=_291b8e96564265636432c6d494e02322" Date: {date} From: "Mollekopf, Christian" To: christian@example.ch Subject: {subject} Message-ID: {messageid} --=_291b8e96564265636432c6d494e02322 Content-Type: multipart/alternative; boundary="=_ceff0fd19756f45ed1295ee2069ff8e0" --=_ceff0fd19756f45ed1295ee2069ff8e0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=US-ASCII sdlkjsdjf --=_ceff0fd19756f45ed1295ee2069ff8e0 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=UTF-8

sdlkjsdjf

--=_ceff0fd19756f45ed1295ee2069ff8e0-- --=_291b8e96564265636432c6d494e02322 Content-Transfer-Encoding: base64 Content-Type: text/plain; name=xorg.conf Content-Disposition: attachment; filename=xorg.conf; size=211 U2VjdGlvbiAiRGV2aWNlIgogICAgSWRlbnRpZmllciAgICAgIkRldmljZTAiCiAgICBEcml2ZXIg {attachment}ICAgIEJvYXJkTmFtZSAgICAgICJOVlMgNDIwME0iCiAgICBPcHRpb24gIk5vTG9nbyIgInRydWUi CiAgICBPcHRpb24gIlVzZUVESUQiICJ0cnVlIgpFbmRTZWN0aW9uCg== --=_291b8e96564265636432c6d494e02322-- '''.strip() eventtemplate = ''' MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=_a56b92bc39b8cc011c0c98c3dcac708a" From: admin@kolab-premium.centos7.local To: admin@kolab-premium.centos7.local Date: Thu, 07 May 2020 07:28:51 +0000 X-Kolab-Type: application/x-vnd.kolab.event X-Kolab-Mime-Version: 3.0 Subject: {uid} User-Agent: Kolab 16/Roundcube 1.4.2 --=_a56b92bc39b8cc011c0c98c3dcac708a Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=ISO-8859-1 This is a Kolab Groupware object. To view this object you will need an emai= l client that understands the Kolab Groupware format. For a list of such em= ail clients please visit http://www.kolab.org/ --=_a56b92bc39b8cc011c0c98c3dcac708a Content-Transfer-Encoding: 8bit Content-Type: application/calendar+xml; charset=UTF-8; name=kolab.xml Content-Disposition: attachment; filename=kolab.xml; size=2724 Roundcube-libkolab-1.1 Libkolabxml-1.2.0 2.0 3.1.0 {uid} 2020-05-07T07:28:51Z 2020-05-07T07:28:51Z 0 PUBLIC /kolab.org/Europe/Zurich {dtstart} /kolab.org/Europe/Zurich {dtend} {summary} Testdescription Testlocation mailto:%3Cadmin%40kolab-premium.centos7.local%3E NEEDS-ACTION REQ-PARTICIPANT true mailto:%3Ctest1%40kolab-premium.centos7.local%3E text/x-ruby safe_yaml cid:safe_yaml.1588836531.13830 --=_a56b92bc39b8cc011c0c98c3dcac708a Content-ID: Content-Transfer-Encoding: base64 Content-Type: text/x-ruby; name=safe_yaml Content-Disposition: attachment; filename=safe_yaml; size=540 IyEvdXNyL2Jpbi9ydWJ5CiMKIyBUaGlzIGZpbGUgd2FzIGdlbmVyYXRlZCBieSBSdWJ5R2Vtcy4K {attachment}dAppZiBzdHIKICBzdHIgPSBzdHIuYlsvXEFfKC4qKV9cei8sIDFdCiAgaWYgc3RyIGFuZCBHZW06 ICJzYWZlX3lhbWwiLCB2ZXJzaW9uKQplbmQK --=_a56b92bc39b8cc011c0c98c3dcac708a-- '''.strip() contacttemplate = ''' MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=_a56b92bc39b8cc011c0c98c3dcac708a" From: admin@kolab-premium.centos7.local To: admin@kolab-premium.centos7.local Date: Thu, 07 May 2020 07:28:51 +0000 X-Kolab-Type: application/x-vnd.kolab.contact X-Kolab-Mime-Version: 3.0 Subject: {uid} User-Agent: Kolab 16/Roundcube 1.4.2 --=_a56b92bc39b8cc011c0c98c3dcac708a Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=ISO-8859-1 This is a Kolab Groupware object. To view this object you will need an emai= l client that understands the Kolab Groupware format. For a list of such em= ail clients please visit http://www.kolab.org/ --=_a56b92bc39b8cc011c0c98c3dcac708a Content-Transfer-Encoding: 8bit Content-Type: application/vcard+xml; charset=UTF-8; name=kolab.xml Content-Disposition: attachment; filename=kolab.xml; size=646 urn:uuid:{uid} 3.1.0 Roundcube-libkolab-1.1 Libkolabxml-1.3.0 20230428T134238Z individual {given} {surname} home {email} --=_a56b92bc39b8cc011c0c98c3dcac708a-- '''.strip() class Generator: def __init__(self, options): self.target_directory = options.target_directory self.host = options.host self.port = options.port self.username = options.username self.password = options.password self.maxAttachmentSize = options.maxAttachmentSize if options.ssl: self.imap = imaplib.IMAP4_SSL(host=self.host, port=self.port) else: self.imap = imaplib.IMAP4(host=self.host, port=self.port) self.imap.login(options.username, options.password) def clearmailbox(self): #FIXME restore support for just writing to a directory # for f in glob.glob("{}/../cur/*".format(self.target_directory)): # os.remove(f) self.imap.select(self.target_directory) typ, data = self.imap.search(None, 'ALL') for num in data[0].split(): self.imap.store(num, '+FLAGS', '\\Deleted') self.imap.expunge() def upload(self, i, data): #FIXME restore support for just writing to a directory # fname = "{}/{}.".format(self.target_directory, i) # with open(fname, 'wb') as f: # f.write(data.encode()) - ret = self.imap.append(self.target_directory, '', datetime.now(pytz.UTC), data.encode()) + ret = self.imap.append(self.target_directory, '', datetime.now(UTC), data.encode()) if ret[0] != 'OK': raise Exception(ret) def populatemailbox(self, type, count): - dtstamp = datetime.utcnow() + dtstamp = datetime.now(UTC) # Reproducible results random.seed(30) for i in range(1, count + 1): dtstamp = dtstamp - timedelta(seconds=600) if type == "mail": attachmentMultiplier = 13158 * random.randint(0, self.maxAttachmentSize) # 13158 is roughly 1 MB result = mailtemplate.format( messageid="".format(i), subject="Foobar {}".format(i), date=dtstamp.strftime("%a, %d %b %Y %H:%M:%S %z"), attachment='ICAgIEJvYXJkTmFtZSAgICAgICJOVlMgNDIwME0iCiAgICBPcHRpb24gIk5vTG9nbyIgInRydWUi\n' * attachmentMultiplier ) if type == "event": result = eventtemplate.format( uid="B06DBE43D213419A9D705D6B7FAB2CA2-{}".format(i), summary="Foobar {}".format(i), dtstart=dtstamp.strftime("%Y-%m-%dT%H:%M:%S"), dtend=(dtstamp + timedelta(seconds=300)).strftime("%Y-%m-%dT%H:%M:%S"), attachment='dAppZiBzdHIKICBzdHIgPSBzdHIuYlsvXEFfKC4qKV9cei8sIDFdCiAgaWYgc3RyIGFuZCBHZW06\n' * 5000 * random.randint(0, 10) ) if type == "contact": result = contacttemplate.format( uid="B06DBE43D213419A9D705D6B7FAB2CA3-{}".format(i), given="John {}".format(i), surname="Doe {}".format(i), email="doe{}@example.com".format(i), ) print(i) self.upload(i, result) parser = argparse.ArgumentParser(description='Generate some mail.') parser.add_argument('target_directory', help='the target directory') parser.add_argument('--count', help='Number of emails to generate', type=int) parser.add_argument('--type', help='Type to generate', default='mail') parser.add_argument('--clear', help='Type to generate', action='store_true') parser.add_argument('--ssl', help='Use ssl', action='store_true') parser.add_argument('--host', help='imap host', default='localhost') parser.add_argument('--port', help='imap port', type=int, default=993) parser.add_argument('--maxAttachmentSize', help='in MB', type=int, default=20) parser.add_argument('--username', help='imap username') parser.add_argument('--password', help='imap password') args = parser.parse_args() gen = Generator(args) if args.clear: gen.clearmailbox() gen.populatemailbox(args.type, args.count) diff --git a/docker/utils/rootfs/opt/app-root/src/mailtransporttest.py b/docker/utils/rootfs/opt/app-root/src/mailtransporttest.py index 29b92136..b1640616 100755 --- a/docker/utils/rootfs/opt/app-root/src/mailtransporttest.py +++ b/docker/utils/rootfs/opt/app-root/src/mailtransporttest.py @@ -1,142 +1,142 @@ #!/bin/env python3 """ Send an email via SMTP and then look for it via IMAP. ./mailtransporttest.py --sender-username test1@kolab.org --sender-password foobar --sender-host smtp.kolabnow.com --recipient-username test2@kolab.org --recipient-password foobar --recipient-host imap.kolabnow.com """ -from datetime import datetime +from datetime import datetime, UTC import argparse import sys import imaplib import smtplib import uuid import time mailtemplate = ''' MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=_291b8e96564265636432c6d494e02322" Date: {date} From: {sender} To: {to} Subject: {subject} Message-ID: {messageid} --=_291b8e96564265636432c6d494e02322 Content-Type: multipart/alternative; boundary="=_ceff0fd19756f45ed1295ee2069ff8e0" --=_ceff0fd19756f45ed1295ee2069ff8e0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=US-ASCII sdlkjsdjf --=_ceff0fd19756f45ed1295ee2069ff8e0 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=UTF-8

sdlkjsdjf

--=_ceff0fd19756f45ed1295ee2069ff8e0-- --=_291b8e96564265636432c6d494e02322 Content-Transfer-Encoding: base64 Content-Type: text/plain; name=xorg.conf Content-Disposition: attachment; filename=xorg.conf; size=211 U2VjdGlvbiAiRGV2aWNlIgogICAgSWRlbnRpZmllciAgICAgIkRldmljZTAiCiAgICBEcml2ZXIg {attachment}ICAgIEJvYXJkTmFtZSAgICAgICJOVlMgNDIwME0iCiAgICBPcHRpb24gIk5vTG9nbyIgInRydWUi CiAgICBPcHRpb24gIlVzZUVESUQiICJ0cnVlIgpFbmRTZWN0aW9uCg== --=_291b8e96564265636432c6d494e02322-- '''.strip() class SendTest: def __init__(self, options): self.recipient_host = options.recipient_host self.recipient_username = options.recipient_username self.recipient_password = options.recipient_password self.sender_host = options.sender_host self.sender_username = options.sender_username self.sender_password = options.sender_password self.uuid = str(uuid.uuid4()) self.subject = f"Delivery Check {self.uuid}" def check_for_mail(self): print(f"Checking for uuid {self.uuid}") imap = imaplib.IMAP4_SSL(host=self.recipient_host, port=993) imap.login(self.recipient_username, self.recipient_password) imap.select("INBOX") typ, data = imap.search(None, 'SUBJECT', '"' + self.subject + '"') for num in data[0].split(): print(f"Found the mail with uid {num}") imap.store(num, '+FLAGS', '\\Deleted') imap.expunge() return True return False def send_mail(self, starttls): - dtstamp = datetime.utcnow() + dtstamp = datetime.now(UTC) msg = mailtemplate.format( messageid="<{}@deliverycheck.org>".format(self.uuid), subject=self.subject, sender=self.sender_username, to=self.recipient_username, date=dtstamp.strftime("%a, %d %b %Y %H:%M:%S %z"), attachment='ICAgIEJvYXJkTmFtZSAgICAgICJOVlMgNDIwME0iCiAgICBPcHRpb24gIk5vTG9nbyIgInRydWUi\n' ) if starttls: with smtplib.SMTP(host=self.sender_host, port=587) as smtp: smtp.starttls() smtp.ehlo() smtp.login(self.sender_username, self.sender_password) smtp.noop() smtp.sendmail(self.sender_username, self.recipient_username, msg) print(f"Email with uuid {self.uuid} sent") else: with smtplib.SMTP_SSL(host=self.sender_host, port=465) as smtp: smtp.login(self.sender_username, self.sender_password) smtp.noop() smtp.sendmail(self.sender_username, self.recipient_username, msg) print(f"Email with uuid {self.uuid} sent") parser = argparse.ArgumentParser(description='Mail transport tests.') parser.add_argument('--sender-username', help='The SMTP sender username') parser.add_argument('--sender-password', help='The SMTP sender password') parser.add_argument('--sender-host', help='The SMTP sender host') parser.add_argument('--recipient-username', help='The IMAP recipient username') parser.add_argument('--recipient-password', help='The IMAP recipient password') parser.add_argument('--recipient-host', help='The IMAP recipient host') parser.add_argument('--timeout', help='Timeout in minutes', type=int, default=10) parser.add_argument("--starttls", action='store_true', help="Use starttls over 587") args = parser.parse_args() obj = SendTest(args) obj.send_mail(args.starttls) timeout = 10 for i in range(1, round(args.timeout * 60 / timeout) + 1): if obj.check_for_mail(): print("Success!") sys.exit(0) print(f"waiting for {timeout}") time.sleep(timeout) print("Failed to find the mail") sys.exit(1) diff --git a/docker/utils/rootfs/opt/app-root/src/sendmail.py b/docker/utils/rootfs/opt/app-root/src/sendmail.py index e425f653..7bccb5b8 100755 --- a/docker/utils/rootfs/opt/app-root/src/sendmail.py +++ b/docker/utils/rootfs/opt/app-root/src/sendmail.py @@ -1,70 +1,70 @@ #!/bin/env python3 """ Utilty to send an email. Primarily useful to quickly generate test messages to e.g. troubleshoot mail delivery. ./sendmail.py --sender-username admin@kolab.local --sender-password test123 --to test@kolab.org --subject 'test4' --body 'test4'""" -from datetime import datetime +from datetime import datetime, UTC import argparse import sys import smtplib import uuid mailtemplate = ''' MIME-Version: 1.0 Content-Type: text/plain; Date: {date} From: {sender} To: {to} Subject: {subject} Message-ID: {messageid} {body} '''.strip() class SendMail: def __init__(self, options): self.sender_username = options.sender_username self.sender_password = options.sender_password self.to = options.to self.uuid = str(uuid.uuid4()) self.subject = options.subject self.body = options.body def send_mail(self): - dtstamp = datetime.utcnow() + dtstamp = datetime.now(UTC) msg = mailtemplate.format( messageid="<{}@sendmail.py>".format(self.uuid), subject=self.subject, body=self.body, sender=self.sender_username, to=self.to, date=dtstamp.strftime("%a, %d %b %Y %H:%M:%S %z"), ) with smtplib.SMTP(host="postfix", port=10587) as smtp: smtp.starttls() smtp.ehlo() smtp.login(self.sender_username, self.sender_password) smtp.noop() smtp.sendmail(self.sender_username, self.to, msg) print(f"Email with uuid {self.uuid} sent") parser = argparse.ArgumentParser(description='Mail transport tests.') parser.add_argument('--sender-username', help='The SMTP sender username') parser.add_argument('--sender-password', help='The SMTP sender password') parser.add_argument('--to', help='The IMAP recipient username') parser.add_argument('--subject', help='Subject') parser.add_argument('--body', help='Body') args = parser.parse_args() obj = SendMail(args) obj.send_mail() sys.exit(0)