comparison mercurial/mail.py @ 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 d467bae86b2d
children 5fa019ceb499
comparison
equal deleted inserted replaced
46990:0b569c75d180 46991:83c0d144ef8d
149 s.starttls() 149 s.starttls()
150 s.ehlo() 150 s.ehlo()
151 if starttls or smtps: 151 if starttls or smtps:
152 ui.note(_(b'(verifying remote certificate)\n')) 152 ui.note(_(b'(verifying remote certificate)\n'))
153 sslutil.validatesocket(s.sock) 153 sslutil.validatesocket(s.sock)
154
155 try:
156 _smtp_login(ui, s, mailhost, mailport)
157 except smtplib.SMTPException as inst:
158 raise error.Abort(stringutil.forcebytestr(inst))
159
160 def send(sender, recipients, msg):
161 try:
162 return s.sendmail(sender, recipients, msg)
163 except smtplib.SMTPRecipientsRefused as inst:
164 recipients = [r[1] for r in inst.recipients.values()]
165 raise error.Abort(b'\n' + b'\n'.join(recipients))
166 except smtplib.SMTPException as inst:
167 raise error.Abort(inst)
168
169 return send
170
171
172 def _smtp_login(ui, smtp, mailhost, mailport):
173 """A hook for the keyring extension to perform the actual SMTP login.
174
175 An already connected SMTP object of the proper type is provided, based on
176 the current configuration. The host and port to which the connection was
177 established are provided for accessibility, since the SMTP object doesn't
178 provide an accessor. ``smtplib.SMTPException`` is raised on error.
179 """
154 username = ui.config(b'smtp', b'username') 180 username = ui.config(b'smtp', b'username')
155 password = ui.config(b'smtp', b'password') 181 password = ui.config(b'smtp', b'password')
156 if username: 182 if username:
157 if password: 183 if password:
158 password = encoding.strfromlocal(password) 184 password = encoding.strfromlocal(password)
161 if password is not None: 187 if password is not None:
162 password = encoding.strfromlocal(password) 188 password = encoding.strfromlocal(password)
163 if username and password: 189 if username and password:
164 ui.note(_(b'(authenticating to mail server as %s)\n') % username) 190 ui.note(_(b'(authenticating to mail server as %s)\n') % username)
165 username = encoding.strfromlocal(username) 191 username = encoding.strfromlocal(username)
166 try: 192 smtp.login(username, password)
167 s.login(username, password)
168 except smtplib.SMTPException as inst:
169 raise error.Abort(stringutil.forcebytestr(inst))
170
171 def send(sender, recipients, msg):
172 try:
173 return s.sendmail(sender, recipients, msg)
174 except smtplib.SMTPRecipientsRefused as inst:
175 recipients = [r[1] for r in inst.recipients.values()]
176 raise error.Abort(b'\n' + b'\n'.join(recipients))
177 except smtplib.SMTPException as inst:
178 raise error.Abort(inst)
179
180 return send
181 193
182 194
183 def _sendmail(ui, sender, recipients, msg): 195 def _sendmail(ui, sender, recipients, msg):
184 '''send mail using sendmail.''' 196 '''send mail using sendmail.'''
185 program = ui.config(b'email', b'method') 197 program = ui.config(b'email', b'method')