[PATCH 4 of 6] email: allow specifying a different noreply email than app_email_from

Thomas De Schampheleire patrickdepinguin at gmail.com
Tue Sep 1 16:28:36 UTC 2015


# HG changeset patch
# User Thomas De Schampheleire <thomas.de.schampheleire at gmail.com>
# Date 1441051494 -7200
#      Mon Aug 31 22:04:54 2015 +0200
# Node ID 3ca9738eb4f87f38b99404a1eda22fb889e2d0d9
# Parent  6f6acca6da4ad913f45eb18441575ea04d27eedd
email: allow specifying a different noreply email than app_email_from

The configuration setting app_email_from is currently used both for the SMTP
envelope sender as for the From header inside the email (what mail clients
show). It is recommended to use an anonymous but monitored address here.
However, when no such mailbox can be created (e.g. due to corporate
IT rules), app_email_from would need to be set to that of a real (admin)
user. As this address would then be used in the From header of various
emails, to which users could be tempted to reply to, the admin user would
unwillingly be spammed with such reply mails (including out-of-office
mails).

Instead, add an extra configuration setting app_email_noreply that is used
for the From header. Setting app_email_from remains being used for the SMTP
envelope.

diff --git a/development.ini b/development.ini
--- a/development.ini
+++ b/development.ini
@@ -24,13 +24,23 @@ pdebug = false
 ## validation and spam filtering in mail servers.                             ##
 ################################################################################
 
-## 'From' header for application emails. You can optionally add a name.
+## SMTP envelope sender for application emails.
+## This setting also provides the default for app_email_noreply.
 ## Default:
 #app_email_from = Kallithea
 ## Examples:
 #app_email_from = Kallithea <kallithea-noreply at example.com>
 #app_email_from = kallithea-noreply at example.com
 
+## 'From' header for application emails. You can optionally add a name.
+## Defaults to the value of app_email_from.
+## This setting is only useful if you cannot use the value of app_email_from
+## for app_email_noreply, for example because app_email_from is not an anonymous
+## address and you do not wish it to be visible to recipients of email.
+## Examples:
+#app_email_noreply = Kallithea <kallithea-noreply at example.com>
+#app_email_noreply = kallithea-noreply at example.com
+
 ## Subject prefix for application emails.
 ## A space between this prefix and the real subject is automatically added.
 ## Default:
diff --git a/docs/usage/email.rst b/docs/usage/email.rst
--- a/docs/usage/email.rst
+++ b/docs/usage/email.rst
@@ -35,14 +35,23 @@ When Kallithea wants to send an email bu
 determine the intended recipients, the administrators and the addresses
 specified in ``email_to`` in the configuration file are used as fallback.
 
-Recipients will see these emails originating from the sender specified in the
-``app_email_from`` setting in the configuration file. This setting can either
+The email address used as the SMTP envelope sender -- a technical address which
+is not visible to the recipients of the email -- is specified in the
+``app_email_from`` setting in the configuration file.  This setting can either
+contain only an email address, like `kallithea-noreply at example.com`, or both a
+name and an address in the following format: `Kallithea
+<kallithea-noreply at example.com>`.
+
+Recipients will see application emails originating from the sender specified in
+the ``app_email_noreply`` setting in the configuration file, which defaults to
+the value of ``app_email_from`` and thus normally need not be set explicitly if
+``app_email_from`` is already set. This setting can either
 contain only an email address, like `kallithea-noreply at example.com`, or both
 a name and an address in the following format: `Kallithea
 <kallithea-noreply at example.com>`. However, if the email is sent due to an
 action of a particular user, for example when a comment is given or a pull
 request created, the name of that user will be combined with the email address
-specified in ``app_email_from`` to form the sender (and any name part in that
+specified in ``app_email_noreply`` to form the sender (and any name part in that
 configuration setting disregarded).
 
 The subject of these emails can optionally be prefixed with the value of
diff --git a/kallithea/bin/template.ini.mako b/kallithea/bin/template.ini.mako
--- a/kallithea/bin/template.ini.mako
+++ b/kallithea/bin/template.ini.mako
@@ -18,13 +18,23 @@ pdebug = false
 <%text>## validation and spam filtering in mail servers.                             ##</%text>
 <%text>################################################################################</%text>
 
-<%text>## 'From' header for application emails. You can optionally add a name.</%text>
+<%text>## SMTP envelope sender for application emails.</%text>
+<%text>## This setting also provides the default for app_email_noreply.</%text>
 <%text>## Default:</%text>
 #app_email_from = Kallithea
 <%text>## Examples:</%text>
 #app_email_from = Kallithea <kallithea-noreply at example.com>
 #app_email_from = kallithea-noreply at example.com
 
+<%text>## 'From' header for application emails. You can optionally add a name.</%text>
+<%text>## Defaults to the value of app_email_from.</%text>
+<%text>## This setting is only useful if you cannot use the value of app_email_from</%text>
+<%text>## for app_email_noreply, for example because app_email_from is not an anonymous</%text>
+<%text>## address and you do not wish it to be visible to recipients of email.</%text>
+<%text>## Examples:</%text>
+#app_email_noreply = Kallithea <kallithea-noreply at example.com>
+#app_email_noreply = kallithea-noreply at example.com
+
 <%text>## Subject prefix for application emails.</%text>
 <%text>## A space between this prefix and the real subject is automatically added.</%text>
 <%text>## Default:</%text>
diff --git a/kallithea/config/deployment.ini_tmpl b/kallithea/config/deployment.ini_tmpl
--- a/kallithea/config/deployment.ini_tmpl
+++ b/kallithea/config/deployment.ini_tmpl
@@ -19,13 +19,23 @@ pdebug = false
 ## validation and spam filtering in mail servers.                             ##
 ################################################################################
 
-## 'From' header for application emails. You can optionally add a name.
+## SMTP envelope sender for application emails.
+## This setting also provides the default for app_email_noreply.
 ## Default:
 #app_email_from = Kallithea
 ## Examples:
 #app_email_from = Kallithea <kallithea-noreply at example.com>
 #app_email_from = kallithea-noreply at example.com
 
+## 'From' header for application emails. You can optionally add a name.
+## Defaults to the value of app_email_from.
+## This setting is only useful if you cannot use the value of app_email_from
+## for app_email_noreply, for example because app_email_from is not an anonymous
+## address and you do not wish it to be visible to recipients of email.
+## Examples:
+#app_email_noreply = Kallithea <kallithea-noreply at example.com>
+#app_email_noreply = kallithea-noreply at example.com
+
 ## Subject prefix for application emails.
 ## A space between this prefix and the real subject is automatically added.
 ## Default:
diff --git a/kallithea/lib/celerylib/tasks.py b/kallithea/lib/celerylib/tasks.py
--- a/kallithea/lib/celerylib/tasks.py
+++ b/kallithea/lib/celerylib/tasks.py
@@ -291,12 +291,15 @@ def send_email(recipients, subject, body
     # SMTP sender
     envelope_from = email_config.get('app_email_from', 'Kallithea')
     # 'From' header
-    if author is not None:
+    noreply_from = email_config.get('app_email_noreply', envelope_from)
+    if author is None:
+        headers['From'] = noreply_from
+    else:
         # set From header based on author but with a generic e-mail address
         # In case app_email_from is in "Some Name <e-mail>" format, we first
         # extract the e-mail address.
-        envelope_addr = author_email(envelope_from)
-        headers['From'] = '%s (no-reply) <%s>' % (author.full_name_or_username, envelope_addr)
+        noreply_addr = author_email(noreply_from)
+        headers['From'] = '%s (no-reply) <%s>' % (author.full_name_or_username, noreply_addr)
 
     user = email_config.get('smtp_username')
     passwd = email_config.get('smtp_password')
diff --git a/kallithea/tests/other/test_mail.py b/kallithea/tests/other/test_mail.py
--- a/kallithea/tests/other/test_mail.py
+++ b/kallithea/tests/other/test_mail.py
@@ -166,3 +166,53 @@ class TestMail(BaseTestCase):
         # verify that headers dict hasn't mutated by send_email
         self.assertDictEqual(headers, {'extra': 'yes'})
 
+    def test_send_mail_with_author_noreply(self):
+        mailserver = 'smtp.mailserver.org'
+        recipients = ['rcpt1', 'rcpt2']
+        envelope_from = 'noreply at mailserver.org'
+        noreply_addr = 'another at mailserver.org'
+        subject = 'subject'
+        body = 'body'
+        html_body = 'html_body'
+        author = User.get_by_username(TEST_USER_REGULAR_LOGIN)
+
+        config_mock = {
+            'smtp_server': mailserver,
+            'app_email_from': envelope_from,
+            'app_email_noreply': noreply_addr,
+        }
+        with mock.patch('kallithea.lib.celerylib.tasks.config', config_mock):
+            kallithea.lib.celerylib.tasks.send_email(recipients, subject, body, html_body, author=author)
+
+        self.assertSetEqual(smtplib_mock.lastdest, set(recipients))
+        self.assertEqual(smtplib_mock.lastsender, envelope_from)
+        self.assertIn('From: Kallithea Admin (no-reply) <%s>' % noreply_addr, smtplib_mock.lastmsg)
+        self.assertIn('Subject: %s' % subject, smtplib_mock.lastmsg)
+        self.assertIn(body, smtplib_mock.lastmsg)
+        self.assertIn(html_body, smtplib_mock.lastmsg)
+
+    def test_send_mail_with_author_full_mail_noreply(self):
+        mailserver = 'smtp.mailserver.org'
+        recipients = ['rcpt1', 'rcpt2']
+        envelope_from = 'noreply at mailserver.org'
+        noreply_addr = 'another at mailserver.org'
+        noreply_full = 'Some Name <%s>' % noreply_addr
+        subject = 'subject'
+        body = 'body'
+        html_body = 'html_body'
+        author = User.get_by_username(TEST_USER_REGULAR_LOGIN)
+
+        config_mock = {
+            'smtp_server': mailserver,
+            'app_email_from': envelope_from,
+            'app_email_noreply': noreply_full,
+        }
+        with mock.patch('kallithea.lib.celerylib.tasks.config', config_mock):
+            kallithea.lib.celerylib.tasks.send_email(recipients, subject, body, html_body, author=author)
+
+        self.assertSetEqual(smtplib_mock.lastdest, set(recipients))
+        self.assertEqual(smtplib_mock.lastsender, envelope_from)
+        self.assertIn('From: Kallithea Admin (no-reply) <%s>' % noreply_addr, smtplib_mock.lastmsg)
+        self.assertIn('Subject: %s' % subject, smtplib_mock.lastmsg)
+        self.assertIn(body, smtplib_mock.lastmsg)
+        self.assertIn(html_body, smtplib_mock.lastmsg)
diff --git a/kallithea/tests/test.ini b/kallithea/tests/test.ini
--- a/kallithea/tests/test.ini
+++ b/kallithea/tests/test.ini
@@ -23,13 +23,23 @@ pdebug = false
 ## validation and spam filtering in mail servers.                             ##
 ################################################################################
 
-## 'From' header for application emails. You can optionally add a name.
+## SMTP envelope sender for application emails.
+## This setting also provides the default for app_email_noreply.
 ## Default:
 #app_email_from = Kallithea
 ## Examples:
 #app_email_from = Kallithea <kallithea-noreply at example.com>
 #app_email_from = kallithea-noreply at example.com
 
+## 'From' header for application emails. You can optionally add a name.
+## Defaults to the value of app_email_from.
+## This setting is only useful if you cannot use the value of app_email_from
+## for app_email_noreply, for example because app_email_from is not an anonymous
+## address and you do not wish it to be visible to recipients of email.
+## Examples:
+#app_email_noreply = Kallithea <kallithea-noreply at example.com>
+#app_email_noreply = kallithea-noreply at example.com
+
 ## Subject prefix for application emails.
 ## A space between this prefix and the real subject is automatically added.
 ## Default:


More information about the kallithea-general mailing list