We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
mail controlpanel: doesn't keep password field
Saving the mail settings in the controlpanel doesn't keep the password field value, as it is obviously never shown in ESMTP password.

Steps to reproduce:
1. Fill in ESMTP username and ESMTP password. Save settings. They are correctly stored.
2. Apply save settings again. ESMTP password is incorrectly stored as None.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `Products/CMFPlone/controlpanel/browser/mail.py`
Content:
```
1 from Products.CMFCore.utils import getToolByName
2 from Products.CMFPlone import PloneMessageFactory as _
3 from Products.CMFPlone.interfaces.controlpanel import IMailSchema
4 from Products.MailHost.MailHost import MailHostError
5 from Products.statusmessages.interfaces import IStatusMessage
6 from logging import getLogger
7 from plone.app.registry.browser import controlpanel
8 from plone.registry.interfaces import IRegistry
9 from z3c.form import button
10 from zope.component import getUtility
11 
12 import smtplib
13 import socket
14 import sys
15 
16 log = getLogger('Plone')
17 
18 
19 class MailControlPanelForm(controlpanel.RegistryEditForm):
20 
21     id = "MailControlPanel"
22     label = _(u"Mail Settings")
23     schema = IMailSchema
24     schema_prefix = "plone"
25 
26     @button.buttonAndHandler(_('Save'), name=None)
27     def handleSave(self, action):
28         self.save()
29 
30     @button.buttonAndHandler(_('Cancel'), name='cancel')
31     def handleCancel(self, action):
32         super(MailControlPanelForm, self).handleCancel(self, action)
33 
34     def save(self):
35         data, errors = self.extractData()
36         if errors:
37             self.status = self.formErrorsMessage
38             return False
39         self.applyChanges(data)
40         return True
41 
42     @button.buttonAndHandler(
43         _('label_smtp_test', default='Save and send test e-mail'),
44         name='test')
45     def handle_test_action(self, action):
46         # Save data first
47         if not self.save():
48             return
49         mailhost = getToolByName(self.context, 'MailHost')
50 
51         registry = getUtility(IRegistry)
52         mail_settings = registry.forInterface(IMailSchema, prefix='plone')
53         fromaddr = mail_settings.email_from_address
54         fromname = mail_settings.email_from_name
55 
56         message = ("Hi,\n\nThis is a test message sent from the Plone "
57                    "'Mail settings' control panel. Your receipt of this "
58                    "message (at the address specified in the Site 'From' "
59                    "address field) indicates that your e-mail server is "
60                    "working!\n\n"
61                    "Have a nice day.\n\n"
62                    "Love,\n\nPlone")
63         email_charset = mail_settings.email_charset
64         subject = "Test e-mail from Plone"
65 
66         # Make the timeout incredibly short. This is enough time for most mail
67         # servers, wherever they may be in the world, to respond to the
68         # connection request. Make sure we save the current value
69         # and restore it afterward.
70         timeout = socket.getdefaulttimeout()
71         try:
72             socket.setdefaulttimeout(3)
73             try:
74                 mailhost.send(message,
75                               mto=fromaddr,
76                               mfrom=fromaddr,
77                               subject=subject,
78                               charset=email_charset,
79                               immediate=True)
80 
81             except (socket.error, MailHostError, smtplib.SMTPException):
82                 # Connection refused or timeout.
83                 log.exception('Unable to send test e-mail.')
84                 value = sys.exc_info()[1]
85                 msg = _(u'Unable to send test e-mail ${error}.',
86                         mapping={'error': unicode(value)})
87                 IStatusMessage(self.request).addStatusMessage(
88                     msg, type='error')
89             else:
90                 IStatusMessage(self.request).addStatusMessage(
91                     _(u'Success! Check your mailbox for the test message.'),
92                     type='info')
93         finally:
94             # Restore timeout to default value
95             socket.setdefaulttimeout(timeout)
96 
97 
98 class MailControlPanel(controlpanel.ControlPanelFormWrapper):
99     form = MailControlPanelForm
100
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/Products/CMFPlone/controlpanel/browser/mail.py b/Products/CMFPlone/controlpanel/browser/mail.py
--- a/Products/CMFPlone/controlpanel/browser/mail.py
+++ b/Products/CMFPlone/controlpanel/browser/mail.py
@@ -36,6 +36,10 @@
         if errors:
             self.status = self.formErrorsMessage
             return False
+        #keep password field
+        if (data.get('smtp_userid') is not None
+            and data.get('smtp_pass') is None):
+            del data['smtp_pass']
         self.applyChanges(data)
         return True

{"golden_diff": "diff --git a/Products/CMFPlone/controlpanel/browser/mail.py b/Products/CMFPlone/controlpanel/browser/mail.py\n--- a/Products/CMFPlone/controlpanel/browser/mail.py\n+++ b/Products/CMFPlone/controlpanel/browser/mail.py\n@@ -36,6 +36,10 @@\n         if errors:\n             self.status = self.formErrorsMessage\n             return False\n+        #keep password field\n+        if (data.get('smtp_userid') is not None\n+            and data.get('smtp_pass') is None):\n+            del data['smtp_pass']\n         self.applyChanges(data)\n         return True\n", "issue": "mail controlpanel: doesn't keep password field\nSaving the mail settings in the controlpanel doesn't keep the password field value, as it is obviously never shown in ESMTP password.\n\nSteps to reproduce:\n1. Fill in ESMTP username and ESMTP password. Save settings. They are correctly stored.\n2. Apply save settings again. ESMTP password is incorrectly stored as None.\n\n", "before_files": [{"content": "from Products.CMFCore.utils import getToolByName\nfrom Products.CMFPlone import PloneMessageFactory as _\nfrom Products.CMFPlone.interfaces.controlpanel import IMailSchema\nfrom Products.MailHost.MailHost import MailHostError\nfrom Products.statusmessages.interfaces import IStatusMessage\nfrom logging import getLogger\nfrom plone.app.registry.browser import controlpanel\nfrom plone.registry.interfaces import IRegistry\nfrom z3c.form import button\nfrom zope.component import getUtility\n\nimport smtplib\nimport socket\nimport sys\n\nlog = getLogger('Plone')\n\n\nclass MailControlPanelForm(controlpanel.RegistryEditForm):\n\n    id = \"MailControlPanel\"\n    label = _(u\"Mail Settings\")\n    schema = IMailSchema\n    schema_prefix = \"plone\"\n\n    @button.buttonAndHandler(_('Save'), name=None)\n    def handleSave(self, action):\n        self.save()\n\n    @button.buttonAndHandler(_('Cancel'), name='cancel')\n    def handleCancel(self, action):\n        super(MailControlPanelForm, self).handleCancel(self, action)\n\n    def save(self):\n        data, errors = self.extractData()\n        if errors:\n            self.status = self.formErrorsMessage\n            return False\n        self.applyChanges(data)\n        return True\n\n    @button.buttonAndHandler(\n        _('label_smtp_test', default='Save and send test e-mail'),\n        name='test')\n    def handle_test_action(self, action):\n        # Save data first\n        if not self.save():\n            return\n        mailhost = getToolByName(self.context, 'MailHost')\n\n        registry = getUtility(IRegistry)\n        mail_settings = registry.forInterface(IMailSchema, prefix='plone')\n        fromaddr = mail_settings.email_from_address\n        fromname = mail_settings.email_from_name\n\n        message = (\"Hi,\\n\\nThis is a test message sent from the Plone \"\n                   \"'Mail settings' control panel. Your receipt of this \"\n                   \"message (at the address specified in the Site 'From' \"\n                   \"address field) indicates that your e-mail server is \"\n                   \"working!\\n\\n\"\n                   \"Have a nice day.\\n\\n\"\n                   \"Love,\\n\\nPlone\")\n        email_charset = mail_settings.email_charset\n        subject = \"Test e-mail from Plone\"\n\n        # Make the timeout incredibly short. This is enough time for most mail\n        # servers, wherever they may be in the world, to respond to the\n        # connection request. Make sure we save the current value\n        # and restore it afterward.\n        timeout = socket.getdefaulttimeout()\n        try:\n            socket.setdefaulttimeout(3)\n            try:\n                mailhost.send(message,\n                              mto=fromaddr,\n                              mfrom=fromaddr,\n                              subject=subject,\n                              charset=email_charset,\n                              immediate=True)\n\n            except (socket.error, MailHostError, smtplib.SMTPException):\n                # Connection refused or timeout.\n                log.exception('Unable to send test e-mail.')\n                value = sys.exc_info()[1]\n                msg = _(u'Unable to send test e-mail ${error}.',\n                        mapping={'error': unicode(value)})\n                IStatusMessage(self.request).addStatusMessage(\n                    msg, type='error')\n            else:\n                IStatusMessage(self.request).addStatusMessage(\n                    _(u'Success! Check your mailbox for the test message.'),\n                    type='info')\n        finally:\n            # Restore timeout to default value\n            socket.setdefaulttimeout(timeout)\n\n\nclass MailControlPanel(controlpanel.ControlPanelFormWrapper):\n    form = MailControlPanelForm\n", "path": "Products/CMFPlone/controlpanel/browser/mail.py"}], "after_files": [{"content": "from Products.CMFCore.utils import getToolByName\nfrom Products.CMFPlone import PloneMessageFactory as _\nfrom Products.CMFPlone.interfaces.controlpanel import IMailSchema\nfrom Products.MailHost.MailHost import MailHostError\nfrom Products.statusmessages.interfaces import IStatusMessage\nfrom logging import getLogger\nfrom plone.app.registry.browser import controlpanel\nfrom plone.registry.interfaces import IRegistry\nfrom z3c.form import button\nfrom zope.component import getUtility\n\nimport smtplib\nimport socket\nimport sys\n\nlog = getLogger('Plone')\n\n\nclass MailControlPanelForm(controlpanel.RegistryEditForm):\n\n    id = \"MailControlPanel\"\n    label = _(u\"Mail Settings\")\n    schema = IMailSchema\n    schema_prefix = \"plone\"\n\n    @button.buttonAndHandler(_('Save'), name=None)\n    def handleSave(self, action):\n        self.save()\n\n    @button.buttonAndHandler(_('Cancel'), name='cancel')\n    def handleCancel(self, action):\n        super(MailControlPanelForm, self).handleCancel(self, action)\n\n    def save(self):\n        data, errors = self.extractData()\n        if errors:\n            self.status = self.formErrorsMessage\n            return False\n        #keep password field\n        if (data.get('smtp_userid') is not None\n            and data.get('smtp_pass') is None):\n            del data['smtp_pass']\n        self.applyChanges(data)\n        return True\n\n    @button.buttonAndHandler(\n        _('label_smtp_test', default='Save and send test e-mail'),\n        name='test')\n    def handle_test_action(self, action):\n        # Save data first\n        if not self.save():\n            return\n        mailhost = getToolByName(self.context, 'MailHost')\n\n        registry = getUtility(IRegistry)\n        mail_settings = registry.forInterface(IMailSchema, prefix='plone')\n        fromaddr = mail_settings.email_from_address\n        fromname = mail_settings.email_from_name\n\n        message = (\"Hi,\\n\\nThis is a test message sent from the Plone \"\n                   \"'Mail settings' control panel. Your receipt of this \"\n                   \"message (at the address specified in the Site 'From' \"\n                   \"address field) indicates that your e-mail server is \"\n                   \"working!\\n\\n\"\n                   \"Have a nice day.\\n\\n\"\n                   \"Love,\\n\\nPlone\")\n        email_charset = mail_settings.email_charset\n        subject = \"Test e-mail from Plone\"\n\n        # Make the timeout incredibly short. This is enough time for most mail\n        # servers, wherever they may be in the world, to respond to the\n        # connection request. Make sure we save the current value\n        # and restore it afterward.\n        timeout = socket.getdefaulttimeout()\n        try:\n            socket.setdefaulttimeout(3)\n            try:\n                mailhost.send(message,\n                              mto=fromaddr,\n                              mfrom=fromaddr,\n                              subject=subject,\n                              charset=email_charset,\n                              immediate=True)\n\n            except (socket.error, MailHostError, smtplib.SMTPException):\n                # Connection refused or timeout.\n                log.exception('Unable to send test e-mail.')\n                value = sys.exc_info()[1]\n                msg = _(u'Unable to send test e-mail ${error}.',\n                        mapping={'error': unicode(value)})\n                IStatusMessage(self.request).addStatusMessage(\n                    msg, type='error')\n            else:\n                IStatusMessage(self.request).addStatusMessage(\n                    _(u'Success! Check your mailbox for the test message.'),\n                    type='info')\n        finally:\n            # Restore timeout to default value\n            socket.setdefaulttimeout(timeout)\n\n\nclass MailControlPanel(controlpanel.ControlPanelFormWrapper):\n    form = MailControlPanelForm\n", "path": "Products/CMFPlone/controlpanel/browser/mail.py"}]}