From 5b370ec9b2ecaf9a7f828ae78bf3789a79618f0f Mon Sep 17 00:00:00 2001 From: Kara Engelhardt Date: Wed, 8 Nov 2023 21:47:33 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Create=20problem=20report=20for=20b?= =?UTF-8?q?ounced=20delivery=20reports?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- froide/foirequest/signals.py | 13 ++++++- froide/helper/tests/test_email_log_parsing.py | 35 +++++++++++++++++++ froide/helper/tests/testdata/maillog_006.txt | 6 ++++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 froide/helper/tests/testdata/maillog_006.txt diff --git a/froide/foirequest/signals.py b/froide/foirequest/signals.py index da9c2f3a2..4904a0ec1 100644 --- a/froide/foirequest/signals.py +++ b/froide/foirequest/signals.py @@ -7,6 +7,7 @@ from froide.helper.email_sending import mail_registry from froide.helper.signals import email_left_queue +from froide.problem.models import ProblemReport from .models import ( DeliveryStatus, @@ -435,7 +436,7 @@ def save_delivery_status( except FoiMessage.DoesNotExist: return - DeliveryStatus.objects.update_or_create( + delivery_status, _ = DeliveryStatus.objects.update_or_create( message=message, defaults={ "log": "".join(log), @@ -446,6 +447,16 @@ def save_delivery_status( if status == "sent": send_foimessage_sent_confirmation(message) + elif delivery_status.is_failed(): + if not ProblemReport.objects.filter( + message=message, kind=ProblemReport.PROBLEM.BOUNCE_PUBLICBODY + ).exists(): + ProblemReport.objects.report( + message=message, + kind=ProblemReport.PROBLEM.BOUNCE_PUBLICBODY, + description=delivery_status.log, + auto_submitted=True, + ) def send_foimessage_sent_confirmation(message: FoiMessage = None, **kwargs): diff --git a/froide/helper/tests/test_email_log_parsing.py b/froide/helper/tests/test_email_log_parsing.py index 3999161af..fe7127eb6 100644 --- a/froide/helper/tests/test_email_log_parsing.py +++ b/froide/helper/tests/test_email_log_parsing.py @@ -5,6 +5,10 @@ import pytest +from froide.foirequest.models.request import FoiRequest +from froide.foirequest.tests import factories +from froide.problem.models import ProblemReport + from ..email_log_parsing import ( PostfixLogfileParser, PostfixLogLine, @@ -53,6 +57,17 @@ def p(path): } +@pytest.fixture +def req_with_msgs(world): + secret_address = "sw+yurpykc1hr@fragdenstaat.de" + req = factories.FoiRequestFactory.create( + site=world, secret_address=secret_address, closed=True + ) + factories.FoiMessageFactory.create(request=req) + factories.FoiMessageFactory.create(request=req, is_response=True) + return req + + def test_parse_field_minimal(): assert PostfixLogfileParser._parse_fields(DEMO_FIELDS) == { "to": "poststelle@zitis.bund.de", @@ -234,3 +249,23 @@ def callback(**kwargs): print(invocations[0]) assert invocations[0]["message_id"] == MAIL_1_ID assert invocations[0]["log"] == MAIL_1_LOG + + +@pytest.mark.django_db +def test_bouncing_email(req_with_msgs: FoiRequest): + msg = req_with_msgs.messages[0] + msg.email_message_id = "" + msg.save() + problem_reports_before = ProblemReport.objects.filter(message=msg).count() + # Check that problem report gets created + with tempfile.TemporaryDirectory() as tmpdir: + check_delivery_from_log(p("maillog_006.txt"), str(tmpdir + "/mail_log.offset")) + assert ( + ProblemReport.objects.filter(message=msg).count() == problem_reports_before + 1 + ) + # Check that problem report does not created again + with tempfile.TemporaryDirectory() as tmpdir: + check_delivery_from_log(p("maillog_006.txt"), str(tmpdir + "/mail_log.offset")) + assert ( + ProblemReport.objects.filter(message=msg).count() == problem_reports_before + 1 + ) diff --git a/froide/helper/tests/testdata/maillog_006.txt b/froide/helper/tests/testdata/maillog_006.txt new file mode 100644 index 000000000..be2c6a5e9 --- /dev/null +++ b/froide/helper/tests/testdata/maillog_006.txt @@ -0,0 +1,6 @@ +Jul 7 13:01:25 brooke postfix/smtpd[581830]: ABCDEF12345: client=localhost.localdomain[127.0.0.1], sasl_method=PLAIN, sasl_username=examplemail@example.com +Jul 7 13:01:25 brooke postfix/cleanup[580201]: ABCDEF12345: message-id= +Jul 7 13:01:25 brooke postfix/qmgr[61174]: ABCDEF12345: from=, size=5264, nrcpt=1 (queue active) +Jul 7 13:01:27 brooke postfix/smtp[586922]: ABCDEF12345: to=, relay=exapmle.com[1.2.3.4]:25, delay=2.6, delays=0.09/0/1/1.4, dsn=5.0.0, status=bounced (host example.com[1.2.3.4] said: 550-Callout verification failed: 550-550 5.1.1 : Recipient address rejected: 550 Ungueltige Mail-Domain example.com (in reply to RCPT TO command)) +Jul 7 13:01:27 brooke postfix/bounce[589205]: ABCDEF12345: sender non-delivery notification: 12345ABCDEF +Jul 7 13:01:27 brooke postfix/qmgr[61174]: ABCDEF12345: removed