diff --git a/addons/microsoft_outlook/models/ir_mail_server.py b/addons/microsoft_outlook/models/ir_mail_server.py index e988569fd6371..41a5a74671513 100644 --- a/addons/microsoft_outlook/models/ir_mail_server.py +++ b/addons/microsoft_outlook/models/ir_mail_server.py @@ -2,10 +2,15 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. import base64 +import smtplib +import threading -from odoo import _, api, models + +from odoo import api, models, tools, _ from odoo.exceptions import UserError +SMTP_TIMEOUT = 60 + class IrMailServer(models.Model): """Add the Outlook OAuth authentication on the outgoing mail servers.""" @@ -52,11 +57,62 @@ def _onchange_use_microsoft_outlook_service(self): self.microsoft_outlook_access_token = False self.microsoft_outlook_access_token_expiration = False - def _smtp_login(self, connection, smtp_user, smtp_password): - if len(self) == 1 and self.use_microsoft_outlook_service: - auth_string = self._generate_outlook_oauth2_string(smtp_user) - oauth_param = base64.b64encode(auth_string.encode()).decode() - connection.ehlo() - connection.docmd('AUTH', 'XOAUTH2 %s' % oauth_param) + def connect(self, host=None, port=None, user=None, password=None, + encryption=None, smtp_debug=False, mail_server_id=None): + # Do not actually connect while running in test mode + if getattr(threading.currentThread(), 'testing', False): + return None + if not (len(self) == 1 and self.use_microsoft_outlook_service): + return super(IrMailServer, self).connect( + host, port, user, password, encryption, smtp_debug, + mail_server_id) + mail_server = None + if mail_server_id: + mail_server = self.sudo().browse(mail_server_id) + + elif not host: + mail_server = self.sudo().search([], order='sequence', limit=1) + + if mail_server: + smtp_server = mail_server.smtp_host + smtp_port = mail_server.smtp_port + smtp_user = mail_server.smtp_user + smtp_encryption = mail_server.smtp_encryption + smtp_debug = smtp_debug or mail_server.smtp_debug else: - super()._smtp_login(connection, smtp_user, smtp_password) + smtp_server = host or tools.config.get('smtp_server') + smtp_port = tools.config.get('smtp_port', + 25) if port is None else port + smtp_user = user or tools.config.get('smtp_user') + smtp_encryption = encryption + if smtp_encryption is None and tools.config.get('smtp_ssl'): + smtp_encryption = 'starttls' # smtp_ssl => STARTTLS as of v7 + + if not smtp_server: + raise UserError( + (_("Missing SMTP Server") + "\n" + + _("Please define at least one SMTP server, " + "or provide the SMTP parameters explicitly."))) + + if smtp_encryption == 'ssl': + if 'SMTP_SSL' not in smtplib.__all__: + raise UserError( + _("Your Odoo Server does not support SMTP-over-SSL. " + "You could use STARTTLS instead. " + "If SSL is needed, an upgrade to Python 2.6 on the server-side " + "should do the trick.")) + connection = smtplib.SMTP_SSL(smtp_server, smtp_port, + timeout=SMTP_TIMEOUT) + else: + connection = smtplib.SMTP(smtp_server, smtp_port, + timeout=SMTP_TIMEOUT) + connection.set_debuglevel(smtp_debug) + if smtp_encryption == 'starttls': + connection.starttls() + + auth_string = self._generate_outlook_oauth2_string(smtp_user) + oauth_param = base64.b64encode(auth_string.encode()).decode() + connection.ehlo() + connection.docmd('AUTH', 'XOAUTH2 %s' % oauth_param) + return connection +