# Copyright 2017 LasLabs Inc. # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). from email.utils import formataddr, parseaddr from odoo import _, api, fields, models, tools from odoo.exceptions import ValidationError class IrMailServer(models.Model): _inherit = "ir.mail_server" smtp_from = fields.Char( string="Email From", help="Set this in order to email from a specific address." " If the original message's 'From' does not match with the domain" " whitelist then it is replaced with this value. If does match with the" " domain whitelist then the original message's 'From' will not change", ) domain_whitelist = fields.Char( help="Allowed Domains list separated by commas. If there is not given" " SMTP server it will let us to search the proper mail server to be" " used to sent the messages where the message 'From' email domain" " match with the domain whitelist." ) @api.constrains("domain_whitelist") def check_valid_domain_whitelist(self): if self.domain_whitelist: values = False try: values = list(self.domain_whitelist.split(",")) except Exception: pass if not isinstance(values, list): raise ValidationError( _("Please define a list of domains separate by comma") ) @api.model def _get_domain_whitelist(self, domain_whitelist_string): res = domain_whitelist_string.split(",") if domain_whitelist_string else [] res = [item.strip() for item in res] return res @api.model def send_email( self, message, mail_server_id=None, smtp_server=None, *args, **kwargs ): # Get email_from and name_from if message["From"].count("<") > 1: split_from = message["From"].rsplit(" <", 1) name_from = split_from[0] email_from = split_from[-1].replace(">", "") else: name_from, email_from = parseaddr(message["From"]) email_domain = email_from.split("@")[1] # Replicate logic from core to get mail server # Get proper mail server to use if not smtp_server and not mail_server_id: mail_server_id = self._get_mail_sever(email_domain) # If not mail sever defined use smtp_from defined in odoo config if mail_server_id: mail_server = self.sudo().browse(mail_server_id) domain_whitelist = mail_server.domain_whitelist smtp_from = mail_server.smtp_from else: domain_whitelist = tools.config.get("smtp_domain_whitelist") smtp_from = tools.config.get("smtp_from") domain_whitelist = self._get_domain_whitelist(domain_whitelist) # Replace the From only if needed if smtp_from and (not domain_whitelist or email_domain not in domain_whitelist): email_from = formataddr((name_from, smtp_from)) message.replace_header("From", email_from) bounce_alias = ( self.env["ir.config_parameter"].sudo().get_param("mail.bounce.alias") ) if not bounce_alias: # then, bounce handling is disabled and we want # Return-Path = From if "Return-Path" in message: message.replace_header("Return-Path", email_from) else: message.add_header("Return-Path", email_from) return super(IrMailServer, self).send_email( message, mail_server_id, smtp_server, *args, **kwargs ) @tools.ormcache("email_domain") def _get_mail_sever(self, email_domain): """ return the mail server id that match with the domain_whitelist If not match then return the default mail server id available one """ mail_server_id = None for item in self.sudo().search( [("domain_whitelist", "!=", False)], order="sequence" ): domain_whitelist = self._get_domain_whitelist(item.domain_whitelist) if email_domain in domain_whitelist: mail_server_id = item.id break if not mail_server_id: mail_server_id = self.sudo().search([], order="sequence", limit=1).id return mail_server_id @api.model def create(self, values): self.clear_caches() return super().create(values) def write(self, values): self.clear_caches() return super().write(values) def unlink(self): self.clear_caches() return super().unlink()