diff --git a/frappe/email/doctype/email_account/email_account.py b/frappe/email/doctype/email_account/email_account.py index 3b966a44ac..37c84cf12a 100755 --- a/frappe/email/doctype/email_account/email_account.py +++ b/frappe/email/doctype/email_account/email_account.py @@ -179,6 +179,7 @@ class EmailAccount(Document): ): if validate_oauth or self.password or self.smtp_server in ("127.0.0.1", "localhost"): if self.enable_incoming: + self.flags.validate_imap_pop_connection = True self.get_incoming_server() self.no_failed = 0 @@ -212,8 +213,9 @@ class EmailAccount(Document): if not self.smtp_server: frappe.throw(_("SMTP Server is required")) - server = self.get_smtp_server() - return server.session + self.flags.validate_smtp_connection = True + self.get_smtp_server().session + del self._smtp_server_instance def before_save(self): messages = [] @@ -304,6 +306,9 @@ class EmailAccount(Document): if not args.get("host"): frappe.throw(_("{0} is required").format("Email Server")) + if self.flags.validate_imap_pop_connection: + args.timeout = 15 + email_server = EmailServer(frappe._dict(args)) self.check_email_server_connection(email_server, in_receive) @@ -507,7 +512,7 @@ class EmailAccount(Document): return oauth_token.get_password("access_token") if oauth_token else None def sendmail_config(self): - return { + config = { "email_account": self.name, "server": self.smtp_server, "port": cint(self.smtp_port), @@ -519,6 +524,11 @@ class EmailAccount(Document): "access_token": self.get_access_token(), } + if self.flags.validate_smtp_connection: + config["timeout"] = 15 + + return config + def get_smtp_server(self): """Get SMTPServer (wrapper around actual smtplib object) for this account. diff --git a/frappe/email/doctype/email_domain/email_domain.py b/frappe/email/doctype/email_domain/email_domain.py index 32c9696b18..e57e04a24e 100644 --- a/frappe/email/doctype/email_domain/email_domain.py +++ b/frappe/email/doctype/email_domain/email_domain.py @@ -111,7 +111,7 @@ class EmailDomain(Document): conn_method = poplib.POP3_SSL if self.use_ssl else poplib.POP3 self.use_starttls = cint(self.use_imap and self.use_starttls and not self.use_ssl) - incoming_conn = conn_method(self.email_server, port=self.incoming_port, timeout=30) + incoming_conn = conn_method(self.email_server, port=self.incoming_port, timeout=15) incoming_conn.logout() if self.use_imap else incoming_conn.quit() @handle_error("outgoing") @@ -124,4 +124,4 @@ class EmailDomain(Document): elif self.use_tls: self.smtp_port = self.smtp_port or 587 - conn_method((self.smtp_server or ""), cint(self.smtp_port), timeout=30).quit() + conn_method((self.smtp_server or ""), cint(self.smtp_port), timeout=15).quit() diff --git a/frappe/email/receive.py b/frappe/email/receive.py index c962e71c82..ed941a75ad 100644 --- a/frappe/email/receive.py +++ b/frappe/email/receive.py @@ -69,7 +69,10 @@ class EmailServer: def __init__(self, args=None): self.retry_limit = 3 self.retry_count = 0 + self.settings = args or frappe._dict() + self.pop_timeout = self.settings.timeout or frappe.conf.pop_timeout + self.imap_timeout = self.settings.timeout or frappe.conf.imap_timeout def connect(self): """Connect to **Email Account**.""" @@ -82,12 +85,12 @@ class EmailServer: self.imap = imaplib.IMAP4_SSL( self.settings.host, self.settings.incoming_port, - timeout=frappe.conf.pop_timeout, + timeout=self.imap_timeout, ssl_context=ssl.create_default_context(), ) else: self.imap = imaplib.IMAP4( - self.settings.host, self.settings.incoming_port, timeout=frappe.conf.pop_timeout + self.settings.host, self.settings.incoming_port, timeout=self.imap_timeout ) if cint(self.settings.use_starttls): @@ -119,12 +122,12 @@ class EmailServer: self.pop = poplib.POP3_SSL( self.settings.host, self.settings.incoming_port, - timeout=frappe.conf.pop_timeout, + timeout=self.pop_timeout, context=ssl.create_default_context(), ) else: self.pop = poplib.POP3( - self.settings.host, self.settings.incoming_port, timeout=frappe.conf.pop_timeout + self.settings.host, self.settings.incoming_port, timeout=self.pop_timeout ) if self.settings.use_oauth: diff --git a/frappe/email/smtp.py b/frappe/email/smtp.py index e19afb56bf..1c782979e2 100644 --- a/frappe/email/smtp.py +++ b/frappe/email/smtp.py @@ -26,6 +26,7 @@ class SMTPServer: use_ssl=None, use_oauth=0, access_token=None, + timeout=2 * 60, ): self.login = login self.email_account = email_account @@ -37,6 +38,7 @@ class SMTPServer: self.use_oauth = use_oauth self.access_token = access_token self._session = None + self.timeout = timeout if not self.server: frappe.msgprint( @@ -72,7 +74,7 @@ class SMTPServer: SMTP = smtplib.SMTP_SSL if self.use_ssl else smtplib.SMTP try: - _session = SMTP(self.server, self.port, timeout=2 * 60) + _session = SMTP(self.server, self.port, timeout=self.timeout) if not _session: frappe.msgprint( _("Could not connect to outgoing email server"), raise_exception=frappe.OutgoingEmailError