We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Passwords complexity
We must ensure passwords respect a minimum complexity.

See https://github.com/modoboa/modoboa-admin/issues/27


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `modoboa/core/forms.py`
Content:
```
1 # coding: utf-8
2 
3 """Core forms."""
4 
5 from django import forms
6 from django.utils.translation import ugettext as _, ugettext_lazy
7 
8 from modoboa.core.models import User
9 from modoboa.lib import parameters
10 
11 
12 class LoginForm(forms.Form):
13     username = forms.CharField(
14         label=ugettext_lazy("Username"),
15         widget=forms.TextInput(attrs={"class": "form-control"})
16     )
17     password = forms.CharField(
18         label=ugettext_lazy("Password"),
19         widget=forms.PasswordInput(attrs={"class": "form-control"})
20     )
21     rememberme = forms.BooleanField(
22         initial=False,
23         required=False
24     )
25 
26 
27 class ProfileForm(forms.ModelForm):
28     oldpassword = forms.CharField(
29         label=ugettext_lazy("Old password"), required=False,
30         widget=forms.PasswordInput(attrs={"class": "form-control"})
31     )
32     newpassword = forms.CharField(
33         label=ugettext_lazy("New password"), required=False,
34         widget=forms.PasswordInput(attrs={"class": "form-control"})
35     )
36     confirmation = forms.CharField(
37         label=ugettext_lazy("Confirmation"), required=False,
38         widget=forms.PasswordInput(attrs={"class": "form-control"})
39     )
40 
41     class Meta:
42         model = User
43         fields = ("first_name", "last_name")
44         widgets = {
45             'first_name': forms.TextInput(attrs={'class': 'form-control'}),
46             'last_name': forms.TextInput(attrs={'class': 'form-control'})
47         }
48 
49     def __init__(self, update_password, *args, **kwargs):
50         super(ProfileForm, self).__init__(*args, **kwargs)
51         if not update_password:
52             del self.fields["oldpassword"]
53             del self.fields["newpassword"]
54             del self.fields["confirmation"]
55 
56     def clean_oldpassword(self):
57         if self.cleaned_data["oldpassword"] == "":
58             return self.cleaned_data["oldpassword"]
59 
60         if parameters.get_admin("AUTHENTICATION_TYPE") != "local":
61             return self.cleaned_data["oldpassword"]
62 
63         if not self.instance.check_password(self.cleaned_data["oldpassword"]):
64             raise forms.ValidationError(_("Old password mismatchs"))
65         return self.cleaned_data["oldpassword"]
66 
67     def clean_confirmation(self):
68         newpassword = self.cleaned_data["newpassword"]
69         confirmation = self.cleaned_data["confirmation"]
70         if newpassword != confirmation:
71             raise forms.ValidationError(_("Passwords mismatch"))
72         return self.cleaned_data["confirmation"]
73 
74     def save(self, commit=True):
75         user = super(ProfileForm, self).save(commit=False)
76         if commit:
77             if self.cleaned_data.get("confirmation", "") != "":
78                 user.set_password(
79                     self.cleaned_data["confirmation"],
80                     self.cleaned_data["oldpassword"]
81                 )
82             user.save()
83         return user
84
```

Path: `modoboa/core/dev_settings.py`
Content:
```
1 # Development settings
2 import os
3 
4 BOWER_COMPONENTS_ROOT = os.path.join(
5     os.path.dirname(__file__), ".."
6 )
7 
8 BOWER_INSTALLED_APPS = (
9     "jquery#1.9",
10     "jquery-ui#1.11",
11     "bootstrap#3.3.1",
12     "bootstrap-select#1.6",
13     "d3#3.5.0",
14     "eonasdan-bootstrap-datetimepicker#3.1.3",
15     "font-awesome#4.2.0",
16     "c3#0.4.10",
17 )
18
```
--- 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/modoboa/core/dev_settings.py b/modoboa/core/dev_settings.py
--- a/modoboa/core/dev_settings.py
+++ b/modoboa/core/dev_settings.py
@@ -8,7 +8,7 @@
 BOWER_INSTALLED_APPS = (
     "jquery#1.9",
     "jquery-ui#1.11",
-    "bootstrap#3.3.1",
+    "bootstrap#3.3.5",
     "bootstrap-select#1.6",
     "d3#3.5.0",
     "eonasdan-bootstrap-datetimepicker#3.1.3",
diff --git a/modoboa/core/forms.py b/modoboa/core/forms.py
--- a/modoboa/core/forms.py
+++ b/modoboa/core/forms.py
@@ -5,6 +5,8 @@
 from django import forms
 from django.utils.translation import ugettext as _, ugettext_lazy
 
+from passwords.fields import PasswordField
+
 from modoboa.core.models import User
 from modoboa.lib import parameters
 
@@ -29,11 +31,11 @@
         label=ugettext_lazy("Old password"), required=False,
         widget=forms.PasswordInput(attrs={"class": "form-control"})
     )
-    newpassword = forms.CharField(
+    newpassword = PasswordField(
         label=ugettext_lazy("New password"), required=False,
         widget=forms.PasswordInput(attrs={"class": "form-control"})
     )
-    confirmation = forms.CharField(
+    confirmation = PasswordField(
         label=ugettext_lazy("Confirmation"), required=False,
         widget=forms.PasswordInput(attrs={"class": "form-control"})
     )

{"golden_diff": "diff --git a/modoboa/core/dev_settings.py b/modoboa/core/dev_settings.py\n--- a/modoboa/core/dev_settings.py\n+++ b/modoboa/core/dev_settings.py\n@@ -8,7 +8,7 @@\n BOWER_INSTALLED_APPS = (\n     \"jquery#1.9\",\n     \"jquery-ui#1.11\",\n-    \"bootstrap#3.3.1\",\n+    \"bootstrap#3.3.5\",\n     \"bootstrap-select#1.6\",\n     \"d3#3.5.0\",\n     \"eonasdan-bootstrap-datetimepicker#3.1.3\",\ndiff --git a/modoboa/core/forms.py b/modoboa/core/forms.py\n--- a/modoboa/core/forms.py\n+++ b/modoboa/core/forms.py\n@@ -5,6 +5,8 @@\n from django import forms\n from django.utils.translation import ugettext as _, ugettext_lazy\n \n+from passwords.fields import PasswordField\n+\n from modoboa.core.models import User\n from modoboa.lib import parameters\n \n@@ -29,11 +31,11 @@\n         label=ugettext_lazy(\"Old password\"), required=False,\n         widget=forms.PasswordInput(attrs={\"class\": \"form-control\"})\n     )\n-    newpassword = forms.CharField(\n+    newpassword = PasswordField(\n         label=ugettext_lazy(\"New password\"), required=False,\n         widget=forms.PasswordInput(attrs={\"class\": \"form-control\"})\n     )\n-    confirmation = forms.CharField(\n+    confirmation = PasswordField(\n         label=ugettext_lazy(\"Confirmation\"), required=False,\n         widget=forms.PasswordInput(attrs={\"class\": \"form-control\"})\n     )\n", "issue": "Passwords complexity\nWe must ensure passwords respect a minimum complexity.\n\nSee https://github.com/modoboa/modoboa-admin/issues/27\n\n", "before_files": [{"content": "# coding: utf-8\n\n\"\"\"Core forms.\"\"\"\n\nfrom django import forms\nfrom django.utils.translation import ugettext as _, ugettext_lazy\n\nfrom modoboa.core.models import User\nfrom modoboa.lib import parameters\n\n\nclass LoginForm(forms.Form):\n    username = forms.CharField(\n        label=ugettext_lazy(\"Username\"),\n        widget=forms.TextInput(attrs={\"class\": \"form-control\"})\n    )\n    password = forms.CharField(\n        label=ugettext_lazy(\"Password\"),\n        widget=forms.PasswordInput(attrs={\"class\": \"form-control\"})\n    )\n    rememberme = forms.BooleanField(\n        initial=False,\n        required=False\n    )\n\n\nclass ProfileForm(forms.ModelForm):\n    oldpassword = forms.CharField(\n        label=ugettext_lazy(\"Old password\"), required=False,\n        widget=forms.PasswordInput(attrs={\"class\": \"form-control\"})\n    )\n    newpassword = forms.CharField(\n        label=ugettext_lazy(\"New password\"), required=False,\n        widget=forms.PasswordInput(attrs={\"class\": \"form-control\"})\n    )\n    confirmation = forms.CharField(\n        label=ugettext_lazy(\"Confirmation\"), required=False,\n        widget=forms.PasswordInput(attrs={\"class\": \"form-control\"})\n    )\n\n    class Meta:\n        model = User\n        fields = (\"first_name\", \"last_name\")\n        widgets = {\n            'first_name': forms.TextInput(attrs={'class': 'form-control'}),\n            'last_name': forms.TextInput(attrs={'class': 'form-control'})\n        }\n\n    def __init__(self, update_password, *args, **kwargs):\n        super(ProfileForm, self).__init__(*args, **kwargs)\n        if not update_password:\n            del self.fields[\"oldpassword\"]\n            del self.fields[\"newpassword\"]\n            del self.fields[\"confirmation\"]\n\n    def clean_oldpassword(self):\n        if self.cleaned_data[\"oldpassword\"] == \"\":\n            return self.cleaned_data[\"oldpassword\"]\n\n        if parameters.get_admin(\"AUTHENTICATION_TYPE\") != \"local\":\n            return self.cleaned_data[\"oldpassword\"]\n\n        if not self.instance.check_password(self.cleaned_data[\"oldpassword\"]):\n            raise forms.ValidationError(_(\"Old password mismatchs\"))\n        return self.cleaned_data[\"oldpassword\"]\n\n    def clean_confirmation(self):\n        newpassword = self.cleaned_data[\"newpassword\"]\n        confirmation = self.cleaned_data[\"confirmation\"]\n        if newpassword != confirmation:\n            raise forms.ValidationError(_(\"Passwords mismatch\"))\n        return self.cleaned_data[\"confirmation\"]\n\n    def save(self, commit=True):\n        user = super(ProfileForm, self).save(commit=False)\n        if commit:\n            if self.cleaned_data.get(\"confirmation\", \"\") != \"\":\n                user.set_password(\n                    self.cleaned_data[\"confirmation\"],\n                    self.cleaned_data[\"oldpassword\"]\n                )\n            user.save()\n        return user\n", "path": "modoboa/core/forms.py"}, {"content": "# Development settings\nimport os\n\nBOWER_COMPONENTS_ROOT = os.path.join(\n    os.path.dirname(__file__), \"..\"\n)\n\nBOWER_INSTALLED_APPS = (\n    \"jquery#1.9\",\n    \"jquery-ui#1.11\",\n    \"bootstrap#3.3.1\",\n    \"bootstrap-select#1.6\",\n    \"d3#3.5.0\",\n    \"eonasdan-bootstrap-datetimepicker#3.1.3\",\n    \"font-awesome#4.2.0\",\n    \"c3#0.4.10\",\n)\n", "path": "modoboa/core/dev_settings.py"}], "after_files": [{"content": "# coding: utf-8\n\n\"\"\"Core forms.\"\"\"\n\nfrom django import forms\nfrom django.utils.translation import ugettext as _, ugettext_lazy\n\nfrom passwords.fields import PasswordField\n\nfrom modoboa.core.models import User\nfrom modoboa.lib import parameters\n\n\nclass LoginForm(forms.Form):\n    username = forms.CharField(\n        label=ugettext_lazy(\"Username\"),\n        widget=forms.TextInput(attrs={\"class\": \"form-control\"})\n    )\n    password = forms.CharField(\n        label=ugettext_lazy(\"Password\"),\n        widget=forms.PasswordInput(attrs={\"class\": \"form-control\"})\n    )\n    rememberme = forms.BooleanField(\n        initial=False,\n        required=False\n    )\n\n\nclass ProfileForm(forms.ModelForm):\n    oldpassword = forms.CharField(\n        label=ugettext_lazy(\"Old password\"), required=False,\n        widget=forms.PasswordInput(attrs={\"class\": \"form-control\"})\n    )\n    newpassword = PasswordField(\n        label=ugettext_lazy(\"New password\"), required=False,\n        widget=forms.PasswordInput(attrs={\"class\": \"form-control\"})\n    )\n    confirmation = PasswordField(\n        label=ugettext_lazy(\"Confirmation\"), required=False,\n        widget=forms.PasswordInput(attrs={\"class\": \"form-control\"})\n    )\n\n    class Meta:\n        model = User\n        fields = (\"first_name\", \"last_name\")\n        widgets = {\n            'first_name': forms.TextInput(attrs={'class': 'form-control'}),\n            'last_name': forms.TextInput(attrs={'class': 'form-control'})\n        }\n\n    def __init__(self, update_password, *args, **kwargs):\n        super(ProfileForm, self).__init__(*args, **kwargs)\n        if not update_password:\n            del self.fields[\"oldpassword\"]\n            del self.fields[\"newpassword\"]\n            del self.fields[\"confirmation\"]\n\n    def clean_oldpassword(self):\n        if self.cleaned_data[\"oldpassword\"] == \"\":\n            return self.cleaned_data[\"oldpassword\"]\n\n        if parameters.get_admin(\"AUTHENTICATION_TYPE\") != \"local\":\n            return self.cleaned_data[\"oldpassword\"]\n\n        if not self.instance.check_password(self.cleaned_data[\"oldpassword\"]):\n            raise forms.ValidationError(_(\"Old password mismatchs\"))\n        return self.cleaned_data[\"oldpassword\"]\n\n    def clean_confirmation(self):\n        newpassword = self.cleaned_data[\"newpassword\"]\n        confirmation = self.cleaned_data[\"confirmation\"]\n        if newpassword != confirmation:\n            raise forms.ValidationError(_(\"Passwords mismatch\"))\n        return self.cleaned_data[\"confirmation\"]\n\n    def save(self, commit=True):\n        user = super(ProfileForm, self).save(commit=False)\n        if commit:\n            if self.cleaned_data.get(\"confirmation\", \"\") != \"\":\n                user.set_password(\n                    self.cleaned_data[\"confirmation\"],\n                    self.cleaned_data[\"oldpassword\"]\n                )\n            user.save()\n        return user\n", "path": "modoboa/core/forms.py"}, {"content": "# Development settings\nimport os\n\nBOWER_COMPONENTS_ROOT = os.path.join(\n    os.path.dirname(__file__), \"..\"\n)\n\nBOWER_INSTALLED_APPS = (\n    \"jquery#1.9\",\n    \"jquery-ui#1.11\",\n    \"bootstrap#3.3.5\",\n    \"bootstrap-select#1.6\",\n    \"d3#3.5.0\",\n    \"eonasdan-bootstrap-datetimepicker#3.1.3\",\n    \"font-awesome#4.2.0\",\n    \"c3#0.4.10\",\n)\n", "path": "modoboa/core/dev_settings.py"}]}