changeset 46991:83c0d144ef8d

mail: split out the SMTP login to allow the keyring extension to wrap it The keyring extension only needs to tweak this tiny section of the larger function. But without any place to intercept the username/password fetching, it copy/pasted the entire function, and has grown a bunch of compatibility hacks to support older versions of Mercurial as well. Differential Revision: https://phab.mercurial-scm.org/D10471
author Matt Harbison <matt_harbison@yahoo.com>
date Mon, 19 Apr 2021 17:26:57 -0400
parents 0b569c75d180
children 5fa019ceb499
files mercurial/mail.py
diffstat 1 files changed, 27 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/mail.py	Tue Apr 20 04:27:03 2021 +0200
+++ b/mercurial/mail.py	Mon Apr 19 17:26:57 2021 -0400
@@ -151,6 +151,32 @@
     if starttls or smtps:
         ui.note(_(b'(verifying remote certificate)\n'))
         sslutil.validatesocket(s.sock)
+
+    try:
+        _smtp_login(ui, s, mailhost, mailport)
+    except smtplib.SMTPException as inst:
+        raise error.Abort(stringutil.forcebytestr(inst))
+
+    def send(sender, recipients, msg):
+        try:
+            return s.sendmail(sender, recipients, msg)
+        except smtplib.SMTPRecipientsRefused as inst:
+            recipients = [r[1] for r in inst.recipients.values()]
+            raise error.Abort(b'\n' + b'\n'.join(recipients))
+        except smtplib.SMTPException as inst:
+            raise error.Abort(inst)
+
+    return send
+
+
+def _smtp_login(ui, smtp, mailhost, mailport):
+    """A hook for the keyring extension to perform the actual SMTP login.
+
+    An already connected SMTP object of the proper type is provided, based on
+    the current configuration.  The host and port to which the connection was
+    established are provided for accessibility, since the SMTP object doesn't
+    provide an accessor.  ``smtplib.SMTPException`` is raised on error.
+    """
     username = ui.config(b'smtp', b'username')
     password = ui.config(b'smtp', b'password')
     if username:
@@ -163,21 +189,7 @@
     if username and password:
         ui.note(_(b'(authenticating to mail server as %s)\n') % username)
         username = encoding.strfromlocal(username)
-        try:
-            s.login(username, password)
-        except smtplib.SMTPException as inst:
-            raise error.Abort(stringutil.forcebytestr(inst))
-
-    def send(sender, recipients, msg):
-        try:
-            return s.sendmail(sender, recipients, msg)
-        except smtplib.SMTPRecipientsRefused as inst:
-            recipients = [r[1] for r in inst.recipients.values()]
-            raise error.Abort(b'\n' + b'\n'.join(recipients))
-        except smtplib.SMTPException as inst:
-            raise error.Abort(inst)
-
-    return send
+        smtp.login(username, password)
 
 
 def _sendmail(ui, sender, recipients, msg):