From fdcc82839543d636c1270ecf9fb166c347d01e21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Sun, 26 Sep 2021 23:11:21 +0200 Subject: [PATCH] Add set_from_header in email tools issue10753 review377121002 --- CHANGELOG | 1 + doc/ref/tools/email.rst | 10 ++++++++++ doc/ref/tools/index.rst | 1 + trytond/ir/email_.py | 11 +++-------- trytond/res/user.py | 3 ++- trytond/tools/email_.py | 23 +++++++++++++++++++++++ 6 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 doc/ref/tools/email.rst create mode 100644 trytond/tools/email_.py diff --git a/CHANGELOG b/CHANGELOG index a10256266a..d982e7b5de 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Add set_from_header in email tools * Add grouping attribute to numeric widgets * Ensure with a test that objects in the Pool have __slots__ * Use bigdecimal tag for XML-RPC diff --git a/doc/ref/tools/email.rst b/doc/ref/tools/email.rst new file mode 100644 index 0000000000..452d7d35d4 --- /dev/null +++ b/doc/ref/tools/email.rst @@ -0,0 +1,10 @@ +.. _ref-tools-email_: +.. module:: trytond.tools.email_ + +===== +Email +===== + +.. method:: set_from_header(message, sender, from\_) + +Fill email headers to appear at best from the address. diff --git a/doc/ref/tools/index.rst b/doc/ref/tools/index.rst index 80ce14bc16..d74ac88241 100644 --- a/doc/ref/tools/index.rst +++ b/doc/ref/tools/index.rst @@ -10,5 +10,6 @@ Tools API reference. :maxdepth: 1 misc + email singleton immutabledict diff --git a/trytond/ir/email_.py b/trytond/ir/email_.py index b066895e6c..5e2f0f18e4 100644 --- a/trytond/ir/email_.py +++ b/trytond/ir/email_.py @@ -28,6 +28,7 @@ from trytond.rpc import RPC from trytond.sendmail import sendmail_transactional, SMTPDataManager from trytond.tools import escape_wildcard from trytond.tools.string_ import StringMatcher +from trytond.tools.email_ import set_from_header from trytond.transaction import Transaction from .resource import ResourceAccessMixin @@ -164,14 +165,8 @@ class Email(ResourceAccessMixin, ModelSQL, ModelView): msg.attach(attachment) else: msg = content - msg['From'] = from_ = config.get('email', 'from') - if user.email: - if user.name: - user_email = formataddr((user.name, user.email)) - else: - user_email = user.email - msg['Behalf-Of'] = user_email - msg['Reply-To'] = user_email + from_ = config.get('email', 'from') + set_from_header(msg, from_, user.email or from_) msg['To'] = ', '.join(formataddr(a) for a in getaddresses([to])) msg['Cc'] = ', '.join(formataddr(a) for a in getaddresses([cc])) msg['Subject'] = Header(subject, 'utf-8') diff --git a/trytond/res/user.py b/trytond/res/user.py index 01f68c1599..51bdcad48a 100644 --- a/trytond/res/user.py +++ b/trytond/res/user.py @@ -55,6 +55,7 @@ from trytond.report import Report, get_email from trytond.rpc import RPC from trytond.sendmail import sendmail_transactional from trytond.tools import grouped_slice +from trytond.tools.email_ import set_from_header from trytond.transaction import Transaction from trytond.url import host, http_host from trytond.wizard import Wizard, StateView, Button, StateTransition @@ -93,7 +94,7 @@ def _send_email(from_, users, email_func): logger.info("Missing address for '%s' to send email", user.login) continue msg, title = email_func(user) - msg['From'] = from_ or from_cfg + set_from_header(msg, from_cfg, from_ or from_cfg) msg['To'] = user.email msg['Subject'] = Header(title, 'utf-8') sendmail_transactional(from_cfg, [user.email], msg) diff --git a/trytond/tools/email_.py b/trytond/tools/email_.py new file mode 100644 index 0000000000..f8141ec84d --- /dev/null +++ b/trytond/tools/email_.py @@ -0,0 +1,23 @@ +# This file is part of Tryton. The COPYRIGHT file at the top level of +# this repository contains the full copyright notices and license terms. +from email.utils import parseaddr + + +def _domainaddr(address): + _, email = parseaddr(address) + if '@' in email: + return email.split('@', 1)[1] + + +def set_from_header(message, sender, from_): + "Fill email headers to appear at best from the address" + if parseaddr(sender)[1] != parseaddr(from_)[1]: + if _domainaddr(sender) == _domainaddr(from_): + message['From'] = from_ + message['Sender'] = sender + else: + message['From'] = sender + message['On-Behalf-Of'] = from_ + message['Reply-To'] = from_ + else: + message['From'] = from_