Convert email address to ASCII to support RFC6530
Python email library does not support non-ASCII emails so we convert email addresses to ASCII version before passing them to sendmail. Closes #10650
This commit is contained in:
1 parent
66f10aed84
commit
13cedb53e8
5 files changed
+37
-19
No files matched your search
@@ -9,11 +9,18 @@ from trytond.pool import Pool, PoolMeta
|
||||
from trytond.pyson import Bool, Eval
|
||||
from trytond.report import get_email
|
||||
from trytond.sendmail import SMTPDataManager, sendmail_transactional
|
||||
from trytond.tools.email_ import set_from_header
|
||||
from trytond.tools.email_ import convert_ascii_email, set_from_header
|
||||
from trytond.transaction import Transaction
|
||||
from trytond.wizard import StateTransition
|
||||
|
||||
|
||||
def _formataddr(pair):
|
||||
name, address = pair
|
||||
if name:
|
||||
name = str(Header(name, 'utf-8'))
|
||||
return formataddr((name, convert_ascii_email(address)))
|
||||
|
||||
|
||||
class Configuration(metaclass=PoolMeta):
|
||||
__name__ = 'account.configuration'
|
||||
|
||||
@@ -117,12 +124,12 @@ class Dunning(metaclass=PoolMeta):
|
||||
contact = self.party.contact_mechanism_get(
|
||||
'email', usage=self.level.email_contact_mechanism)
|
||||
if contact and contact.email:
|
||||
name = str(Header(contact.name or self.party.rec_name))
|
||||
to.append(formataddr((name, contact.email)))
|
||||
name = contact.name or self.party.rec_name
|
||||
to.append(_formataddr((name, contact.email)))
|
||||
elif account_config.dunning_email_fallback:
|
||||
user = account_config.get_multivalue(
|
||||
'dunning_email_fallback', company=self.company.id)
|
||||
to.append(formataddr((self.party.rec_name, user.email)))
|
||||
to.append(_formataddr((self.party.rec_name, user.email)))
|
||||
cc = []
|
||||
bcc = []
|
||||
languages = set()
|
||||
|
||||
@@ -32,7 +32,7 @@ from trytond.pyson import Eval, If, PYSONDecoder, TimeDelta
|
||||
from trytond.report import Report
|
||||
from trytond.sendmail import SMTPDataManager, sendmail_transactional
|
||||
from trytond.tools import grouped_slice, reduce_ids
|
||||
from trytond.tools.email_ import set_from_header
|
||||
from trytond.tools.email_ import convert_ascii_email, set_from_header
|
||||
from trytond.transaction import Transaction
|
||||
from trytond.url import http_host
|
||||
from trytond.wsgi import Base64Converter
|
||||
@@ -55,7 +55,7 @@ logger = logging.getLogger(__name__)
|
||||
def _formataddr(name, email):
|
||||
if name:
|
||||
name = str(Header(name, 'utf-8'))
|
||||
return formataddr((name, email))
|
||||
return formataddr((name, convert_ascii_email(email)))
|
||||
|
||||
|
||||
class Scenario(Workflow, ModelSQL, ModelView):
|
||||
|
||||
@@ -31,7 +31,7 @@ from trytond.pyson import Eval
|
||||
from trytond.report import Report, get_email
|
||||
from trytond.sendmail import SMTPDataManager, sendmail_transactional
|
||||
from trytond.tools import grouped_slice, reduce_ids
|
||||
from trytond.tools.email_ import set_from_header
|
||||
from trytond.tools.email_ import convert_ascii_email, set_from_header
|
||||
from trytond.transaction import Transaction, inactive_records
|
||||
from trytond.url import http_host
|
||||
from trytond.wizard import Button, StateTransition, StateView, Wizard
|
||||
@@ -51,7 +51,7 @@ URL_OPEN = urljoin(URL_BASE, '/m/empty.gif')
|
||||
def _formataddr(name, email):
|
||||
if name:
|
||||
name = str(Header(name, 'utf-8'))
|
||||
return formataddr((name, email))
|
||||
return formataddr((name, convert_ascii_email(email)))
|
||||
|
||||
|
||||
def _add_params(url, **params):
|
||||
@@ -297,7 +297,8 @@ class EmailList(DeactivableMixin, ModelSQL, ModelView):
|
||||
set_from_header(msg, from_cfg, from_ or from_cfg)
|
||||
msg['To'] = record.email
|
||||
msg['Subject'] = Header(title, 'utf-8')
|
||||
sendmail_transactional(from_cfg, [record.email], msg)
|
||||
sendmail_transactional(
|
||||
from_cfg, [convert_ascii_email(record.email)], msg)
|
||||
|
||||
def request_unsubscribe(self, email, from_=None):
|
||||
pool = Pool()
|
||||
@@ -322,7 +323,8 @@ class EmailList(DeactivableMixin, ModelSQL, ModelView):
|
||||
set_from_header(msg, from_cfg, from_ or from_cfg)
|
||||
msg['To'] = record.email
|
||||
msg['Subject'] = Header(title, 'utf-8')
|
||||
sendmail_transactional(from_cfg, [record.email], msg)
|
||||
sendmail_transactional(
|
||||
from_cfg, [convert_ascii_email(record.email)], msg)
|
||||
|
||||
|
||||
class Message(Workflow, ModelSQL, ModelView):
|
||||
|
||||
@@ -6,7 +6,7 @@ from email.header import Header
|
||||
from email.mime.application import MIMEApplication
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.nonmultipart import MIMENonMultipart
|
||||
from email.utils import formataddr, getaddresses, parseaddr
|
||||
from email.utils import formataddr, getaddresses
|
||||
|
||||
from genshi.template import TextTemplate
|
||||
|
||||
@@ -17,7 +17,7 @@ from trytond.pool import Pool
|
||||
from trytond.pyson import Eval, TimeDelta
|
||||
from trytond.report import get_email
|
||||
from trytond.sendmail import SMTPDataManager, sendmail_transactional
|
||||
from trytond.tools.email_ import set_from_header
|
||||
from trytond.tools.email_ import convert_ascii_email, set_from_header
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
from .exceptions import TemplateError
|
||||
@@ -195,8 +195,12 @@ class Email(ModelSQL, ModelView):
|
||||
msg = content
|
||||
|
||||
set_from_header(msg, sender, from_)
|
||||
msg['To'] = ', '.join(formataddr(parseaddr(a)) for a in to)
|
||||
msg['Cc'] = ', '.join(formataddr(parseaddr(a)) for a in cc)
|
||||
msg['To'] = ', '.join(
|
||||
formataddr((n, convert_ascii_email(a)))
|
||||
for n, a in getaddresses(to))
|
||||
msg['Cc'] = ', '.join(
|
||||
formataddr((n, convert_ascii_email(a)))
|
||||
for n, a in getaddresses(cc))
|
||||
msg['Subject'] = Header(title, 'utf-8')
|
||||
msg['Auto-Submitted'] = 'auto-generated'
|
||||
return msg, title
|
||||
@@ -238,7 +242,8 @@ class Email(ModelSQL, ModelView):
|
||||
cc, cc_languages = self._get_cc(record)
|
||||
bcc, bcc_languages = self._get_bcc(record)
|
||||
languages = to_languages | cc_languages | bcc_languages
|
||||
to_addrs = [e for _, e in getaddresses(to + cc + bcc)]
|
||||
to_addrs = [
|
||||
convert_ascii_email(e) for _, e in getaddresses(to + cc + bcc)]
|
||||
if to_addrs:
|
||||
msg, title = self.get_email(
|
||||
record, from_, to, cc, bcc, languages)
|
||||
|
||||
@@ -27,7 +27,7 @@ from trytond.report import Report
|
||||
from trytond.rpc import RPC
|
||||
from trytond.sendmail import sendmail_transactional
|
||||
from trytond.tools import escape_wildcard
|
||||
from trytond.tools.email_ import set_from_header
|
||||
from trytond.tools.email_ import convert_ascii_email, set_from_header
|
||||
from trytond.tools.string_ import StringMatcher
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
@@ -56,7 +56,7 @@ def _get_emails(value):
|
||||
def _formataddr(pair):
|
||||
"Format address without encoding"
|
||||
name, address = pair
|
||||
address.encode('ascii')
|
||||
convert_ascii_email(address).encode('ascii')
|
||||
if name:
|
||||
quotes = ''
|
||||
if specialsre.search(name):
|
||||
@@ -167,8 +167,12 @@ class Email(ResourceAccessMixin, ModelSQL, ModelView):
|
||||
msg = content
|
||||
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['To'] = ', '.join(
|
||||
formataddr((n, convert_ascii_email(a)))
|
||||
for n, a in getaddresses([to]))
|
||||
msg['Cc'] = ', '.join(
|
||||
formataddr((n, convert_ascii_email(a)))
|
||||
for n, a in getaddresses([cc]))
|
||||
msg['Subject'] = Header(subject, 'utf-8')
|
||||
|
||||
to_addrs = list(filter(None, map(
|
||||
|
||||
Reference in new issue
Block a user