You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by cc...@apache.org on 2026/10/14 21:54:04 UTC
(allura) 01/01: [#8626] Make inbound email auto-reply verification case insensitive
This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch cc/8626b
in repository https://gitbox.apache.org/repos/asf/allura.git
commit 40b88335bab41efa71a3e1f1fd2be99cf1a25978
Author: Carlos Cruz <ca...@slashdotmedia.com>
AuthorDate: Wed Oct 14 21:48:07 2026 +0000
[#8626] Make inbound email auto-reply verification case insensitive
---
Allura/allura/lib/mail_util.py | 21 ++++++++++++---------
Allura/allura/tests/test_mail_util.py | 21 +++++++++++++++++++++
2 files changed, 33 insertions(+), 9 deletions(-)
diff --git a/Allura/allura/lib/mail_util.py b/Allura/allura/lib/mail_util.py
index 5f574dd9d..fc7b9a36f 100644
--- a/Allura/allura/lib/mail_util.py
+++ b/Allura/allura/lib/mail_util.py
@@ -116,16 +116,19 @@ def is_autoreply(msg):
Detection based on suggestions from
https://github.com/opennorth/multi_mail/wiki/Detecting-autoresponders
'''
- h = msg['headers']
+ # header names are case-insensitive, but msg['headers'] is a plain dict
+ h = {str(name).lower(): value for name, value in msg['headers'].items()}
+ # RFC 3834: any Auto-Submitted keyword other than "no" marks an automatic message
+ auto_submitted = str(h.get('auto-submitted', '')).split(';')[0].strip().lower()
return (
- h.get('Auto-Submitted') == 'auto-replied'
- or h.get('X-POST-MessageClass') == '9; Autoresponder'
- or h.get('Delivered-To') == 'Autoresponder'
- or h.get('X-FC-MachineGenerated') == 'true'
- or h.get('X-AutoReply-From') is not None
- or h.get('X-Autogenerated') in ['Forward', 'Group', 'Letter', 'Mirror', 'Redirect', 'Reply']
- or h.get('X-Precedence') == 'auto_reply'
- or h.get('Return-Path') == '<>'
+ auto_submitted not in ('', 'no')
+ or h.get('x-post-messageclass') == '9; Autoresponder'
+ or h.get('delivered-to') == 'Autoresponder'
+ or h.get('x-fc-machinegenerated') == 'true'
+ or h.get('x-autoreply-from') is not None
+ or h.get('x-autogenerated') in ['Forward', 'Group', 'Letter', 'Mirror', 'Redirect', 'Reply']
+ or h.get('x-precedence') == 'auto_reply'
+ or h.get('return-path') == '<>'
)
diff --git a/Allura/allura/tests/test_mail_util.py b/Allura/allura/tests/test_mail_util.py
index c74f8d85b..23470c731 100644
--- a/Allura/allura/tests/test_mail_util.py
+++ b/Allura/allura/tests/test_mail_util.py
@@ -303,6 +303,27 @@ def test_return_path(self):
self.msg['headers']['Return-Path'] = '<>'
assert is_autoreply(self.msg)
+ def test_header_name_case_insensitive(self):
+ self.msg['headers']['auto-submitted'] = 'auto-replied'
+ assert is_autoreply(self.msg)
+
+ def test_auto_submitted_auto_generated(self):
+ self.msg['headers']['auto-submitted'] = 'auto-generated'
+ assert is_autoreply(self.msg)
+
+ def test_auto_submitted_keyword_with_params(self):
+ self.msg['headers']['Auto-Submitted'] = 'Auto-Replied; owner-email="a@b.com"'
+ assert is_autoreply(self.msg)
+
+ def test_auto_submitted_no(self):
+ self.msg['headers']['Auto-Submitted'] = 'No'
+ assert not is_autoreply(self.msg)
+
+ def test_parsed_message_lowercase_header(self):
+ msg = parse_message(
+ 'From: <a...@b.com>\nMessage-ID: <a...@b.com>\nauto-submitted: auto-generated\n\nbody')
+ assert is_autoreply(msg)
+
class TestIdentifySender: