From 3e7b817510d4c0068312c0348830e79bc3621ec3 Mon Sep 17 00:00:00 2001
From: Antoine Nguyen
Date: Wed, 21 Oct 2020 15:41:05 +0200
Subject: [PATCH 01/44] Bumped passlib to 1.7.3
fix #2036
---
requirements.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/requirements.txt b/requirements.txt
index baf72252c..784f34c99 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -11,7 +11,7 @@ dj-database-url
djangorestframework>=3.11,<3.12
uritemplate
-passlib==1.7.2
+passlib~=1.7.3
bcrypt # Requires libffi-dev and python-dev
dnspython==1.16.0
From 68dad785d6c3403e1f989e664d868b76ab7230d0 Mon Sep 17 00:00:00 2001
From: Michael Cramer
Date: Wed, 21 Oct 2020 15:44:08 +0200
Subject: [PATCH 02/44] Polish and Fixing issues when using "docker-compose up"
(#2039)
* add missing dependencies to be able to use docker
without these dependencies, the `docker-compose up` command is failing
- `rrdtool-dev` and `librrd` when building `rrdtool-0.1.15.tar.gz`
- `make` and `file` when building `gevent-1.5.0.tar.gz`
* disable secure cookies for being able to login when docker is used with runserver (there is no ssl)
* run develop command to avoid a hard failure after login when using the docker image (version check is performed but pkg_resources is not able to find modoboa distribution)
* polish multi stage docker build (adding missing dependencies for pip install and when running the application); use a virtual environment which is shared between the stages by using a base image and others will extend this
---
Dockerfile.dev | 20 +++++++++++---------
docker-compose.yml | 2 +-
test_project/test_project/settings.py | 4 ++--
3 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/Dockerfile.dev b/Dockerfile.dev
index 8ecde4047..52eca494f 100644
--- a/Dockerfile.dev
+++ b/Dockerfile.dev
@@ -1,21 +1,23 @@
FROM python:3.6-alpine as base
MAINTAINER Antoine Nguyen
+ENV VIRTUAL_ENV=/opt/venv
+ENV PATH="$VIRTUAL_ENV/bin:$PATH"
-RUN apk add --update openssl python3-dev libffi-dev gcc musl-dev libxml2-dev libxslt-dev \
- libressl-dev jpeg-dev \
+FROM base as build
+
+RUN apk add --update openssl librrd python3-dev libffi-dev gcc musl-dev libxml2-dev libxslt-dev \
+ libressl-dev jpeg-dev rrdtool-dev file make \
&& rm -rf /var/cache/apk/*
-
+RUN python3 -m venv $VIRTUAL_ENV
WORKDIR /tmp
COPY requirements.txt /tmp
COPY test-requirements.txt /tmp
-RUN pip install --user -r requirements.txt --user -r test-requirements.txt
+RUN pip install -r requirements.txt -r test-requirements.txt
-FROM python:3.6-alpine
-COPY --from=base /root/.local /root/.local
-ENV PATH=/root/.local/bin:$PATH
-RUN apk add --no-cache --update libxml2-dev libxslt-dev\
+FROM base as run
+COPY --from=build $VIRTUAL_ENV $VIRTUAL_ENV
+RUN apk add --no-cache --update librrd libxslt libjpeg libressl git rrdtool \
&& rm -rf /var/cache/apk/*
-
RUN mkdir /code
WORKDIR /code
diff --git a/docker-compose.yml b/docker-compose.yml
index 5630bfb11..e7009ea76 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -13,6 +13,6 @@ services:
PYTHONPATH: ".."
DB: "SQLITE"
DEBUG: "True"
- command: sh -c "cd test_project && python3 manage.py migrate && python3 manage.py load_initial_data && python3 manage.py runserver 0:8000"
+ command: sh -c "python3 setup.py develop && cd test_project && python3 manage.py migrate && python3 manage.py load_initial_data && python3 manage.py runserver 0:8000"
volumes:
- .:/code
diff --git a/test_project/test_project/settings.py b/test_project/test_project/settings.py
index 65b9bda87..c626b04de 100644
--- a/test_project/test_project/settings.py
+++ b/test_project/test_project/settings.py
@@ -46,8 +46,8 @@ SITE_ID = 1
# Security settings
X_FRAME_OPTIONS = "SAMEORIGIN"
-CSRF_COOKIE_SECURE = True
-SESSION_COOKIE_SECURE = True
+CSRF_COOKIE_SECURE = False
+SESSION_COOKIE_SECURE = False
# Application definition
From 01891b85fdb5cf72a1e9c5d304ec2c61b90a7506 Mon Sep 17 00:00:00 2001
From: Antoine Nguyen
Date: Wed, 21 Oct 2020 19:22:35 +0200
Subject: [PATCH 03/44] policyd: Replaced 127.0.0.1 by localhost.
see #2028
---
doc/manual_installation/postfix.rst | 2 +-
modoboa/policyd/management/commands/policy_daemon.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/doc/manual_installation/postfix.rst b/doc/manual_installation/postfix.rst
index 6d331addb..4d9d7e9ea 100644
--- a/doc/manual_installation/postfix.rst
+++ b/doc/manual_installation/postfix.rst
@@ -76,7 +76,7 @@ content to the :file:`/etc/postfix/main.cf` file::
smtpd_recipient_restrictions =
# ...
- check_policy_service inet:127.0.0.1:9999
+ check_policy_service inet:localhost:9999
# ...
And reload postfix.
diff --git a/modoboa/policyd/management/commands/policy_daemon.py b/modoboa/policyd/management/commands/policy_daemon.py
index a454e032d..e0b135853 100644
--- a/modoboa/policyd/management/commands/policy_daemon.py
+++ b/modoboa/policyd/management/commands/policy_daemon.py
@@ -25,7 +25,7 @@ class Command(BaseCommand):
def add_arguments(self, parser):
"""Add command line arguments."""
- parser.add_argument("--host", type=str, default="127.0.0.1")
+ parser.add_argument("--host", type=str, default="localhost")
parser.add_argument("--port", type=int, default=9999)
parser.add_argument("--debug", action="store_true",
help="Enable debug mode")
From 6df0a93e30fccf0a15cfda11ac64ba1a6e3df98f Mon Sep 17 00:00:00 2001
From: Antoine Nguyen
Date: Thu, 22 Oct 2020 17:46:40 +0200
Subject: [PATCH 04/44] Make sure to disable/enable self alias according to
forward settings.
see #1356
---
modoboa/admin/tests/test_user.py | 13 ++++++++++++
modoboa/admin/views/user.py | 36 +++++++++++++++++++++++---------
2 files changed, 39 insertions(+), 10 deletions(-)
diff --git a/modoboa/admin/tests/test_user.py b/modoboa/admin/tests/test_user.py
index 312a6c804..346300cce 100644
--- a/modoboa/admin/tests/test_user.py
+++ b/modoboa/admin/tests/test_user.py
@@ -34,9 +34,22 @@ class ForwardTestCase(ModoTestCase):
domadmin = User.objects.get(username="admin@test.com")
self.assertTrue(domadmin.can_access(forward))
+ selfalias = Alias.objects.get(address="user@test.com", internal=True)
+ self.assertTrue(selfalias.enabled)
+
+ # Deactivate local copies
+ self.ajax_post(
+ url,
+ {"dest": "user@extdomain.com", "keepcopies": False}
+ )
+ selfalias.refresh_from_db()
+ self.assertFalse(selfalias.enabled)
+
# Now, empty forward
self.ajax_post(url, {"dest": "", "keepcopies": False})
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
content = response.json()
self.assertNotIn("user@extdomain.com", content["content"])
+ selfalias.refresh_from_db()
+ self.assertTrue(selfalias.enabled)
diff --git a/modoboa/admin/views/user.py b/modoboa/admin/views/user.py
index 308cdf268..8edc6fa09 100644
--- a/modoboa/admin/views/user.py
+++ b/modoboa/admin/views/user.py
@@ -21,18 +21,34 @@ def forward(request, tplname="admin/forward.html"):
if request.method == "POST":
form = ForwardForm(request.POST)
if form.is_valid():
- if al is None:
- al = Alias.objects.create(
- address=mb.full_address, domain=mb.domain,
- enabled=mb.user.is_active)
recipients = form.cleaned_data["dest"]
- if form.cleaned_data["keepcopies"]:
- recipients.append(mb.full_address)
- al.set_recipients(recipients)
- if len(recipients) == 0:
- al.delete()
+ if not recipients:
+ Alias.objects.filter(
+ address=mb.full_address, internal=False).delete()
+ # Make sure internal self-alias is enabled
+ Alias.objects.filter(
+ address=mb.full_address, internal=True
+ ).update(enabled=True)
else:
- al.post_create(request.user)
+ if al is None:
+ al = Alias.objects.create(
+ address=mb.full_address,
+ domain=mb.domain,
+ enabled=mb.user.is_active
+ )
+ al.post_create(request.user)
+ if form.cleaned_data["keepcopies"]:
+ # Make sure internal self-alias is enabled
+ Alias.objects.filter(
+ address=mb.full_address, internal=True
+ ).update(enabled=True)
+ else:
+ # Deactivate internal self-alias to avoid storing
+ # local copies...
+ Alias.objects.filter(
+ address=mb.full_address, internal=True
+ ).update(enabled=False)
+ al.set_recipients(recipients)
return render_to_json_response(_("Forward updated"))
return render_to_json_response(
From c891724b5d6a08933a911d5416892bffc1642365 Mon Sep 17 00:00:00 2001
From: "transifex-integration[bot]"
<43880903+transifex-integration[bot]@users.noreply.github.com>
Date: Fri, 23 Oct 2020 14:15:00 +0200
Subject: [PATCH 05/44] Apply translations in nl_NL (#2025)
translation completed for the source file '/modoboa/ldapsync/locale/en/LC_MESSAGES/django.po'
on the 'nl_NL' language.
Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
---
.../locale/nl_NL/LC_MESSAGES/django.po | 22 +++++++++++--------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/modoboa/ldapsync/locale/nl_NL/LC_MESSAGES/django.po b/modoboa/ldapsync/locale/nl_NL/LC_MESSAGES/django.po
index 2fe38569f..0b7d94546 100644
--- a/modoboa/ldapsync/locale/nl_NL/LC_MESSAGES/django.po
+++ b/modoboa/ldapsync/locale/nl_NL/LC_MESSAGES/django.po
@@ -2,33 +2,37 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR , YEAR.
-#
+#
+# Translators:
+# J Rosier , 2020
+#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-06 13:15+0200\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME \n"
-"Language-Team: LANGUAGE \n"
-"Language: \n"
+"PO-Revision-Date: 2020-05-11 18:45+0000\n"
+"Last-Translator: J Rosier , 2020\n"
+"Language-Team: Dutch (Netherlands) (https://www.transifex.com/tonio/teams/13749/nl_NL/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Language: nl_NL\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: ldapsync/lib.py:84
msgid "Failed to create LDAP account: {}"
-msgstr ""
+msgstr "Aanmaken LDAP account mislukt: {}"
#: ldapsync/lib.py:124
msgid "Failed to update LDAP account: {}"
-msgstr ""
+msgstr "Wijzigen LDAP account mislukt: {}"
#: ldapsync/lib.py:138
msgid "Failed to delete LDAP account: {}"
-msgstr ""
+msgstr "Verwijderen LDAP account mislukt: {}"
#: ldapsync/lib.py:149
msgid "Failed to disable LDAP account: {}"
-msgstr ""
+msgstr "Uitschakelen LDAP account mislukt: {}"
From aa1a353e77a8667c7cc8aed8786c19dbacdcd777 Mon Sep 17 00:00:00 2001
From: "transifex-integration[bot]"
<43880903+transifex-integration[bot]@users.noreply.github.com>
Date: Fri, 23 Oct 2020 14:15:39 +0200
Subject: [PATCH 06/44] Apply translations in nl_NL (#2026)
translation completed for the source file '/modoboa/locale/en/LC_MESSAGES/djangojs.po'
on the 'nl_NL' language.
Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
---
modoboa/locale/nl_NL/LC_MESSAGES/djangojs.po | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/modoboa/locale/nl_NL/LC_MESSAGES/djangojs.po b/modoboa/locale/nl_NL/LC_MESSAGES/djangojs.po
index ec3742949..929bffdf3 100644
--- a/modoboa/locale/nl_NL/LC_MESSAGES/djangojs.po
+++ b/modoboa/locale/nl_NL/LC_MESSAGES/djangojs.po
@@ -1,19 +1,21 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR , YEAR.
#
# Translators:
-# R Kloosterman , 2016
-# TuxBrother , 2014
-# TuxBrother , 2014
+# Antoine Nguyen , 2020
+# J Rosier , 2020
+#
+#, fuzzy
msgid ""
msgstr ""
-"Project-Id-Version: Modoboa\n"
+"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-03-09 16:48+0100\n"
-"PO-Revision-Date: 2020-03-09 15:49+0000\n"
-"Last-Translator: Antoine Nguyen \n"
-"Language-Team: Dutch (Netherlands) (http://www.transifex.com/tonio/modoboa/language/nl_NL/)\n"
+"PO-Revision-Date: 2020-05-11 18:45+0000\n"
+"Last-Translator: J Rosier , 2020\n"
+"Language-Team: Dutch (Netherlands) (https://www.transifex.com/tonio/teams/13749/nl_NL/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -26,7 +28,7 @@ msgstr "'"
#: bower_components/swagger-ui/dist/swagger-ui-bundle.js:133
msgid "operation"
-msgstr ""
+msgstr "bewerking"
#: core/static/core/js/settings.js:16
msgid "No more log entry to show"
From c7b8eb09d2abfbacab688d06417c7e7246bc9565 Mon Sep 17 00:00:00 2001
From: "transifex-integration[bot]"
<43880903+transifex-integration[bot]@users.noreply.github.com>
Date: Fri, 23 Oct 2020 14:16:18 +0200
Subject: [PATCH 07/44] Apply translations in nl_NL (#2021)
translation completed for the source file '/modoboa/locale/en/LC_MESSAGES/django.po'
on the 'nl_NL' language.
Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
---
modoboa/locale/nl_NL/LC_MESSAGES/django.po | 129 +++++++++++----------
1 file changed, 65 insertions(+), 64 deletions(-)
diff --git a/modoboa/locale/nl_NL/LC_MESSAGES/django.po b/modoboa/locale/nl_NL/LC_MESSAGES/django.po
index 6cf8fe3f6..251b31fcf 100644
--- a/modoboa/locale/nl_NL/LC_MESSAGES/django.po
+++ b/modoboa/locale/nl_NL/LC_MESSAGES/django.po
@@ -4,9 +4,10 @@
#
# Translators:
# Andrew , 2014
-# Chris de Gelder , 2017
+# ABC, 2017
# Fred Durst , 2019
# Harrie v.d. Vegt , 2016
+# J Rosier , 2020
# Peter van den Heuvel , 2017
# Remco de Hiep , 2017
# R Kloosterman , 2016
@@ -19,8 +20,8 @@ msgstr ""
"Project-Id-Version: Modoboa\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-06 13:15+0200\n"
-"PO-Revision-Date: 2020-05-06 11:16+0000\n"
-"Last-Translator: Antoine Nguyen \n"
+"PO-Revision-Date: 2020-10-03 09:44+0000\n"
+"Last-Translator: J Rosier \n"
"Language-Team: Dutch (Netherlands) (http://www.transifex.com/tonio/modoboa/language/nl_NL/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -68,7 +69,7 @@ msgstr "Nummer van te gebruiken randomizeringsrondes (alleen bij sha256crypt en
#: core/app_settings.py:69
msgid "Update password scheme at login"
-msgstr ""
+msgstr "Update wachtwoordschema bij inloggen"
#: core/app_settings.py:72
msgid "Update user password at login to use the default password scheme"
@@ -84,7 +85,7 @@ msgstr "Standaard wachtwoord voor automatisch gecreëerde accounts."
#: core/app_settings.py:84
msgid "Random password length"
-msgstr "Lengte willekeurig wachtwoord"
+msgstr "Lengte van willekeurig wachtwoord"
#: core/app_settings.py:88
msgid "Length of randomly generated passwords."
@@ -92,38 +93,38 @@ msgstr "Lengte van willekeurig gegenereerde wachtwoorden"
#: core/app_settings.py:92
msgid "Update password service URL"
-msgstr ""
+msgstr "Service-url voor wachtwoorden updaten"
#: core/app_settings.py:96
msgid ""
"The URL of an external page where users will be able to update their "
"password. It applies only to non local users, ie. those automatically "
"created after a successful external authentication (LDAP, SMTP)."
-msgstr ""
+msgstr "De URL van een externe pagina waar gebruikers hun wachtwoord kunnen bijwerken. Alleen van toepassing op niet-lokale gebruikers die automatisch worden aangemaakt na een succesvolle externe authenticatie (LDAP, SMTP)."
#: core/app_settings.py:104
msgid "Password recovery announcement"
-msgstr ""
+msgstr "Melding wachtwoordherstel"
#: core/app_settings.py:109
msgid "A temporary message that will be displayed on the reset password page."
-msgstr ""
+msgstr "Een tijdelijke melding die wordt getoond op de wachtwoordresetpagina."
#: core/app_settings.py:115
msgid "Enable password recovery by SMS"
-msgstr ""
+msgstr "Wachtwoordherstel via SMS activeren"
#: core/app_settings.py:118
msgid "Enable password recovery by SMS for users who filled a phone number."
-msgstr ""
+msgstr "Wachtwoordherstel via SMS activeren voor gebruikers die een telefoonnummer hebben ingevuld."
#: core/app_settings.py:124
msgid "SMS provider"
-msgstr ""
+msgstr "SMS provider"
#: core/app_settings.py:127
msgid "Choose a provider to send password recovery SMS"
-msgstr ""
+msgstr "Kies een provider voor het sturen van een SMS voor wachtwoordherstel."
#: core/app_settings.py:133
msgid "LDAP settings"
@@ -147,28 +148,28 @@ msgstr "Het TCP poortnummer van de LDAP-server"
#: core/app_settings.py:149
msgid "Enable secondary server (fallback)"
-msgstr ""
+msgstr "Secundaire server activeren (fallback)"
#: core/app_settings.py:152
msgid ""
"Enable a secondary LDAP server which will be used if the primary one fails"
-msgstr ""
+msgstr "Activeer secundaire LDAP server, te gebruiken als de primaire server wegvalt"
#: core/app_settings.py:158
msgid "Secondary server address"
-msgstr ""
+msgstr "Adres van secundaire server"
#: core/app_settings.py:161
msgid "The IP address or the DNS name of the seondary LDAP server"
-msgstr ""
+msgstr "Het IP adres of DNS naam van de secundaire LDAP server"
#: core/app_settings.py:165
msgid "Secondary server port"
-msgstr ""
+msgstr "secundaire-serverpoort"
#: core/app_settings.py:168
msgid "The TCP port number used by the LDAP secondary server"
-msgstr ""
+msgstr "TCP poortnummer van de secundaire LDAP server"
#: core/app_settings.py:172
msgid "Use a secured connection"
@@ -222,7 +223,7 @@ msgstr "Het attribuut dat gebruikt wordt om wachtwoorden op te slaan"
#: core/app_settings.py:222
msgid "LDAP authentication settings"
-msgstr ""
+msgstr "LDAP authenticatie-instellingen"
#: core/app_settings.py:225
msgid "Authentication method"
@@ -289,70 +290,70 @@ msgstr "Het template dat gebruikt wordt om een gebruiker zijn/haar DN op te bouw
#: core/app_settings.py:284
msgid "LDAP synchronization settings"
-msgstr ""
+msgstr "LDAP synchronisatie-instellingen"
#: core/app_settings.py:308
msgid "Enable export to LDAP"
-msgstr ""
+msgstr "Activeer export naar LDAP"
#: core/app_settings.py:311
msgid ""
"Enable automatic synchronization between local database and LDAP directory"
-msgstr ""
+msgstr "Activeer automatische synchronisatie tussen lokale database en LDAP directory"
#: core/app_settings.py:317
msgid "Delete remote LDAP account when local account is deleted"
-msgstr ""
+msgstr "Verwijder extern LDAP account als het lokale account wordt verwijderd"
#: core/app_settings.py:321
msgid ""
"Delete remote LDAP account when local account is deleted, otherwise it will "
"be disabled."
-msgstr ""
+msgstr "Verwijder extern LDAP account als het lokale account wordt verwijderd. Zo niet, dan wordt het gedeactiveerd."
#: core/app_settings.py:327
msgid "Account DN template"
-msgstr ""
+msgstr "Account DN sjabloon"
#: core/app_settings.py:330
#, python-format
msgid ""
"The template used to construct an account's DN. It should contain one "
"placeholder (ie. %(user)s)"
-msgstr ""
+msgstr "Het sjabloon voor het opbouwen van het DN (distinguishedname). Het moet een tijdelijke aanduiding (placeholder) bevatten (bijvoorbeeld %(user)s)"
#: core/app_settings.py:337
msgid "Enable import from LDAP"
-msgstr ""
+msgstr "Activeer import van LDAP"
#: core/app_settings.py:340
msgid "Enable account synchronization from LDAP directory to local database"
-msgstr ""
+msgstr "Activeer accountsynchronisatie van LDAP directory naar lokale database"
#: core/app_settings.py:365
msgid "Username attribute"
-msgstr ""
+msgstr "Gebruikersnaamattribuut"
#: core/app_settings.py:368
msgid "The name of the LDAP attribute where the username can be found."
-msgstr ""
+msgstr "De naam van het LDAP-attribuut waar de gebruikersnaam staat."
#: core/app_settings.py:373
msgid "Enable Dovecot LDAP sync"
-msgstr ""
+msgstr "Activeer Dovecot LDAP synchronisatie"
#: core/app_settings.py:376
msgid "LDAP authentication settings will be applied to Dovecot configuration."
-msgstr ""
+msgstr "LDAP authenticatie-instellingen worden toegepast op Dovecot-configuratie."
#: core/app_settings.py:382
msgid "Dovecot LDAP config file"
-msgstr ""
+msgstr "Dovecot LDAP configuratiebestand"
#: core/app_settings.py:386
msgid ""
"Location of the configuration file which contains Dovecot LDAP settings."
-msgstr ""
+msgstr "Locatie van het configuratiebestand met Dovecot LDAP-instellingen."
#: core/app_settings.py:391 core/templates/core/dashboard.html:5
msgid "Dashboard"
@@ -408,19 +409,19 @@ msgstr "Controleert automatisch of een nieuwere versie beschikbaar is"
#: core/app_settings.py:436
msgid "Send an email when new versions are found"
-msgstr ""
+msgstr "Stuur een e-mail als er nieuwe versies worden gevonden"
#: core/app_settings.py:439
msgid "Send an email to notify admins about new versions"
-msgstr ""
+msgstr "Stuur een e-mail naar administrators over nieuwe versies"
#: core/app_settings.py:443
msgid "Recipient"
-msgstr ""
+msgstr "Ontvanger"
#: core/app_settings.py:446
msgid "Recipient of new versions notification emails."
-msgstr ""
+msgstr "Ontvanger van notificatiemails over nieuwe versies"
#: core/app_settings.py:451
msgid "Send statistics"
@@ -525,11 +526,11 @@ msgstr "Nee"
#: core/constants.py:102
msgid "Choose a provider"
-msgstr ""
+msgstr "Kies een provider"
#: core/constants.py:107
msgid "Dummy"
-msgstr ""
+msgstr "Dummy"
#: core/forms.py:21
msgid "Username"
@@ -565,11 +566,11 @@ msgstr "Activeer API-toegang"
#: core/forms.py:137
msgid "Verification code"
-msgstr ""
+msgstr "Verificatiecode"
#: core/forms.py:148
msgid "Invalid code"
-msgstr ""
+msgstr "Ongeldige code"
#: core/handlers.py:36
msgid "added"
@@ -595,7 +596,7 @@ msgstr "verwijderd"
#: core/handlers.py:69
msgid "user {}"
-msgstr "gebruiker{}"
+msgstr "gebruiker {}"
#: core/handlers.py:71
msgid "management command"
@@ -611,7 +612,7 @@ msgstr "Er zijn een of meer updates beschikbaar"
#: core/management/commands/communicate_with_public_api.py:44
msgid "[modoboa] Update(s) available"
-msgstr ""
+msgstr "[modoboa] update(s) beschikbaar"
#: core/models.py:55
msgid "Allow mailboxes access"
@@ -705,47 +706,47 @@ msgstr "Uw wachtwoord moet verschillende tekens bevatten."
#: core/sms_backends/ovh.py:19
msgid "API endpoint"
-msgstr ""
+msgstr "API eindpunt"
#: core/sms_backends/ovh.py:22
msgid "OVH Europe"
-msgstr ""
+msgstr "OVH Europa"
#: core/sms_backends/ovh.py:23
msgid "OVH US"
-msgstr ""
+msgstr "OVH Verenigde Staten"
#: core/sms_backends/ovh.py:24
msgid "OVH North-America"
-msgstr ""
+msgstr "OVH Noord-Amerika"
#: core/sms_backends/ovh.py:25
msgid "So you Start Europe"
-msgstr ""
+msgstr "So you Start Europa"
#: core/sms_backends/ovh.py:26
msgid "So you Start North America"
-msgstr ""
+msgstr "So you Start Noord-Amerika"
#: core/sms_backends/ovh.py:27
msgid "Kimsufi Europe"
-msgstr ""
+msgstr "Kimsufi Europa"
#: core/sms_backends/ovh.py:28
msgid "Kimsufi North America"
-msgstr ""
+msgstr "Kimsufi Noord-Amerika"
#: core/sms_backends/ovh.py:35
msgid "Application key"
-msgstr ""
+msgstr "Applicatiesleutel"
#: core/sms_backends/ovh.py:42
msgid "Application secret"
-msgstr ""
+msgstr "Applicatiegeheim"
#: core/sms_backends/ovh.py:50
msgid "Consumer key"
-msgstr ""
+msgstr "Consumentensleutel"
#: core/templates/core/_current_features.html:6
msgid "Features looking for sponsoring"
@@ -882,8 +883,8 @@ msgid ""
msgid_plural ""
"\n"
" The following updates are available:\n"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "\n De volgende update is beschikbaar:\n"
+msgstr[1] "\nDe volgende updates zijn beschikbaar:\n"
#: core/templates/core/parameters.html:2 core/templatetags/core_tags.py:71
msgid "Parameters"
@@ -929,7 +930,7 @@ msgstr "Persoonlijke informatie aanpassen"
#: core/templates/core/user_profile.html:13
msgid "Click here to update your password"
-msgstr ""
+msgstr "Klik hier om je wachtwoord te wijzigen"
#: core/templatetags/core_tags.py:34
msgid "Modoboa"
@@ -959,7 +960,7 @@ msgstr "Wachtwoord schema matcht niet. Updating %s wachtwoord"
#: core/views/auth.py:66
#, python-format
msgid "Password hash parameter missmatch. Updating %s password"
-msgstr ""
+msgstr "Hashparameter van het wachtwoord klopt niet. Wachtwoord %s wijzigen"
#: core/views/auth.py:82
#, python-format
@@ -976,7 +977,7 @@ msgstr "Gebruiker '{}' is uitgelogd."
#: core/views/auth.py:170 core/views/auth.py:225
msgid "Please use the following code to recover your Modoboa password: {}"
-msgstr ""
+msgstr "Gebruik de volgende code om het Modoboa wachtwoord te herstellen: {}"
#: core/views/user.py:53
msgid "Profile updated"
@@ -1129,11 +1130,11 @@ msgstr "Deze wachtwoord herstel link is ongeldig, misschien is hij al gebruikt.
#: templates/registration/password_reset_confirm_code.html:20
msgid "Enter the code you've just received by SMS"
-msgstr ""
+msgstr "Voer SMS code in"
#: templates/registration/password_reset_confirm_code.html:27
msgid "Resend code"
-msgstr ""
+msgstr "Stuur de code opnieuw"
#: templates/registration/password_reset_done.html:7
msgid ""
@@ -1162,7 +1163,7 @@ msgstr "Met vriendelijke groet, Het Modoboa Team,"
#: templates/registration/password_reset_form.html:24
msgid "Please fill-in your primary email address"
-msgstr ""
+msgstr "Vul uw primaire e-mailadres in"
#: templates/registration/password_reset_subject.txt:3
msgid "Modoboa password reset"
From 00f71de8830d0b56955c07e0c340f73ad90e4eac Mon Sep 17 00:00:00 2001
From: "transifex-integration[bot]"
<43880903+transifex-integration[bot]@users.noreply.github.com>
Date: Fri, 23 Oct 2020 14:16:49 +0200
Subject: [PATCH 08/44] Apply translations in pl_PL (#2016)
translation completed for the source file '/modoboa/locale/en/LC_MESSAGES/djangojs.po'
on the 'pl_PL' language.
Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
---
modoboa/locale/pl_PL/LC_MESSAGES/djangojs.po | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/modoboa/locale/pl_PL/LC_MESSAGES/djangojs.po b/modoboa/locale/pl_PL/LC_MESSAGES/djangojs.po
index 1dbda6226..c304efd6d 100644
--- a/modoboa/locale/pl_PL/LC_MESSAGES/djangojs.po
+++ b/modoboa/locale/pl_PL/LC_MESSAGES/djangojs.po
@@ -1,19 +1,21 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR , YEAR.
#
# Translators:
-# sin88 , 2016
-# sin88 , 2016
-# Wojtek Gajda , 2018
+# Antoine Nguyen , 2020
+# Pedro M , 2020
+#
+#, fuzzy
msgid ""
msgstr ""
-"Project-Id-Version: Modoboa\n"
+"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-03-09 16:48+0100\n"
-"PO-Revision-Date: 2020-03-09 15:49+0000\n"
-"Last-Translator: Antoine Nguyen \n"
-"Language-Team: Polish (Poland) (http://www.transifex.com/tonio/modoboa/language/pl_PL/)\n"
+"PO-Revision-Date: 2020-05-11 18:45+0000\n"
+"Last-Translator: Pedro M , 2020\n"
+"Language-Team: Polish (Poland) (https://www.transifex.com/tonio/teams/13749/pl_PL/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -26,7 +28,7 @@ msgstr "'"
#: bower_components/swagger-ui/dist/swagger-ui-bundle.js:133
msgid "operation"
-msgstr ""
+msgstr "działanie"
#: core/static/core/js/settings.js:16
msgid "No more log entry to show"
From 97df1b6b5d22d607a4b2fb27efa49c5081fc84c7 Mon Sep 17 00:00:00 2001
From: "transifex-integration[bot]"
<43880903+transifex-integration[bot]@users.noreply.github.com>
Date: Fri, 23 Oct 2020 14:17:21 +0200
Subject: [PATCH 09/44] Apply translations in pl_PL (#2017)
translation completed for the source file '/modoboa/ldapsync/locale/en/LC_MESSAGES/django.po'
on the 'pl_PL' language.
Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
---
.../locale/pl_PL/LC_MESSAGES/django.po | 22 +++++++++++--------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/modoboa/ldapsync/locale/pl_PL/LC_MESSAGES/django.po b/modoboa/ldapsync/locale/pl_PL/LC_MESSAGES/django.po
index 2fe38569f..293d4df2c 100644
--- a/modoboa/ldapsync/locale/pl_PL/LC_MESSAGES/django.po
+++ b/modoboa/ldapsync/locale/pl_PL/LC_MESSAGES/django.po
@@ -2,33 +2,37 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR , YEAR.
-#
+#
+# Translators:
+# Pedro M , 2020
+#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-06 13:15+0200\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME \n"
-"Language-Team: LANGUAGE \n"
-"Language: \n"
+"PO-Revision-Date: 2020-05-11 18:45+0000\n"
+"Last-Translator: Pedro M , 2020\n"
+"Language-Team: Polish (Poland) (https://www.transifex.com/tonio/teams/13749/pl_PL/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Language: pl_PL\n"
+"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
#: ldapsync/lib.py:84
msgid "Failed to create LDAP account: {}"
-msgstr ""
+msgstr "Niepowodzenie w trakcie dodawania konta LDAP"
#: ldapsync/lib.py:124
msgid "Failed to update LDAP account: {}"
-msgstr ""
+msgstr "Niepowodzenie w trakcie aktualizacji konta LDAP"
#: ldapsync/lib.py:138
msgid "Failed to delete LDAP account: {}"
-msgstr ""
+msgstr "Niepowodzenie w trakcie usuwania konta LDAP"
#: ldapsync/lib.py:149
msgid "Failed to disable LDAP account: {}"
-msgstr ""
+msgstr "Niepowodzenie w trakcie wyłaczania konta LDAP"
From baa19be556a987a58438055d147f0f9799b86e6b Mon Sep 17 00:00:00 2001
From: "transifex-integration[bot]"
<43880903+transifex-integration[bot]@users.noreply.github.com>
Date: Fri, 23 Oct 2020 14:17:58 +0200
Subject: [PATCH 10/44] Apply translations in sv (#2018)
translation completed for the source file '/modoboa/ldapsync/locale/en/LC_MESSAGES/django.po'
on the 'sv' language.
Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
---
.../ldapsync/locale/sv/LC_MESSAGES/django.po | 21 +++++++++++--------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/modoboa/ldapsync/locale/sv/LC_MESSAGES/django.po b/modoboa/ldapsync/locale/sv/LC_MESSAGES/django.po
index c26d6d26b..52fd6442b 100644
--- a/modoboa/ldapsync/locale/sv/LC_MESSAGES/django.po
+++ b/modoboa/ldapsync/locale/sv/LC_MESSAGES/django.po
@@ -2,34 +2,37 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR , YEAR.
-#
+#
+# Translators:
+# Olle Gustafsson , 2020
+#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-06 13:15+0200\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME \n"
-"Language-Team: LANGUAGE \n"
-"Language: \n"
+"PO-Revision-Date: 2020-05-11 18:45+0000\n"
+"Last-Translator: Olle Gustafsson , 2020\n"
+"Language-Team: Swedish (https://www.transifex.com/tonio/teams/13749/sv/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Language: sv\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: ldapsync/lib.py:84
msgid "Failed to create LDAP account: {}"
-msgstr ""
+msgstr "Misslyckades med att skapa LDAP konto: {}"
#: ldapsync/lib.py:124
msgid "Failed to update LDAP account: {}"
-msgstr ""
+msgstr "Misslyckades med att uppdatera LDAP konto: {}"
#: ldapsync/lib.py:138
msgid "Failed to delete LDAP account: {}"
-msgstr ""
+msgstr "Misslyckades med att radera LDAP konto: {}"
#: ldapsync/lib.py:149
msgid "Failed to disable LDAP account: {}"
-msgstr ""
+msgstr "Misslyckades med att inaktivera LDAP konto: {}"
From 6ea6d0017ccac625d33bbf73c8f4cd97ea580d1e Mon Sep 17 00:00:00 2001
From: "transifex-integration[bot]"
<43880903+transifex-integration[bot]@users.noreply.github.com>
Date: Fri, 23 Oct 2020 14:18:28 +0200
Subject: [PATCH 11/44] Apply translations in sv (#2019)
translation completed for the source file '/modoboa/locale/en/LC_MESSAGES/djangojs.po'
on the 'sv' language.
Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
---
modoboa/locale/sv/LC_MESSAGES/djangojs.po | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/modoboa/locale/sv/LC_MESSAGES/djangojs.po b/modoboa/locale/sv/LC_MESSAGES/djangojs.po
index 034817530..ae62e87d8 100644
--- a/modoboa/locale/sv/LC_MESSAGES/djangojs.po
+++ b/modoboa/locale/sv/LC_MESSAGES/djangojs.po
@@ -1,18 +1,21 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR , YEAR.
#
# Translators:
-# Olle Gustafsson , 2013
-# Olle Gustafsson , 2013,2015-2016
+# Antoine Nguyen , 2020
+# Olle Gustafsson , 2020
+#
+#, fuzzy
msgid ""
msgstr ""
-"Project-Id-Version: Modoboa\n"
+"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-03-09 16:48+0100\n"
-"PO-Revision-Date: 2020-03-09 15:49+0000\n"
-"Last-Translator: Antoine Nguyen \n"
-"Language-Team: Swedish (http://www.transifex.com/tonio/modoboa/language/sv/)\n"
+"PO-Revision-Date: 2020-05-11 18:45+0000\n"
+"Last-Translator: Olle Gustafsson , 2020\n"
+"Language-Team: Swedish (https://www.transifex.com/tonio/teams/13749/sv/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -25,7 +28,7 @@ msgstr "'"
#: bower_components/swagger-ui/dist/swagger-ui-bundle.js:133
msgid "operation"
-msgstr ""
+msgstr "operation"
#: core/static/core/js/settings.js:16
msgid "No more log entry to show"
From 62db847bd4c5432928e5ed6d38114511c5736b39 Mon Sep 17 00:00:00 2001
From: "transifex-integration[bot]"
<43880903+transifex-integration[bot]@users.noreply.github.com>
Date: Fri, 23 Oct 2020 14:18:58 +0200
Subject: [PATCH 12/44] Apply translations in sv (#2020)
translation completed for the source file '/modoboa/locale/en/LC_MESSAGES/django.po'
on the 'sv' language.
Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
---
modoboa/locale/sv/LC_MESSAGES/django.po | 312 ++++++++----------------
1 file changed, 106 insertions(+), 206 deletions(-)
diff --git a/modoboa/locale/sv/LC_MESSAGES/django.po b/modoboa/locale/sv/LC_MESSAGES/django.po
index c78f2b9a1..83afea1e0 100644
--- a/modoboa/locale/sv/LC_MESSAGES/django.po
+++ b/modoboa/locale/sv/LC_MESSAGES/django.po
@@ -1,24 +1,23 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
-#
+#
# Translators:
-# Martin Persson , 2014
+# Martin Persson , 2014,2017
# Olle Gustafsson , 2013
-# Olle Gustafsson , 2013,2015-2017
+# Olle Gustafsson , 2013,2015-2018,2020
msgid ""
msgstr ""
"Project-Id-Version: Modoboa\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-06 13:15+0200\n"
-"PO-Revision-Date: 2017-07-07 09:30+0000\n"
-"Last-Translator: Antoine Nguyen \n"
-"Language-Team: Swedish (http://www.transifex.com/tonio/modoboa/language/"
-"sv/)\n"
-"Language: sv\n"
+"PO-Revision-Date: 2020-10-02 18:56+0000\n"
+"Last-Translator: Olle Gustafsson \n"
+"Language-Team: Swedish (http://www.transifex.com/tonio/modoboa/language/sv/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Language: sv\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: core/app_settings.py:26
@@ -57,19 +56,15 @@ msgstr "Antal omgångar"
msgid ""
"Number of rounds to use (only used by sha256crypt and sha512crypt). Must be "
"between 1000 and 999999999, inclusive."
-msgstr ""
-"Antal omgångar att använda (används endast av sha256crypt och sha512crypt). "
-"Måste vara mellan 1000 och 999999999."
+msgstr "Antal omgångar att använda (används endast av sha256crypt och sha512crypt). Måste vara mellan 1000 och 999999999."
#: core/app_settings.py:69
-#, fuzzy
-#| msgid "Default password scheme"
msgid "Update password scheme at login"
-msgstr "Standard lösenords schema"
+msgstr "Uppdatera lösenordsschema vid inloggning"
#: core/app_settings.py:72
msgid "Update user password at login to use the default password scheme"
-msgstr ""
+msgstr "Uppdatera användarlösenord vid inloggning för att använda standard schema"
#: core/app_settings.py:77
msgid "Default password"
@@ -80,51 +75,47 @@ msgid "Default password for automatically created accounts."
msgstr "Standardlösenord för automatiskt skapade konton."
#: core/app_settings.py:84
-#, fuzzy
-#| msgid "Modoboa password reset"
msgid "Random password length"
-msgstr "Modoboa lösenordsåterställning."
+msgstr "Slumpmässig längd på lösenord"
#: core/app_settings.py:88
msgid "Length of randomly generated passwords."
-msgstr ""
+msgstr "Längd på slumpmässigt genererat lösenord"
#: core/app_settings.py:92
-#, fuzzy
-#| msgid "Default password scheme"
msgid "Update password service URL"
-msgstr "Standard lösenords schema"
+msgstr "Uppdatera lösenords service URL"
#: core/app_settings.py:96
msgid ""
"The URL of an external page where users will be able to update their "
"password. It applies only to non local users, ie. those automatically "
"created after a successful external authentication (LDAP, SMTP)."
-msgstr ""
+msgstr "Webbadressen till en extern sida där användare kan uppdatera sitt lösenord. Det gäller endast icke-lokala användare, dvs. de som skapas automatiskt efter en lyckad extern autentisering (LDAP, SMTP)."
#: core/app_settings.py:104
msgid "Password recovery announcement"
-msgstr ""
+msgstr "Meddelande om återställning av lösenord"
#: core/app_settings.py:109
msgid "A temporary message that will be displayed on the reset password page."
-msgstr ""
+msgstr "Ett tillfälligt meddelande som kommer att visas på sidan för återställning av lösenord."
#: core/app_settings.py:115
msgid "Enable password recovery by SMS"
-msgstr ""
+msgstr "Aktivera lösenordsåterställning via SMS"
#: core/app_settings.py:118
msgid "Enable password recovery by SMS for users who filled a phone number."
-msgstr ""
+msgstr "Aktivera återställning av lösenord via SMS för användare som fyllt i ett telefonnummer."
#: core/app_settings.py:124
msgid "SMS provider"
-msgstr ""
+msgstr "SMS provider"
#: core/app_settings.py:127
msgid "Choose a provider to send password recovery SMS"
-msgstr ""
+msgstr "Välj en leverantör för att skicka SMS för lösenordsåterställning"
#: core/app_settings.py:133
msgid "LDAP settings"
@@ -148,46 +139,36 @@ msgstr "TCP port som används av LDAP servern"
#: core/app_settings.py:149
msgid "Enable secondary server (fallback)"
-msgstr ""
+msgstr "Aktivera sekundär server (reserv)"
#: core/app_settings.py:152
msgid ""
"Enable a secondary LDAP server which will be used if the primary one fails"
-msgstr ""
+msgstr "Aktivera en sekundär LDAP-server som kommer att användas om den primära misslyckas"
#: core/app_settings.py:158
-#, fuzzy
-#| msgid "Server address"
msgid "Secondary server address"
-msgstr "Server adress"
+msgstr "Sekundär serveradress"
#: core/app_settings.py:161
-#, fuzzy
-#| msgid "The IP address or the DNS name of the LDAP server"
msgid "The IP address or the DNS name of the seondary LDAP server"
-msgstr "IP adressen eller DNS namn för LDAP server"
+msgstr "IP-adressen eller DNS-namnet på den sekundära LDAP-servern"
#: core/app_settings.py:165
-#, fuzzy
-#| msgid "Server port"
msgid "Secondary server port"
-msgstr "Server port"
+msgstr "Sekundär serverport"
#: core/app_settings.py:168
-#, fuzzy
-#| msgid "The TCP port number used by the LDAP server"
msgid "The TCP port number used by the LDAP secondary server"
-msgstr "TCP port som används av LDAP servern"
+msgstr "TCP-portnumret som används av LDAP sekundärserver"
#: core/app_settings.py:172
msgid "Use a secured connection"
msgstr "Använd en säker anslutning"
#: core/app_settings.py:176
-#, fuzzy
-#| msgid "Use an SSL/TLS connection to access the LDAP server"
msgid "Use an SSL/STARTTLS connection to access the LDAP server"
-msgstr "Använd SSL/TLS anslutning för åtkomst till LDAP servern"
+msgstr "Använd en SSL / STARTTLS-anslutning för att komma åt LDAP-servern"
#: core/app_settings.py:180
msgid "Active Directory"
@@ -203,11 +184,9 @@ msgstr "Administratörsgrupper"
#: core/app_settings.py:190
msgid ""
-"Members of those LDAP Posix groups will be created as domain administrators. "
-"Use ';' characters to separate groups."
-msgstr ""
-"Användare av dessa LDAP Posix grupper kommer skapas som "
-"domänadministratörer. Använd ';' för att separera grupper."
+"Members of those LDAP Posix groups will be created as domain administrators."
+" Use ';' characters to separate groups."
+msgstr "Användare av dessa LDAP Posix grupper kommer skapas som domänadministratörer. Använd ';' för att separera grupper."
#: core/app_settings.py:197
msgid "Group type"
@@ -234,10 +213,8 @@ msgid "The attribute used to store user passwords"
msgstr "Attribut som används för att lagra användarlösenord"
#: core/app_settings.py:222
-#, fuzzy
-#| msgid "Authentication method"
msgid "LDAP authentication settings"
-msgstr "Autentiseringsmetod"
+msgstr "LDAP autentiseringsinställningar"
#: core/app_settings.py:225
msgid "Authentication method"
@@ -263,9 +240,7 @@ msgstr "Bind DN"
msgid ""
"The distinguished name to use when binding to the LDAP server. Leave empty "
"for an anonymous bind"
-msgstr ""
-"Det unika namnet för att använda vid bindningar till LDAP-servern. Lämna "
-"tomt för en anonym bindning"
+msgstr "Det unika namnet för att använda vid bindningar till LDAP-servern. Lämna tomt för en anonym bindning"
#: core/app_settings.py:243 core/app_settings.py:297
msgid "Bind password"
@@ -273,8 +248,7 @@ msgstr "Bind lösenord"
#: core/app_settings.py:246 core/app_settings.py:300
msgid "The password to use when binding to the LDAP server (with 'Bind DN')"
-msgstr ""
-"Lösenordet ska användas vid bindning till LDAP-servern (med \"Bind DN ')"
+msgstr "Lösenordet ska användas vid bindning till LDAP-servern (med \"Bind DN ')"
#: core/app_settings.py:254 core/app_settings.py:346
msgid "Users search base"
@@ -292,9 +266,7 @@ msgstr "Sökfilter"
msgid ""
"An optional filter string (e.g. '(objectClass=person)'). In order to be "
"valid, it must be enclosed in parentheses."
-msgstr ""
-"En valfri filtersträng (t.ex. \"(objectClass = personer) '). För att vara "
-"giltigt måste det omges av parenteser."
+msgstr "En valfri filtersträng (t.ex. \"(objectClass = personer) '). För att vara giltigt måste det omges av parenteser."
#: core/app_settings.py:273
msgid "User DN template"
@@ -305,89 +277,74 @@ msgstr "Anvädar DN mall"
msgid ""
"The template used to construct a user's DN. It should contain one "
"placeholder (ie. %(user)s)"
-msgstr ""
-"Mallen som används för att konstruera en användares DN. Den bör innehålla en "
-"platshållare (dvs. %(user)s)"
+msgstr "Mallen som används för att konstruera en användares DN. Den bör innehålla en platshållare (dvs. %(user)s)"
#: core/app_settings.py:284
-#, fuzzy
-#| msgid "LDAP settings"
msgid "LDAP synchronization settings"
-msgstr "LDAP inställningar"
+msgstr "LDAP synkroniseringsinställningar"
#: core/app_settings.py:308
msgid "Enable export to LDAP"
-msgstr ""
+msgstr "Aktivera export till LDAP"
#: core/app_settings.py:311
msgid ""
"Enable automatic synchronization between local database and LDAP directory"
-msgstr ""
+msgstr "Aktivera automatisk synkronisering mellan lokal databas och LDAP-katalog"
#: core/app_settings.py:317
msgid "Delete remote LDAP account when local account is deleted"
-msgstr ""
+msgstr "Ta bort fjärran LDAP-konto när lokalt konto raderas"
#: core/app_settings.py:321
msgid ""
"Delete remote LDAP account when local account is deleted, otherwise it will "
"be disabled."
-msgstr ""
+msgstr "Radera LDAP-fjärrkonto när det lokala kontot raderas, annars inaktiveras det."
#: core/app_settings.py:327
-#, fuzzy
-#| msgid "User DN template"
msgid "Account DN template"
-msgstr "Anvädar DN mall"
+msgstr "DN-mall för kontot"
#: core/app_settings.py:330
-#, fuzzy, python-format
-#| msgid ""
-#| "The template used to construct a user's DN. It should contain one "
-#| "placeholder (ie. %(user)s)"
+#, python-format
msgid ""
"The template used to construct an account's DN. It should contain one "
"placeholder (ie. %(user)s)"
-msgstr ""
-"Mallen som används för att konstruera en användares DN. Den bör innehålla en "
-"platshållare (dvs. %(user)s)"
+msgstr "Mallen som används för att skapa ett kontos DN. Den ska innehålla en platshållare (ex.%(user)s)"
#: core/app_settings.py:337
msgid "Enable import from LDAP"
-msgstr ""
+msgstr "Aktiver import från LDAP"
#: core/app_settings.py:340
msgid "Enable account synchronization from LDAP directory to local database"
-msgstr ""
+msgstr "Aktivera kontosynkronisering från LDAP-katalog till lokal databas"
#: core/app_settings.py:365
-#, fuzzy
-#| msgid "Password attribute"
msgid "Username attribute"
-msgstr "Lösenordsattribut"
+msgstr "Attribut för användarnamn"
#: core/app_settings.py:368
msgid "The name of the LDAP attribute where the username can be found."
-msgstr ""
+msgstr "Namnet på LDAP-attributet där användarnamnet finns."
#: core/app_settings.py:373
-#, fuzzy
-#| msgid "Enable communication"
msgid "Enable Dovecot LDAP sync"
-msgstr "Aktivera kommunikation"
+msgstr "Aktivera Dovecot LDAP-synkronisering"
#: core/app_settings.py:376
msgid "LDAP authentication settings will be applied to Dovecot configuration."
-msgstr ""
+msgstr "LDAP-autentiseringsinställningar tillämpas på Dovecot-konfigurationen."
#: core/app_settings.py:382
msgid "Dovecot LDAP config file"
-msgstr ""
+msgstr "Dovecot LDAP-konfigurationsfil"
#: core/app_settings.py:386
msgid ""
"Location of the configuration file which contains Dovecot LDAP settings."
-msgstr ""
+msgstr "Plats för konfigurationsfilen som innehåller Dovecot LDAP-inställningar."
#: core/app_settings.py:391 core/templates/core/dashboard.html:5
msgid "Dashboard"
@@ -399,8 +356,7 @@ msgstr "Användardefinierat RSS-flöde"
#: core/app_settings.py:397
msgid "Display custom RSS feed to resellers and domain administrators"
-msgstr ""
-"Visa användardefinierat RSS-flöde för återförsäljare och domänadministratörer"
+msgstr "Visa användardefinierat RSS-flöde för återförsäljare och domänadministratörer"
#: core/app_settings.py:402
msgid "Hide features widget"
@@ -444,19 +400,19 @@ msgstr "Kontrollera automatiskt om en nyare version finns"
#: core/app_settings.py:436
msgid "Send an email when new versions are found"
-msgstr ""
+msgstr "Skicka ett mejl när nya versioner hittas"
#: core/app_settings.py:439
msgid "Send an email to notify admins about new versions"
-msgstr ""
+msgstr "Skicka ett e-postmeddelande för att meddela administratörer om nya versioner"
#: core/app_settings.py:443
msgid "Recipient"
-msgstr ""
+msgstr "Mottagare"
#: core/app_settings.py:446
msgid "Recipient of new versions notification emails."
-msgstr ""
+msgstr "Mottagare av e-postmeddelanden om nya versioner."
#: core/app_settings.py:451
msgid "Send statistics"
@@ -464,8 +420,7 @@ msgstr "Skicka statistik"
#: core/app_settings.py:454
msgid "Send statistics to Modoboa public API (counters and used extensions)"
-msgstr ""
-"Skicka statistik för Modoboas publika API (räknare och använda tillägg)"
+msgstr "Skicka statistik för Modoboas publika API (räknare och använda tillägg)"
#: core/app_settings.py:458
msgid "Miscellaneous"
@@ -473,13 +428,13 @@ msgstr "Övrigt"
#: core/app_settings.py:461
msgid "Inactive account threshold"
-msgstr ""
+msgstr "Gräns för inaktiva konton"
#: core/app_settings.py:464
msgid ""
-"An account with a last login date greater than this threshold (in days) will "
-"be considered as inactive"
-msgstr ""
+"An account with a last login date greater than this threshold (in days) will"
+" be considered as inactive"
+msgstr "Ett konto som inte har loggat in innan denna gräns (antal dagar) kommer anses som inaktivt"
#: core/app_settings.py:470
msgid "Top notifications check interval"
@@ -534,11 +489,11 @@ msgid ""
"You have USE_TZ set to False, this may result in issues during transitions "
"between summer/winter time (ie the same local time occuring twice due to "
"clock change)."
-msgstr ""
+msgstr "Du måste ange USE_TZ till False, detta kan leda till problem under övergångar mellan sommar / vintertid (dvs samma lokal tid som uppträder två gånger på grund av klockbyte)."
#: core/checks/settings_checks.py:9
msgid "Set `USE_TZ = True` in settings.py"
-msgstr ""
+msgstr "Ange `USE_TZ = True` i settings.py"
#: core/constants.py:6
msgid "Simple user"
@@ -562,11 +517,11 @@ msgstr "Nej"
#: core/constants.py:102
msgid "Choose a provider"
-msgstr ""
+msgstr "Välj leverantör"
#: core/constants.py:107
msgid "Dummy"
-msgstr ""
+msgstr "Dummy"
#: core/forms.py:21
msgid "Username"
@@ -601,16 +556,12 @@ msgid "Enable API access"
msgstr "Aktivera API access"
#: core/forms.py:137
-#, fuzzy
-#| msgid "Notifications"
msgid "Verification code"
-msgstr "Notifikationer"
+msgstr "Verifikationskod"
#: core/forms.py:148
-#, fuzzy
-#| msgid "Invalid line"
msgid "Invalid code"
-msgstr "Ogiltig rad"
+msgstr "Ogiltig kod"
#: core/handlers.py:36
msgid "added"
@@ -626,10 +577,9 @@ msgid "%(object)s '%(name)s' %(action)s by user %(user)s"
msgstr "%(object)s '%(name)s' %(action)s av användare %(user)s"
#: core/handlers.py:63
-#, fuzzy, python-format
-#| msgid "%(object)s '%(name)s' %(action)s by user %(user)s"
+#, python-format
msgid "%(object)s '%(name)s' %(action)s by "
-msgstr "%(object)s '%(name)s' %(action)s av användare %(user)s"
+msgstr "%(object)s '%(name)s' %(action)s av"
#: core/handlers.py:65
msgid "deleted"
@@ -637,11 +587,11 @@ msgstr "raderad"
#: core/handlers.py:69
msgid "user {}"
-msgstr ""
+msgstr "användare {}"
#: core/handlers.py:71
msgid "management command"
-msgstr ""
+msgstr "management kommando"
#: core/handlers.py:95
msgid "You can't delete your own account"
@@ -652,10 +602,8 @@ msgid "One or more updates are available"
msgstr "En eller fler uppdateringar finns tillgängliga"
#: core/management/commands/communicate_with_public_api.py:44
-#, fuzzy
-#| msgid "One or more updates are available"
msgid "[modoboa] Update(s) available"
-msgstr "En eller fler uppdateringar finns tillgängliga"
+msgstr "[modoboa] Uppdatering(ar) finns"
#: core/models.py:55
msgid "Allow mailboxes access"
@@ -749,51 +697,47 @@ msgstr "Ditt lösenord måste innehålla en kombination av olika typer av tecken
#: core/sms_backends/ovh.py:19
msgid "API endpoint"
-msgstr ""
+msgstr "API endpoint"
#: core/sms_backends/ovh.py:22
msgid "OVH Europe"
-msgstr ""
+msgstr "OVH Europe"
#: core/sms_backends/ovh.py:23
msgid "OVH US"
-msgstr ""
+msgstr "OVH US"
#: core/sms_backends/ovh.py:24
msgid "OVH North-America"
-msgstr ""
+msgstr "OVH Nordamerika"
#: core/sms_backends/ovh.py:25
msgid "So you Start Europe"
-msgstr ""
+msgstr "So you Start Europa"
#: core/sms_backends/ovh.py:26
msgid "So you Start North America"
-msgstr ""
+msgstr "So you Start Nordamerika"
#: core/sms_backends/ovh.py:27
msgid "Kimsufi Europe"
-msgstr ""
+msgstr "Kimsufi Europa"
#: core/sms_backends/ovh.py:28
msgid "Kimsufi North America"
-msgstr ""
+msgstr "Kimsufi Nordamerika"
#: core/sms_backends/ovh.py:35
-#, fuzzy
-#| msgid "Applications"
msgid "Application key"
-msgstr "Applikationer"
+msgstr "Applikationsnyckel"
#: core/sms_backends/ovh.py:42
-#, fuzzy
-#| msgid "Applications"
msgid "Application secret"
-msgstr "Applikationer"
+msgstr "Applikationshemlighet"
#: core/sms_backends/ovh.py:50
msgid "Consumer key"
-msgstr ""
+msgstr "Konsumentnyckel"
#: core/templates/core/_current_features.html:6
msgid "Features looking for sponsoring"
@@ -819,9 +763,7 @@ msgstr "Senaste nytt"
msgid ""
"Visit the official "
"weblog for more information."
-msgstr ""
-"Besök den officiella "
-"bloggen för mer information."
+msgstr "Besök den officiella bloggen för mer information."
#: core/templates/core/api_access.html:3
msgid "API access"
@@ -834,11 +776,9 @@ msgstr "Kontrollera din åtskomst till Modoboa API"
#: core/templates/core/api_access.html:7
#, python-format
msgid ""
-"A documentation of the API is available here."
-msgstr ""
-"Dokumentation över API:et finns här."
+"A documentation of the API is available here."
+msgstr "Dokumentation över API:et finns här."
#: core/templates/core/api_access.html:14
msgid "API access token"
@@ -868,8 +808,7 @@ msgstr "En eller flera uppdateringar finns tillgängliga!"
#: core/templates/core/information.html:6
msgid "Check the following list to find the component(s) that can be updated."
-msgstr ""
-"Kontrollera följande lista för att se de komponenter som kan uppdateras."
+msgstr "Kontrollera följande lista för att se de komponenter som kan uppdateras."
#: core/templates/core/information.html:10
msgid "Applications"
@@ -929,16 +868,14 @@ msgid "Message"
msgstr "Meddelande"
#: core/templates/core/notifications/update_available.html:3
-#, fuzzy
-#| msgid "One or more updates are available"
msgid ""
"\n"
" The following update is available:\n"
msgid_plural ""
"\n"
" The following updates are available:\n"
-msgstr[0] "En eller fler uppdateringar finns tillgängliga"
-msgstr[1] "En eller fler uppdateringar finns tillgängliga"
+msgstr[0] "\n Följande uppdateringar finns tillgängliga:\n"
+msgstr[1] "\n Följande uppdateringar finns tillgängliga:\n"
#: core/templates/core/parameters.html:2 core/templatetags/core_tags.py:71
msgid "Parameters"
@@ -983,10 +920,8 @@ msgid "Update your personal information"
msgstr "Uppdatera personlig information"
#: core/templates/core/user_profile.html:13
-#, fuzzy
-#| msgid "Failed to update password: {}"
msgid "Click here to update your password"
-msgstr "Misslyckades med att uppdatera lösenord: {}"
+msgstr "Klicka här för att uppdatera ditt lösenord"
#: core/templatetags/core_tags.py:34
msgid "Modoboa"
@@ -1011,12 +946,12 @@ msgstr "Parametrar sparade"
#: core/views/auth.py:59
#, python-format
msgid "Password scheme mismatch. Updating %s password"
-msgstr ""
+msgstr "Fel lösenordsschema. Uppdaterar %s lösenord"
#: core/views/auth.py:66
#, python-format
msgid "Password hash parameter missmatch. Updating %s password"
-msgstr ""
+msgstr "Fel lösenordshash. Uppdaterar %s lösenord"
#: core/views/auth.py:82
#, python-format
@@ -1033,7 +968,7 @@ msgstr "Användare '{}' loggade ut framgångsrikt"
#: core/views/auth.py:170 core/views/auth.py:225
msgid "Please use the following code to recover your Modoboa password: {}"
-msgstr ""
+msgstr "Använd följande kod för att återställa ditt Modoboa lösenord: {}"
#: core/views/user.py:53
msgid "Profile updated"
@@ -1054,7 +989,7 @@ msgstr "Anslutning till databasen %s är inte konfigurerad"
#: lib/email_utils.py:141 lib/email_utils.py:360
msgid "unable to determine encoding of string"
-msgstr ""
+msgstr "kan inte bestämma kodning av sträng"
#: lib/exceptions.py:67
#, python-format
@@ -1136,8 +1071,9 @@ msgstr "Fel:"
msgid "Help:"
msgstr "Hjälp:"
-#: templates/common/generic_modal.html:6 templates/common/generic_modal.html:13
-#: templates/common/wizard_forms.html:6 templates/common/wizard_forms.html:27
+#: templates/common/generic_modal.html:6
+#: templates/common/generic_modal.html:13 templates/common/wizard_forms.html:6
+#: templates/common/wizard_forms.html:27
msgid "Close"
msgstr "Stäng"
@@ -1171,9 +1107,7 @@ msgstr "Glömt ditt lösenord?"
msgid ""
"Your password has been set. You may go ahead and sign "
"in now."
-msgstr ""
-"Ditt lösenord har ändrats. Du kan fortsätta med att logga in."
+msgstr "Ditt lösenord har ändrats. Du kan fortsätta med att logga in."
#: templates/registration/password_reset_confirm.html:7
msgid "Change password"
@@ -1183,17 +1117,15 @@ msgstr "Ändra lösenord"
msgid ""
"The password reset link was invalid, possibly because it has already been "
"used. Please request a new password reset."
-msgstr ""
-"Lösenordets återställningslänk är ogiltig, förmodligen för att den redan "
-"använts. Var vänlig begär en ny återställning av lösenord."
+msgstr "Lösenordets återställningslänk är ogiltig, förmodligen för att den redan använts. Var vänlig begär en ny återställning av lösenord."
#: templates/registration/password_reset_confirm_code.html:20
msgid "Enter the code you've just received by SMS"
-msgstr ""
+msgstr "Ange koden du precis fick via SMS"
#: templates/registration/password_reset_confirm_code.html:27
msgid "Resend code"
-msgstr ""
+msgstr "Skicka kod igen"
#: templates/registration/password_reset_done.html:7
msgid ""
@@ -1201,28 +1133,20 @@ msgid ""
"exists with the email you entered. You should receive them shortly.
"
"
If you don't receive an email, please make sure you've entered your "
"primary address, and check your spam folder.
"
-msgstr ""
-"
Vi har e-postat dig instruktioner för att ändra ditt lösenord, om ett "
-"konto finns med den e-post adress du angav. Du borde få detta brev inom kort."
-"
Om du inte fått något brev, var vänlig kontrollera att du angav rätt "
-"e-post adress, och kolla din skräpkatalog.
"
+msgstr "
Vi har e-postat dig instruktioner för att ändra ditt lösenord, om ett konto finns med den e-post adress du angav. Du borde få detta brev inom kort.
Om du inte fått något brev, var vänlig kontrollera att du angav rätt e-post adress, och kolla din skräpkatalog.
"
#: templates/registration/password_reset_email.html:4
#, python-format
msgid ""
"To initiate the password reset process for your %(username)s Modoboa "
"account, click the link below:"
-msgstr ""
-"För att starta processen för återställning av lösenord för ditt %(username)s "
-"Modoboa konto, klicka på länken nedanför:"
+msgstr "För att starta processen för återställning av lösenord för ditt %(username)s Modoboa konto, klicka på länken nedanför:"
#: templates/registration/password_reset_email.html:10
msgid ""
"If clicking the link above doesn't work, please copy and paste the URL in a "
"new browser window instead."
-msgstr ""
-"Om det ej går att klicka på länken, klipp och klistra länken i ett nytt "
-"webbläsarfönster istället."
+msgstr "Om det ej går att klicka på länken, klipp och klistra länken i ett nytt webbläsarfönster istället."
#: templates/registration/password_reset_email.html:14
msgid "Sincerely, The Modoboa Team."
@@ -1230,32 +1154,8 @@ msgstr "Vänligen, Modoboa teamet."
#: templates/registration/password_reset_form.html:24
msgid "Please fill-in your primary email address"
-msgstr ""
+msgstr "Var vänlig fyll i din primära e-postadress"
#: templates/registration/password_reset_subject.txt:3
msgid "Modoboa password reset"
msgstr "Modoboa lösenordsåterställning."
-
-#~ msgid "md5crypt (weak)"
-#~ msgstr "md5crypt (svag)"
-
-#~ msgid "sha256 (weak)"
-#~ msgstr "sha256 (svag)"
-
-#~ msgid "md5 (weak)"
-#~ msgstr "md5 (svag)"
-
-#~ msgid "crypt (weak)"
-#~ msgstr "crypt (svag)"
-
-#~ msgid "plain (weak)"
-#~ msgstr "okrypterad (svag)"
-
-#~ msgid "Secret key"
-#~ msgstr "Hemlig nyckel"
-
-#~ msgid "Key used to encrypt/decrypt passwords"
-#~ msgstr "Nyckel som används för att kryptera / dekryptera lösenord"
-
-#~ msgid "Key must be either 16, 24, or 32 bytes long"
-#~ msgstr "Nyckel måste vara endera 16, 24 eller 32 bytes lång"
From 1aed875f6865046a0d538a1a0772e50962987789 Mon Sep 17 00:00:00 2001
From: Antoine Nguyen
Date: Fri, 23 Oct 2020 16:31:05 +0200
Subject: [PATCH 13/44] Disable forward when account is disabled.
see #1761
---
modoboa/admin/forms/account.py | 5 +++++
modoboa/admin/tests/test_account.py | 23 +++++++++++++++++++++++
2 files changed, 28 insertions(+)
diff --git a/modoboa/admin/forms/account.py b/modoboa/admin/forms/account.py
index ff5e1e0c7..f2ca42690 100644
--- a/modoboa/admin/forms/account.py
+++ b/modoboa/admin/forms/account.py
@@ -204,6 +204,11 @@ class AccountFormGeneral(forms.ModelForm):
account.set_password(self.cleaned_data["password2"])
account.save()
account.role = self.cleaned_data["role"]
+ if hasattr(account, "mailbox"):
+ # Update forward status according to account status
+ models.Alias.objects.filter(
+ address=account.email, internal=False).update(
+ enabled=account.is_active)
return account
diff --git a/modoboa/admin/tests/test_account.py b/modoboa/admin/tests/test_account.py
index f5df49a44..4eb722c45 100644
--- a/modoboa/admin/tests/test_account.py
+++ b/modoboa/admin/tests/test_account.py
@@ -119,6 +119,29 @@ class AccountTestCase(ModoTestCase):
account = User.objects.get(username=values["username"])
self.assertEqual(account.language, "fr")
+ def test_forward_updated_on_edit(self):
+ account = User.objects.get(username="user@test.com")
+ forward = models.Alias.objects.create(address=account.email, internal=False)
+ values = {
+ "username": "user@test.com",
+ "role": "SimpleUsers",
+ "quota_act": True,
+ "is_active": False,
+ "email": "user@test.com",
+ "language": "en"
+ }
+ self.ajax_post(
+ reverse("admin:account_change", args=[account.id]), values
+ )
+ forward.refresh_from_db()
+ self.assertFalse(forward.enabled)
+ values["is_active"] = True
+ self.ajax_post(
+ reverse("admin:account_change", args=[account.id]), values
+ )
+ forward.refresh_from_db()
+ self.assertTrue(forward.enabled)
+
def test_aliases_update_on_rename(self):
"""Check if aliases are updated on mailbox rename."""
account = User.objects.get(username="user@test.com")
From abb41b08aeac13f399bc92020ec88485e343e26b Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Fri, 23 Oct 2020 17:46:51 +0000
Subject: [PATCH 14/44] Bump django-otp from 1.0.1 to 1.0.2
Bumps [django-otp](https://github.com/django-otp/django-otp) from 1.0.1 to 1.0.2.
- [Release notes](https://github.com/django-otp/django-otp/releases)
- [Changelog](https://github.com/django-otp/django-otp/blob/master/CHANGES.rst)
- [Commits](https://github.com/django-otp/django-otp/compare/v1.0.1...v1.0.2)
Signed-off-by: dependabot-preview[bot]
---
requirements.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/requirements.txt b/requirements.txt
index 784f34c99..1c832f82d 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -4,7 +4,7 @@ django-ckeditor==5.8.0
django-phonenumber-field[phonenumbers]==4.0.0
django-reversion==3.0.5
django-xforwardedfor-middleware==2.0
-django-otp==1.0.1
+django-otp==1.0.2
dj-database-url
From 7505a946aa77dbfce1800298108b8cfb865a5a05 Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Fri, 23 Oct 2020 20:03:57 +0200
Subject: [PATCH 15/44] Create Dependabot config file (#2045)
Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
---
.github/dependabot.yml | 7 +++++++
1 file changed, 7 insertions(+)
create mode 100644 .github/dependabot.yml
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 000000000..491deae0a
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,7 @@
+version: 2
+updates:
+- package-ecosystem: pip
+ directory: "/"
+ schedule:
+ interval: daily
+ open-pull-requests-limit: 10
From d5b02a6a682aab85dfe71ccb03c11ae8ec5ff77f Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Fri, 23 Oct 2020 18:04:39 +0000
Subject: [PATCH 16/44] Update passlib requirement from ~=1.7.3 to ~=1.7.4
Updates the requirements on [passlib](https://passlib.readthedocs.io) to permit the latest version.
Signed-off-by: dependabot[bot]
---
requirements.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/requirements.txt b/requirements.txt
index 784f34c99..b93ca5a7b 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -11,7 +11,7 @@ dj-database-url
djangorestframework>=3.11,<3.12
uritemplate
-passlib~=1.7.3
+passlib~=1.7.4
bcrypt # Requires libffi-dev and python-dev
dnspython==1.16.0
From 42c9a6d63ab816cdcd6700d8c922b8dfc3dfb525 Mon Sep 17 00:00:00 2001
From: Christophe CHAUVET
Date: Fri, 23 Oct 2020 20:41:35 +0200
Subject: [PATCH 17/44] Create stale.yml (#2061)
Add Stale Bot
---
.github/stale.yml | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
create mode 100644 .github/stale.yml
diff --git a/.github/stale.yml b/.github/stale.yml
new file mode 100644
index 000000000..479deabbd
--- /dev/null
+++ b/.github/stale.yml
@@ -0,0 +1,28 @@
+# Number of days of inactivity before an issue becomes stale
+daysUntilStale: 60
+# Number of days of inactivity before a stale issue is closed
+daysUntilClose: 14
+# Issues with these labels will never be considered stale
+exemptLabels:
+ - pinned
+ - security
+ - bug
+ - dependencies
+ - enhancement
+ - looking-for-sponsors
+ - documentation
+# Label to use when marking an issue as stale
+staleLabel: wontfix
+# Set to true to ignore issues in a milestone (defaults to false)
+exemptMilestones: true
+# Set to true to ignore issues with an assignee (defaults to false)
+exemptAssignees: true
+# Limit to only `issues` or `pulls`
+only: issues
+# Comment to post when marking an issue as stale. Set to `false` to disable
+markComment: >
+ This issue has been automatically marked as stale because it has not had
+ recent activity. It will be closed if no further activity occurs. Thank you
+ for your contributions.
+# Comment to post when closing a stale issue. Set to `false` to disable
+closeComment: false
From 60dd46d06f3c7e371d4b89c506de7962a6b6c4de Mon Sep 17 00:00:00 2001
From: Christophe CHAUVET
Date: Fri, 23 Oct 2020 21:56:33 +0200
Subject: [PATCH 18/44] Mergify: configuration update (#2062)
---
.mergify.yml | 44 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
create mode 100644 .mergify.yml
diff --git a/.mergify.yml b/.mergify.yml
new file mode 100644
index 000000000..a506741d4
--- /dev/null
+++ b/.mergify.yml
@@ -0,0 +1,44 @@
+pull_request_rules:
+ - name: automatic merge on CI success and review
+ conditions:
+ - check-success=Travis CI - Pull Request
+ - "#approved-reviews-by>=1"
+ - "#review-requested=0"
+ - "#changes-requested-reviews-by=0"
+ - "#commented-reviews-by=0"
+ - label=ready-to-merge
+ actions:
+ merge:
+ method: squash
+ strict: true
+ strict_method: rebase
+ - name: delete head branch after merge
+ conditions: []
+ actions:
+ delete_head_branch: {}
+ - name: automatic merge for pyUp pull requests
+ conditions:
+ - author=pyup-bot
+ - check-success=Travis CI - Pull Request
+ - label=dependencies
+ actions:
+ merge:
+ method: squash
+ strict: true
+ strict_method: rebase
+ - name: automatic merge for dependabot pull requests
+ conditions:
+ - author~=^dependabot(|-preview)\[bot\]$
+ - check-success=Travis CI - Pull Request
+ - label=dependencies
+ actions:
+ merge:
+ method: squash
+ strict: true
+ strict_method: rebasepull_request_rules:
+ - name: Automatic merge on approval
+ conditions:
+ - "#approved-reviews-by>=1"
+ actions:
+ merge:
+ method: merge
From 991ed6c8d8e891dbea5e1be247acf79550f1d2d4 Mon Sep 17 00:00:00 2001
From: Christophe CHAUVET
Date: Fri, 23 Oct 2020 22:02:12 +0200
Subject: [PATCH 19/44] Update stale.yml
---
.github/stale.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/stale.yml b/.github/stale.yml
index 479deabbd..eacc2eb55 100644
--- a/.github/stale.yml
+++ b/.github/stale.yml
@@ -12,7 +12,7 @@ exemptLabels:
- looking-for-sponsors
- documentation
# Label to use when marking an issue as stale
-staleLabel: wontfix
+staleLabel: stale
# Set to true to ignore issues in a milestone (defaults to false)
exemptMilestones: true
# Set to true to ignore issues with an assignee (defaults to false)
From a9a84fef006a4bb2fade86aecabff049a2866517 Mon Sep 17 00:00:00 2001
From: Christophe CHAUVET
Date: Fri, 23 Oct 2020 22:04:11 +0200
Subject: [PATCH 20/44] Fix mergify.io
---
.mergify.yml | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/.mergify.yml b/.mergify.yml
index a506741d4..9789e9c38 100644
--- a/.mergify.yml
+++ b/.mergify.yml
@@ -35,10 +35,4 @@ pull_request_rules:
merge:
method: squash
strict: true
- strict_method: rebasepull_request_rules:
- - name: Automatic merge on approval
- conditions:
- - "#approved-reviews-by>=1"
- actions:
- merge:
- method: merge
+ strict_method: rebase
From c15b4fbb979ba0b8494fb4a779390a698fc7633b Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Sat, 24 Oct 2020 12:43:36 +0200
Subject: [PATCH 21/44] Bump django-phonenumber-field[phonenumbers] from 4.0.0
to 5.0.0 (#2056)
Bumps [django-phonenumber-field[phonenumbers]](https://github.com/stefanfoulis/django-phonenumber-field) from 4.0.0 to 5.0.0.
- [Release notes](https://github.com/stefanfoulis/django-phonenumber-field/releases)
- [Changelog](https://github.com/stefanfoulis/django-phonenumber-field/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/stefanfoulis/django-phonenumber-field/compare/4.0.0...5.0.0)
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
requirements.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/requirements.txt b/requirements.txt
index fe3939348..9f4ab00d4 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,7 +1,7 @@
django>=2.2,<2.3
django-braces==1.14.0
django-ckeditor==5.8.0
-django-phonenumber-field[phonenumbers]==4.0.0
+django-phonenumber-field[phonenumbers]==5.0.0
django-reversion==3.0.5
django-xforwardedfor-middleware==2.0
django-otp==1.0.2
From 3bb0c3d38418d5c45e8759abb80369f61079ed74 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Sat, 24 Oct 2020 11:16:52 +0000
Subject: [PATCH 22/44] Bump django-ckeditor from 5.8.0 to 6.0.0 (#2057)
Bumps [django-ckeditor](https://github.com/django-ckeditor/django-ckeditor) from 5.8.0 to 6.0.0.
- [Release notes](https://github.com/django-ckeditor/django-ckeditor/releases)
- [Changelog](https://github.com/django-ckeditor/django-ckeditor/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/django-ckeditor/django-ckeditor/compare/5.8.0...6.0.0)
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
requirements.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/requirements.txt b/requirements.txt
index 9f4ab00d4..d7241c8c3 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,6 +1,6 @@
django>=2.2,<2.3
django-braces==1.14.0
-django-ckeditor==5.8.0
+django-ckeditor==6.0.0
django-phonenumber-field[phonenumbers]==5.0.0
django-reversion==3.0.5
django-xforwardedfor-middleware==2.0
From 8b3af1ae172c3505019aa910d01ed0c50e95099c Mon Sep 17 00:00:00 2001
From: Christophe CHAUVET
Date: Sat, 24 Oct 2020 16:13:48 +0200
Subject: [PATCH 23/44] Update Gevent and Greenlet version together (#2063)
---
requirements.txt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/requirements.txt b/requirements.txt
index d7241c8c3..8242a5aea 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -16,8 +16,8 @@ bcrypt # Requires libffi-dev and python-dev
dnspython==1.16.0
feedparser==5.2.1
-greenlet==0.4.16
-gevent==1.5.0
+greenlet==0.4.17
+gevent==20.9.0
jsonfield==2.0.2
Pillow # Optional dependency for django-ckeditor
progressbar33==2.4
From e93cb49a8ded80b4f193bf826c45ddb3a6e85aad Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Sat, 24 Oct 2020 18:45:04 +0000
Subject: [PATCH 24/44] Bump testfixtures from 6.10.3 to 6.15.0 (#2049)
Bumps [testfixtures](https://github.com/Simplistix/testfixtures) from 6.10.3 to 6.15.0.
- [Release notes](https://github.com/Simplistix/testfixtures/releases)
- [Changelog](https://github.com/Simplistix/testfixtures/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/Simplistix/testfixtures/compare/6.10.3...6.15.0)
Signed-off-by: dependabot-preview[bot]
Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
---
test-requirements.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test-requirements.txt b/test-requirements.txt
index 4a6ebba6f..285c1529d 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -1,6 +1,6 @@
argon2-cffi>=16.1.0
factory-boy<=2.12.0
httmock==1.3.0
-testfixtures==6.10.3
+testfixtures==6.15.0
tox
asynctest
From e4dbb430e5d515f9dec9a21a6a8f140e2e276ee8 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Thu, 29 Oct 2020 05:20:03 +0000
Subject: [PATCH 25/44] Bump httmock from 1.3.0 to 1.4.0 (#2074)
Bumps [httmock](https://github.com/patrys/httmock) from 1.3.0 to 1.4.0.
- [Release notes](https://github.com/patrys/httmock/releases)
- [Commits](https://github.com/patrys/httmock/compare/1.3.0...1.4.0)
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
test-requirements.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test-requirements.txt b/test-requirements.txt
index 285c1529d..6006e2bb4 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -1,6 +1,6 @@
argon2-cffi>=16.1.0
factory-boy<=2.12.0
-httmock==1.3.0
+httmock==1.4.0
testfixtures==6.15.0
tox
asynctest
From 28b41c6951ea92a3d6a26ed3ed99ffe4fc0ed1cd Mon Sep 17 00:00:00 2001
From: Christophe CHAUVET
Date: Fri, 30 Oct 2020 09:01:18 +0100
Subject: [PATCH 26/44] Update ISSUE_TEMPLATE.md
---
.github/ISSUE_TEMPLATE.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 4ff4bec52..6e384061a 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -1,5 +1,7 @@
# Impacted versions
+* OS Type: Debian/Ubuntu, Centos/Redhat, Arch, Gentoo, Slack, ...
+* OS Version: Number or Name
* Modoboa: X.X.x
* installer used: Yes/No ?
* Webserver: Nginx/Apache
From f91ac728fadce3f9e55639ed4461ded3fe378b03 Mon Sep 17 00:00:00 2001
From: Christophe CHAUVET
Date: Fri, 30 Oct 2020 09:20:25 +0100
Subject: [PATCH 27/44] Add database information
---
.github/ISSUE_TEMPLATE.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 6e384061a..b1c69ef2f 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -2,6 +2,8 @@
* OS Type: Debian/Ubuntu, Centos/Redhat, Arch, Gentoo, Slack, ...
* OS Version: Number or Name
+* Database Type: PostgreSQL/MySQL
+* Database version: X.y
* Modoboa: X.X.x
* installer used: Yes/No ?
* Webserver: Nginx/Apache
From 7f94090cb2e6ee53b0e5fcf6958ac4ba1efb535d Mon Sep 17 00:00:00 2001
From: Christophe CHAUVET
Date: Fri, 30 Oct 2020 13:19:43 +0100
Subject: [PATCH 28/44] On Mergify add the revue by one maintainer
---
.mergify.yml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.mergify.yml b/.mergify.yml
index 9789e9c38..9cc823a39 100644
--- a/.mergify.yml
+++ b/.mergify.yml
@@ -21,6 +21,7 @@ pull_request_rules:
- author=pyup-bot
- check-success=Travis CI - Pull Request
- label=dependencies
+ - "#approved-reviews-by>=1"
actions:
merge:
method: squash
@@ -31,6 +32,7 @@ pull_request_rules:
- author~=^dependabot(|-preview)\[bot\]$
- check-success=Travis CI - Pull Request
- label=dependencies
+ - "#approved-reviews-by>=1"
actions:
merge:
method: squash
From f2f3463a17c63f69aa9ffe50564c1653ae99253c Mon Sep 17 00:00:00 2001
From: Antoine Nguyen
Date: Thu, 5 Nov 2020 15:49:32 +0100
Subject: [PATCH 29/44] Updated translations.
---
modoboa/locale/en/LC_MESSAGES/django.po | 154 +++++++---
modoboa/locale/en/LC_MESSAGES/djangojs.po | 12 +-
modoboa/locale/fr/LC_MESSAGES/django.po | 350 ++++++++++++++++------
modoboa/locale/fr/LC_MESSAGES/djangojs.po | 21 +-
4 files changed, 404 insertions(+), 133 deletions(-)
diff --git a/modoboa/locale/en/LC_MESSAGES/django.po b/modoboa/locale/en/LC_MESSAGES/django.po
index 6fb2f1d25..96f737f68 100644
--- a/modoboa/locale/en/LC_MESSAGES/django.po
+++ b/modoboa/locale/en/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-05-06 13:15+0200\n"
+"POT-Creation-Date: 2020-11-05 15:36+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -520,46 +520,50 @@ msgstr ""
msgid "Dummy"
msgstr ""
-#: core/forms.py:21
+#: core/forms.py:23
msgid "Username"
msgstr ""
-#: core/forms.py:25
+#: core/forms.py:27
msgid "Password"
msgstr ""
-#: core/forms.py:38
+#: core/forms.py:40
msgid "Old password"
msgstr ""
-#: core/forms.py:42
+#: core/forms.py:44
msgid "New password"
msgstr ""
-#: core/forms.py:46
+#: core/forms.py:48
msgid "Confirmation"
msgstr ""
-#: core/forms.py:74
+#: core/forms.py:76
msgid "Old password mismatchs"
msgstr ""
-#: core/forms.py:83
+#: core/forms.py:85
msgid "Passwords mismatch"
msgstr ""
-#: core/forms.py:103
+#: core/forms.py:105
msgid "Enable API access"
msgstr ""
-#: core/forms.py:137
+#: core/forms.py:139
msgid "Verification code"
msgstr ""
-#: core/forms.py:148
+#: core/forms.py:150
msgid "Invalid code"
msgstr ""
+#: core/forms.py:163
+msgid "This code is invalid"
+msgstr ""
+
#: core/handlers.py:36
msgid "added"
msgstr ""
@@ -602,35 +606,35 @@ msgstr ""
msgid "[modoboa] Update(s) available"
msgstr ""
-#: core/models.py:55
+#: core/models.py:52
msgid "Allow mailboxes access"
msgstr ""
-#: core/models.py:57
+#: core/models.py:54
msgid "Allow this administrator to access user mailboxes"
msgstr ""
-#: core/models.py:60
+#: core/models.py:57
msgid "password"
msgstr ""
-#: core/models.py:63
+#: core/models.py:60
msgid "language"
msgstr ""
-#: core/models.py:66
+#: core/models.py:63
msgid "Prefered language to display pages."
msgstr ""
-#: core/models.py:70
+#: core/models.py:67
msgid "Phone number"
msgstr ""
-#: core/models.py:72
+#: core/models.py:69
msgid "Secondary email"
msgstr ""
-#: core/models.py:75
+#: core/models.py:72
msgid "An alternative e-mail address, can be used for recovery needs."
msgstr ""
@@ -692,6 +696,14 @@ msgstr[1] ""
msgid "Your password must contain a combination of different character types."
msgstr ""
+#: core/serializers.py:15
+msgid "Invalid PIN code"
+msgstr ""
+
+#: core/serializers.py:21
+msgid "2FA is already enabled"
+msgstr ""
+
#: core/sms_backends/ovh.py:19
msgid "API endpoint"
msgstr ""
@@ -920,6 +932,79 @@ msgstr ""
msgid "Click here to update your password"
msgstr ""
+#: core/templates/core/user_security.html:2 core/templatetags/core_tags.py:124
+msgid "Security"
+msgstr ""
+
+#: core/templates/core/user_security.html:6
+msgid "Two-Factor authentication"
+msgstr ""
+
+#: core/templates/core/user_security.html:17
+msgid ""
+"Install a soft token authenticator like FreeOTP or Google Authenticator from "
+"your application repository and use that app to scan this QR code."
+msgstr ""
+
+#: core/templates/core/user_security.html:25
+msgid "Pin code"
+msgstr ""
+
+#: core/templates/core/user_security.html:28
+msgid "Register"
+msgstr ""
+
+#: core/templates/core/user_security.html:33
+msgid ""
+"Congratulations! Two-Factor Authentication is now enabled for your account."
+msgstr ""
+
+#: core/templates/core/user_security.html:38
+#: core/templates/core/user_security.html:89
+msgid ""
+"The following recovery codes can be used one time each to let you regain "
+"access to your account, in case you lose your phone for example. Make sure "
+"to save them in a safe place, otherwise you won't be able to access your "
+"account anymore."
+msgstr ""
+
+#: core/templates/core/user_security.html:53
+msgid "Two-Factor Authentication is enabled for your account."
+msgstr ""
+
+#: core/templates/core/user_security.html:58
+msgid "Disable 2FA"
+msgstr ""
+
+#: core/templates/core/user_security.html:61
+msgid "Reset recovery codes"
+msgstr ""
+
+#: core/templates/core/user_security.html:65
+msgid ""
+"Two-Factor Authentication (2FA) is not yet activated for your account. "
+"Enabling this feature will increase your account's security."
+msgstr ""
+
+#: core/templates/core/user_security.html:73
+msgid "Enable 2FA"
+msgstr ""
+
+#: core/templates/core/user_security.html:83
+#: core/templates/core/user_security.html:99
+#: templates/common/generic_modal.html:6 templates/common/generic_modal.html:13
+#: templates/common/wizard_forms.html:6 templates/common/wizard_forms.html:27
+msgid "Close"
+msgstr ""
+
+#: core/templates/core/user_security.html:84
+msgid "New recovery codes"
+msgstr ""
+
+#: core/templates/core/user_security.html:88
+msgid "Here are your new recovery codes. "
+msgstr ""
+
#: core/templatetags/core_tags.py:34
msgid "Modoboa"
msgstr ""
@@ -928,7 +1013,7 @@ msgstr ""
msgid "Logout"
msgstr ""
-#: core/templatetags/core_tags.py:127
+#: core/templatetags/core_tags.py:131
msgid "API"
msgstr ""
@@ -940,51 +1025,55 @@ msgstr ""
msgid "Parameters saved"
msgstr ""
-#: core/views/auth.py:59
+#: core/views/auth.py:61
#, python-format
msgid "Password scheme mismatch. Updating %s password"
msgstr ""
-#: core/views/auth.py:66
+#: core/views/auth.py:68
#, python-format
msgid "Password hash parameter missmatch. Updating %s password"
msgstr ""
-#: core/views/auth.py:82
+#: core/views/auth.py:84
#, python-format
msgid "User '%s' successfully logged in"
msgstr ""
-#: core/views/auth.py:90
+#: core/views/auth.py:92
msgid "Your username and password didn't match. Please try again."
msgstr ""
-#: core/views/auth.py:125
+#: core/views/auth.py:127
msgid "User '{}' successfully logged out"
msgstr ""
-#: core/views/auth.py:170 core/views/auth.py:225
+#: core/views/auth.py:172 core/views/auth.py:227
msgid "Please use the following code to recover your Modoboa password: {}"
msgstr ""
-#: core/views/user.py:53
+#: core/views/user.py:60
msgid "Profile updated"
msgstr ""
-#: core/views/user.py:81
+#: core/views/user.py:88
msgid "Preferences saved"
msgstr ""
-#: core/views/user.py:103
+#: core/views/user.py:110
msgid "Access updated"
msgstr ""
+#: core/viewsets.py:52
+msgid "2FA is not enabled"
+msgstr ""
+
#: lib/db_utils.py:23
#, python-format
msgid "Connection to database %s not configured"
msgstr ""
-#: lib/email_utils.py:141 lib/email_utils.py:360
+#: lib/email_utils.py:143 lib/email_utils.py:362
msgid "unable to determine encoding of string"
msgstr ""
@@ -1068,11 +1157,6 @@ msgstr ""
msgid "Help:"
msgstr ""
-#: templates/common/generic_modal.html:6 templates/common/generic_modal.html:13
-#: templates/common/wizard_forms.html:6 templates/common/wizard_forms.html:27
-msgid "Close"
-msgstr ""
-
#: templates/common/wizard_forms.html:31
msgid "Previous"
msgstr ""
diff --git a/modoboa/locale/en/LC_MESSAGES/djangojs.po b/modoboa/locale/en/LC_MESSAGES/djangojs.po
index d4f7a4f01..263146b0a 100644
--- a/modoboa/locale/en/LC_MESSAGES/djangojs.po
+++ b/modoboa/locale/en/LC_MESSAGES/djangojs.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-03-09 16:48+0100\n"
+"POT-Creation-Date: 2020-11-05 15:47+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -37,7 +37,7 @@ msgstr ""
msgid "Cancel"
msgstr ""
-#: static/js/global.js:342
+#: static/js/global.js:347
msgid "Internal error"
msgstr ""
@@ -52,3 +52,11 @@ msgstr ""
#: static/js/searchbar.js:28
msgid "Search..."
msgstr ""
+
+#: static/js/twocols_nav.js:170
+msgid "Are you sure?"
+msgstr ""
+
+#: static/js/twocols_nav.js:171
+msgid "This will invalidate your registered application."
+msgstr ""
diff --git a/modoboa/locale/fr/LC_MESSAGES/django.po b/modoboa/locale/fr/LC_MESSAGES/django.po
index b361b4306..745856a20 100644
--- a/modoboa/locale/fr/LC_MESSAGES/django.po
+++ b/modoboa/locale/fr/LC_MESSAGES/django.po
@@ -1,7 +1,7 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
-#
+#
# Translators:
# Antoine Nguyen , 2016-2017,2020
# Christophe CHAUVET , 2018
@@ -10,14 +10,14 @@ msgid ""
msgstr ""
"Project-Id-Version: Modoboa\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-05-06 13:15+0200\n"
-"PO-Revision-Date: 2020-05-06 11:19+0000\n"
+"POT-Creation-Date: 2020-11-05 15:36+0100\n"
+"PO-Revision-Date: 2020-11-05 15:49+0100\n"
"Last-Translator: Antoine Nguyen \n"
"Language-Team: French (http://www.transifex.com/tonio/modoboa/language/fr/)\n"
+"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Language: fr\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: core/app_settings.py:26
@@ -46,7 +46,8 @@ msgstr "Méthode de chiffrement par défaut"
#: core/app_settings.py:56
msgid "Scheme used to crypt mailbox passwords"
-msgstr "Méthode utilisée pour chiffrer les mots de passe des boites aux lettres"
+msgstr ""
+"Méthode utilisée pour chiffrer les mots de passe des boites aux lettres"
#: core/app_settings.py:60
msgid "Rounds"
@@ -56,7 +57,9 @@ msgstr "Tours"
msgid ""
"Number of rounds to use (only used by sha256crypt and sha512crypt). Must be "
"between 1000 and 999999999, inclusive."
-msgstr "Nombre de tours à utiliser (sha256crypt et sha512crypt uniquement). Doit être compris entre 1000 et 999999999 inclue."
+msgstr ""
+"Nombre de tours à utiliser (sha256crypt et sha512crypt uniquement). Doit "
+"être compris entre 1000 et 999999999 inclue."
#: core/app_settings.py:69
msgid "Update password scheme at login"
@@ -64,7 +67,9 @@ msgstr "Mettre à jour la méthode de chiffrement du mot de passe à la connexio
#: core/app_settings.py:72
msgid "Update user password at login to use the default password scheme"
-msgstr "Mise à jour du mot de passe utilisateur lors d'une connexion pour utiliser la méthode de chiffrement par défaut"
+msgstr ""
+"Mise à jour du mot de passe utilisateur lors d'une connexion pour utiliser "
+"la méthode de chiffrement par défaut"
#: core/app_settings.py:77
msgid "Default password"
@@ -91,7 +96,10 @@ msgid ""
"The URL of an external page where users will be able to update their "
"password. It applies only to non local users, ie. those automatically "
"created after a successful external authentication (LDAP, SMTP)."
-msgstr "L'URL d'une page externe où les utilisateurs pourront mettre à jour leur mot de passe. Elle s'applique uniquement aux utilisateurs non locaux, c'est à dire ceux créés après une authentification externe réussie (LDAP, SMTP)."
+msgstr ""
+"L'URL d'une page externe où les utilisateurs pourront mettre à jour leur mot "
+"de passe. Elle s'applique uniquement aux utilisateurs non locaux, c'est à "
+"dire ceux créés après une authentification externe réussie (LDAP, SMTP)."
#: core/app_settings.py:104
msgid "Password recovery announcement"
@@ -99,7 +107,9 @@ msgstr "Annonce pour la récupération de mot de passe"
#: core/app_settings.py:109
msgid "A temporary message that will be displayed on the reset password page."
-msgstr "Un message temporaire qui sera affiché sur la page de récupération de mot de passe"
+msgstr ""
+"Un message temporaire qui sera affiché sur la page de récupération de mot de "
+"passe"
#: core/app_settings.py:115
msgid "Enable password recovery by SMS"
@@ -107,7 +117,9 @@ msgstr "Activer la récupération de mot de passe par SMS"
#: core/app_settings.py:118
msgid "Enable password recovery by SMS for users who filled a phone number."
-msgstr "Activer la récupération de mot de passe par SMS pour les utilisateurs ayant renseigné un numéro de téléphone"
+msgstr ""
+"Activer la récupération de mot de passe par SMS pour les utilisateurs ayant "
+"renseigné un numéro de téléphone"
#: core/app_settings.py:124
msgid "SMS provider"
@@ -115,7 +127,8 @@ msgstr "Fournisseur SMS"
#: core/app_settings.py:127
msgid "Choose a provider to send password recovery SMS"
-msgstr "Choisir un fournisseur pour envoyer les SMS de récupération de mot de passe"
+msgstr ""
+"Choisir un fournisseur pour envoyer les SMS de récupération de mot de passe"
#: core/app_settings.py:133
msgid "LDAP settings"
@@ -144,7 +157,9 @@ msgstr "Activer le serveur secondaire (secours)"
#: core/app_settings.py:152
msgid ""
"Enable a secondary LDAP server which will be used if the primary one fails"
-msgstr "Activer un serveur LDAP secondaire qui sera utilisé si le principal est en échec"
+msgstr ""
+"Activer un serveur LDAP secondaire qui sera utilisé si le principal est en "
+"échec"
#: core/app_settings.py:158
msgid "Secondary server address"
@@ -184,9 +199,12 @@ msgstr "Groupes administrateurs"
#: core/app_settings.py:190
msgid ""
-"Members of those LDAP Posix groups will be created as domain administrators."
-" Use ';' characters to separate groups."
-msgstr "Les membres de ces groupes LDAP (Posix) seront créés en tant qu'administrateurs de domaine. Utiliser des caractères ';' pour séparer les groupes."
+"Members of those LDAP Posix groups will be created as domain administrators. "
+"Use ';' characters to separate groups."
+msgstr ""
+"Les membres de ces groupes LDAP (Posix) seront créés en tant "
+"qu'administrateurs de domaine. Utiliser des caractères ';' pour séparer les "
+"groupes."
#: core/app_settings.py:197
msgid "Group type"
@@ -202,7 +220,9 @@ msgstr "Base de recherche des groupes"
#: core/app_settings.py:209
msgid "The distinguished name of the search base used to find groups"
-msgstr "Le nom distinctif de la base de recherche utilisée pour rechercher les groupes"
+msgstr ""
+"Le nom distinctif de la base de recherche utilisée pour rechercher les "
+"groupes"
#: core/app_settings.py:215
msgid "Password attribute"
@@ -240,7 +260,9 @@ msgstr "ND de connexion"
msgid ""
"The distinguished name to use when binding to the LDAP server. Leave empty "
"for an anonymous bind"
-msgstr "Le nom distinctif à utiliser pour les connections au serveur LDAP. Laisser vide pour une connexion anonyme"
+msgstr ""
+"Le nom distinctif à utiliser pour les connections au serveur LDAP. Laisser "
+"vide pour une connexion anonyme"
#: core/app_settings.py:243 core/app_settings.py:297
msgid "Bind password"
@@ -248,7 +270,9 @@ msgstr "Mot de passe de connexion"
#: core/app_settings.py:246 core/app_settings.py:300
msgid "The password to use when binding to the LDAP server (with 'Bind DN')"
-msgstr "Le mot de passe à utiliser pour les connections au serveur LDAP (avec 'ND de connexion')"
+msgstr ""
+"Le mot de passe à utiliser pour les connections au serveur LDAP (avec 'ND de "
+"connexion')"
#: core/app_settings.py:254 core/app_settings.py:346
msgid "Users search base"
@@ -256,7 +280,9 @@ msgstr "Base de recherche des utilisateurs"
#: core/app_settings.py:257 core/app_settings.py:349
msgid "The distinguished name of the search base used to find users"
-msgstr "Le nom distinctif de la base de recherche utilisée pour rechercher les utilisateurs"
+msgstr ""
+"Le nom distinctif de la base de recherche utilisée pour rechercher les "
+"utilisateurs"
#: core/app_settings.py:263 core/app_settings.py:355
msgid "Search filter"
@@ -266,7 +292,9 @@ msgstr "Filtre de recherche"
msgid ""
"An optional filter string (e.g. '(objectClass=person)'). In order to be "
"valid, it must be enclosed in parentheses."
-msgstr "Un filtre de recherche optionel (ex. '(objectClass=person)'). Pour être valide, il doit être entouré de parenthèses."
+msgstr ""
+"Un filtre de recherche optionel (ex. '(objectClass=person)'). Pour être "
+"valide, il doit être entouré de parenthèses."
#: core/app_settings.py:273
msgid "User DN template"
@@ -277,7 +305,9 @@ msgstr "Modèle de nom distinctif utilisateur"
msgid ""
"The template used to construct a user's DN. It should contain one "
"placeholder (ie. %(user)s)"
-msgstr "Le modèle utilisé pour construire le nom distinctif d'un utilisateur. Il doit contenir un espace réservé (ex. %(user)s)"
+msgstr ""
+"Le modèle utilisé pour construire le nom distinctif d'un utilisateur. Il "
+"doit contenir un espace réservé (ex. %(user)s)"
#: core/app_settings.py:284
msgid "LDAP synchronization settings"
@@ -290,7 +320,9 @@ msgstr "Activer l'export LDAP"
#: core/app_settings.py:311
msgid ""
"Enable automatic synchronization between local database and LDAP directory"
-msgstr "Activer la synchronisation automatique entre la base de données locale et l'annuaire LDAP"
+msgstr ""
+"Activer la synchronisation automatique entre la base de données locale et "
+"l'annuaire LDAP"
#: core/app_settings.py:317
msgid "Delete remote LDAP account when local account is deleted"
@@ -300,7 +332,9 @@ msgstr "Supprimer un compte LDAP distant lorsqu'un compte local est supprimé"
msgid ""
"Delete remote LDAP account when local account is deleted, otherwise it will "
"be disabled."
-msgstr "Supprimer un compte LDAP distant lorsqu'un compte local supprimé, autrement il sera désactivé."
+msgstr ""
+"Supprimer un compte LDAP distant lorsqu'un compte local supprimé, autrement "
+"il sera désactivé."
#: core/app_settings.py:327
msgid "Account DN template"
@@ -311,7 +345,9 @@ msgstr "Modèle des DN de compte"
msgid ""
"The template used to construct an account's DN. It should contain one "
"placeholder (ie. %(user)s)"
-msgstr "Le modèle utilisé pour construite un DN de compte (nom unique). Il doit contenir un emplacement (c'est à dire 1%(user)s)"
+msgstr ""
+"Le modèle utilisé pour construite un DN de compte (nom unique). Il doit "
+"contenir un emplacement (c'est à dire 1%(user)s)"
#: core/app_settings.py:337
msgid "Enable import from LDAP"
@@ -319,7 +355,9 @@ msgstr "Activer l'import LDAP"
#: core/app_settings.py:340
msgid "Enable account synchronization from LDAP directory to local database"
-msgstr "Activer la synchronisation des comptes entre un annuaire LDAP et la base de données locale"
+msgstr ""
+"Activer la synchronisation des comptes entre un annuaire LDAP et la base de "
+"données locale"
#: core/app_settings.py:365
msgid "Username attribute"
@@ -327,7 +365,8 @@ msgstr "Attribut nom d'utilisateur"
#: core/app_settings.py:368
msgid "The name of the LDAP attribute where the username can be found."
-msgstr "Le nom de l'attribut LDAP dans lequel le nom d'utilisateur peut être trouvé."
+msgstr ""
+"Le nom de l'attribut LDAP dans lequel le nom d'utilisateur peut être trouvé."
#: core/app_settings.py:373
msgid "Enable Dovecot LDAP sync"
@@ -335,7 +374,9 @@ msgstr "Activer la synchronisation LDAP pour Dovecot"
#: core/app_settings.py:376
msgid "LDAP authentication settings will be applied to Dovecot configuration."
-msgstr "Les paramètres d'authentification LDAP seront appliqués à la configuration de Dovecot."
+msgstr ""
+"Les paramètres d'authentification LDAP seront appliqués à la configuration "
+"de Dovecot."
#: core/app_settings.py:382
msgid "Dovecot LDAP config file"
@@ -344,7 +385,9 @@ msgstr "Fichier de configuration Dovecot pour LDAP"
#: core/app_settings.py:386
msgid ""
"Location of the configuration file which contains Dovecot LDAP settings."
-msgstr "Emplacement du fichier de configuration qui contient les paramètres LDAP de Dovecot"
+msgstr ""
+"Emplacement du fichier de configuration qui contient les paramètres LDAP de "
+"Dovecot"
#: core/app_settings.py:391 core/templates/core/dashboard.html:5
msgid "Dashboard"
@@ -356,7 +399,9 @@ msgstr "Flux RSS personnalisé"
#: core/app_settings.py:397
msgid "Display custom RSS feed to resellers and domain administrators"
-msgstr "Afficher un flux RSS personnalisé aux revendeurs et administrateurs de domaine"
+msgstr ""
+"Afficher un flux RSS personnalisé aux revendeurs et administrateurs de "
+"domaine"
#: core/app_settings.py:402
msgid "Hide features widget"
@@ -364,7 +409,9 @@ msgstr "Masquer le widget des fonctionnalités"
#: core/app_settings.py:405
msgid "Hide features widget for resellers and domain administrators"
-msgstr "Masquer le widget des fonctionnalités pour les revendeurs et les administrateurs de domaine"
+msgstr ""
+"Masquer le widget des fonctionnalités pour les revendeurs et les "
+"administrateurs de domaine"
#: core/app_settings.py:409
msgid "Notifications"
@@ -404,7 +451,9 @@ msgstr "Envoyer un email quand de nouvelles versions sont trouvées"
#: core/app_settings.py:439
msgid "Send an email to notify admins about new versions"
-msgstr "Envoyer un email pour notifier les administrateurs à propos des nouvelles versions"
+msgstr ""
+"Envoyer un email pour notifier les administrateurs à propos des nouvelles "
+"versions"
#: core/app_settings.py:443
msgid "Recipient"
@@ -420,7 +469,9 @@ msgstr "Envoyer des statistiques"
#: core/app_settings.py:454
msgid "Send statistics to Modoboa public API (counters and used extensions)"
-msgstr "Envoyer des statistiques à l'API publique de Modoboa (compteurs et extensions utilisées)"
+msgstr ""
+"Envoyer des statistiques à l'API publique de Modoboa (compteurs et "
+"extensions utilisées)"
#: core/app_settings.py:458
msgid "Miscellaneous"
@@ -432,9 +483,11 @@ msgstr "Seuil des comptes inactifs"
#: core/app_settings.py:464
msgid ""
-"An account with a last login date greater than this threshold (in days) will"
-" be considered as inactive"
-msgstr "Un compte avec une date de dernière connexion antérieure à ce seuil sera considéré comme inactif"
+"An account with a last login date greater than this threshold (in days) will "
+"be considered as inactive"
+msgstr ""
+"Un compte avec une date de dernière connexion antérieure à ce seuil sera "
+"considéré comme inactif"
#: core/app_settings.py:470
msgid "Top notifications check interval"
@@ -466,7 +519,8 @@ msgstr "Redirection par défaut"
#: core/app_settings.py:494
msgid "The default redirection used when no application is specified"
-msgstr "La redirection appliquée par défaut quand aucune application n'est spécifiée"
+msgstr ""
+"La redirection appliquée par défaut quand aucune application n'est spécifiée"
#: core/app_settings.py:548 core/app_settings.py:556 core/app_settings.py:564
msgid "Invalid syntax"
@@ -489,7 +543,10 @@ msgid ""
"You have USE_TZ set to False, this may result in issues during transitions "
"between summer/winter time (ie the same local time occuring twice due to "
"clock change)."
-msgstr "Vous avez défini USE_TZ à False, ce qui peut entraîner des problèmes lors des transitions entre l'heure d'été et l'heure d'hiver (c.-à-d. La même heure locale se produisant deux fois en raison d'un changement d'horloge)."
+msgstr ""
+"Vous avez défini USE_TZ à False, ce qui peut entraîner des problèmes lors "
+"des transitions entre l'heure d'été et l'heure d'hiver (c.-à-d. La même "
+"heure locale se produisant deux fois en raison d'un changement d'horloge)."
#: core/checks/settings_checks.py:9
msgid "Set `USE_TZ = True` in settings.py"
@@ -523,46 +580,50 @@ msgstr "Choisir un fournisseur"
msgid "Dummy"
msgstr "Test"
-#: core/forms.py:21
+#: core/forms.py:23
msgid "Username"
msgstr "Nom d'utilisateur"
-#: core/forms.py:25
+#: core/forms.py:27
msgid "Password"
msgstr "Mot de passe"
-#: core/forms.py:38
+#: core/forms.py:40
msgid "Old password"
msgstr "Ancien mot de passe"
-#: core/forms.py:42
+#: core/forms.py:44
msgid "New password"
msgstr "Nouveau mot de passe"
-#: core/forms.py:46
+#: core/forms.py:48
msgid "Confirmation"
msgstr "Confirmation"
-#: core/forms.py:74
+#: core/forms.py:76
msgid "Old password mismatchs"
msgstr "L'ancien mot de passe est incorrect"
-#: core/forms.py:83
+#: core/forms.py:85
msgid "Passwords mismatch"
msgstr "Les mots de passe diffèrent"
-#: core/forms.py:103
+#: core/forms.py:105
msgid "Enable API access"
msgstr "Activer l'accès API"
-#: core/forms.py:137
+#: core/forms.py:139
msgid "Verification code"
msgstr "Code de vérification"
-#: core/forms.py:148
+#: core/forms.py:150
msgid "Invalid code"
msgstr "Code incorrect"
+#: core/forms.py:163
+msgid "This code is invalid"
+msgstr "Ce code est incorrect"
+
#: core/handlers.py:36
msgid "added"
msgstr "ajouté"
@@ -605,41 +666,42 @@ msgstr "Une ou plusieurs mises à jour sont disponibles!"
msgid "[modoboa] Update(s) available"
msgstr "[modoboa] Mise(s) à jour disponible(s)"
-#: core/models.py:55
+#: core/models.py:52
msgid "Allow mailboxes access"
msgstr "Autoriser l'accès aux boites"
-#: core/models.py:57
+#: core/models.py:54
msgid "Allow this administrator to access user mailboxes"
msgstr "Autoriser cet administrateur à accéder aux boites des utilisateurs"
-#: core/models.py:60
+#: core/models.py:57
msgid "password"
msgstr "mot de passe"
-#: core/models.py:63
+#: core/models.py:60
msgid "language"
msgstr "langue"
-#: core/models.py:66
+#: core/models.py:63
msgid "Prefered language to display pages."
msgstr "Langage préféré pour afficher les pages"
-#: core/models.py:70
+#: core/models.py:67
msgid "Phone number"
msgstr "Numéro de téléphone"
-#: core/models.py:72
+#: core/models.py:69
msgid "Secondary email"
msgstr "Email secondaire"
-#: core/models.py:75
+#: core/models.py:72
msgid "An alternative e-mail address, can be used for recovery needs."
msgstr "Une adresse e-mail alternative ou de secours."
#: core/models.py:126
msgid "Failed to update password: LDAP module not installed"
-msgstr "Echec de la mise à jour du mot de passe : le module LDAP n'est pas installé"
+msgstr ""
+"Echec de la mise à jour du mot de passe : le module LDAP n'est pas installé"
#: core/models.py:155
msgid "account"
@@ -693,7 +755,17 @@ msgstr[1] "Le mot de passe doit contenir au moins {} caractères spéciaux."
#: core/password_validation.py:65
msgid "Your password must contain a combination of different character types."
-msgstr "Votre mot de passe doit contenir une combinaison de différents types de caractère."
+msgstr ""
+"Votre mot de passe doit contenir une combinaison de différents types de "
+"caractère."
+
+#: core/serializers.py:15
+msgid "Invalid PIN code"
+msgstr "Code PIN incorrect"
+
+#: core/serializers.py:21
+msgid "2FA is already enabled"
+msgstr "La 2FA est déjà activée"
#: core/sms_backends/ovh.py:19
msgid "API endpoint"
@@ -763,7 +835,9 @@ msgstr "Dernières nouvelles"
msgid ""
"Visit the official "
"weblog for more information."
-msgstr "Visitez le blog officiel pour plus d'information."
+msgstr ""
+"Visitez le blog "
+"officiel pour plus d'information."
#: core/templates/core/api_access.html:3
msgid "API access"
@@ -776,9 +850,11 @@ msgstr "Contrôlez votre accès à l'API de Modoboa"
#: core/templates/core/api_access.html:7
#, python-format
msgid ""
-"A documentation of the API is available here."
-msgstr "Une documentation de l'API est disponible ici."
+"A documentation of the API is available here."
+msgstr ""
+"Une documentation de l'API est disponible ici."
#: core/templates/core/api_access.html:14
msgid "API access token"
@@ -808,7 +884,8 @@ msgstr "Une ou plusieurs mises à jour sont disponibles!"
#: core/templates/core/information.html:6
msgid "Check the following list to find the component(s) that can be updated."
-msgstr "Consulter la liste suivante pour trouver le(s) composant(s) concerné(s)."
+msgstr ""
+"Consulter la liste suivante pour trouver le(s) composant(s) concerné(s)."
#: core/templates/core/information.html:10
msgid "Applications"
@@ -874,8 +951,12 @@ msgid ""
msgid_plural ""
"\n"
" The following updates are available:\n"
-msgstr[0] "\nLa mise à jour suivante est disponible :\n"
-msgstr[1] "\nLes mises à jour suivantes sont disponibles :\n"
+msgstr[0] ""
+"\n"
+"La mise à jour suivante est disponible :\n"
+msgstr[1] ""
+"\n"
+"Les mises à jour suivantes sont disponibles :\n"
#: core/templates/core/parameters.html:2 core/templatetags/core_tags.py:71
msgid "Parameters"
@@ -923,6 +1004,79 @@ msgstr "Mettez à jour vos informations personnelles"
msgid "Click here to update your password"
msgstr "Cliquez ici pour mettre à jour votre mot de passe"
+#: core/templates/core/user_security.html:2 core/templatetags/core_tags.py:124
+msgid "Security"
+msgstr "Sécurité"
+
+#: core/templates/core/user_security.html:6
+msgid "Two-Factor authentication"
+msgstr "Authentification à double facteur"
+
+#: core/templates/core/user_security.html:17
+msgid ""
+"Install a soft token authenticator like FreeOTP or Google Authenticator from "
+"your application repository and use that app to scan this QR code."
+msgstr "Installer une application de génération de mots de passe à usage unique comme FreeOTP ou Google Athenticator depuis votre magasin d'applications et utiliser le pour scanner ce code QR."
+
+#: core/templates/core/user_security.html:25
+msgid "Pin code"
+msgstr "Code PIN"
+
+#: core/templates/core/user_security.html:28
+msgid "Register"
+msgstr "Enregistrer"
+
+#: core/templates/core/user_security.html:33
+msgid ""
+"Congratulations! Two-Factor Authentication is now enabled for your account."
+msgstr "Félicitations ! L'authentification à double facteur est activée pour votre compte."
+
+#: core/templates/core/user_security.html:38
+#: core/templates/core/user_security.html:89
+msgid ""
+"The following recovery codes can be used one time each to let you regain "
+"access to your account, in case you lose your phone for example. Make sure "
+"to save them in a safe place, otherwise you won't be able to access your "
+"account anymore."
+msgstr "Les codes de récuparation suivants peuvent être utilisés une fois chacun pour récupérer l'accès à votre compte, par exemple si vous perdez votre téléphone. Assurez vous de les sauvegarder dans un endroit sûr, autrement vous ne pourrez plus accéder à votre compte."
+
+#: core/templates/core/user_security.html:53
+msgid "Two-Factor Authentication is enabled for your account."
+msgstr "L'authentication à double facteur est activée pour votre compte."
+
+#: core/templates/core/user_security.html:58
+msgid "Disable 2FA"
+msgstr "Désactiver la 2FA"
+
+#: core/templates/core/user_security.html:61
+msgid "Reset recovery codes"
+msgstr "Réinitialiser les codes de récupération"
+
+#: core/templates/core/user_security.html:65
+msgid ""
+"Two-Factor Authentication (2FA) is not yet activated for your account. "
+"Enabling this feature will increase your account's security."
+msgstr "L'authentification à double facteur (2FA) n'est pas encore activée pour votre compte. Activer cette fonctionnalité améliorera la sécurité de votre compte."
+
+#: core/templates/core/user_security.html:73
+msgid "Enable 2FA"
+msgstr "Activer la 2FA"
+
+#: core/templates/core/user_security.html:83
+#: core/templates/core/user_security.html:99
+#: templates/common/generic_modal.html:6 templates/common/generic_modal.html:13
+#: templates/common/wizard_forms.html:6 templates/common/wizard_forms.html:27
+msgid "Close"
+msgstr "Fermer"
+
+#: core/templates/core/user_security.html:84
+msgid "New recovery codes"
+msgstr "Nouveaux codes de récupération"
+
+#: core/templates/core/user_security.html:88
+msgid "Here are your new recovery codes. "
+msgstr "Voici vos nouveaux codes de récupération."
+
#: core/templatetags/core_tags.py:34
msgid "Modoboa"
msgstr "Modoboa"
@@ -931,7 +1085,7 @@ msgstr "Modoboa"
msgid "Logout"
msgstr "Déconnexion"
-#: core/templatetags/core_tags.py:127
+#: core/templatetags/core_tags.py:131
msgid "API"
msgstr "API"
@@ -943,51 +1097,61 @@ msgstr "Le coeur de Modoboa"
msgid "Parameters saved"
msgstr "Paramètres enregistrés"
-#: core/views/auth.py:59
+#: core/views/auth.py:61
#, python-format
msgid "Password scheme mismatch. Updating %s password"
-msgstr "La méthode de chiffrement du mot de passe diffère. Mise à jour du mot de passe de %s"
+msgstr ""
+"La méthode de chiffrement du mot de passe diffère. Mise à jour du mot de "
+"passe de %s"
-#: core/views/auth.py:66
+#: core/views/auth.py:68
#, python-format
msgid "Password hash parameter missmatch. Updating %s password"
msgstr ""
-#: core/views/auth.py:82
+#: core/views/auth.py:84
#, python-format
msgid "User '%s' successfully logged in"
msgstr "Utiliseur '%s' connecté avec succès"
-#: core/views/auth.py:90
+#: core/views/auth.py:92
msgid "Your username and password didn't match. Please try again."
-msgstr "Votre nom d'utilisateur et mot de passe ne correspondent pas. Veuillez réessayer."
+msgstr ""
+"Votre nom d'utilisateur et mot de passe ne correspondent pas. Veuillez "
+"réessayer."
-#: core/views/auth.py:125
+#: core/views/auth.py:127
msgid "User '{}' successfully logged out"
msgstr "Utilisateur '{}' déconnecté avec succès"
-#: core/views/auth.py:170 core/views/auth.py:225
+#: core/views/auth.py:172 core/views/auth.py:227
msgid "Please use the following code to recover your Modoboa password: {}"
-msgstr "Veuillez utiliser le code suivant pour récupérer votre mot de passe Modoboa : {}"
+msgstr ""
+"Veuillez utiliser le code suivant pour récupérer votre mot de passe "
+"Modoboa : {}"
-#: core/views/user.py:53
+#: core/views/user.py:60
msgid "Profile updated"
msgstr "Profil mis à jour"
-#: core/views/user.py:81
+#: core/views/user.py:88
msgid "Preferences saved"
msgstr "Préférences enregistrées"
-#: core/views/user.py:103
+#: core/views/user.py:110
msgid "Access updated"
msgstr "Accès mis à jour"
+#: core/viewsets.py:52
+msgid "2FA is not enabled"
+msgstr "La 2FA n'est pas activée"
+
#: lib/db_utils.py:23
#, python-format
msgid "Connection to database %s not configured"
msgstr "Connexion à la base de données %s non configurée"
-#: lib/email_utils.py:141 lib/email_utils.py:360
+#: lib/email_utils.py:143 lib/email_utils.py:362
msgid "unable to determine encoding of string"
msgstr "Impossible de déterminer l'encodage de la chaîne de caractères"
@@ -1071,12 +1235,6 @@ msgstr "Erreur :"
msgid "Help:"
msgstr "Aide :"
-#: templates/common/generic_modal.html:6
-#: templates/common/generic_modal.html:13 templates/common/wizard_forms.html:6
-#: templates/common/wizard_forms.html:27
-msgid "Close"
-msgstr "Fermer"
-
#: templates/common/wizard_forms.html:31
msgid "Previous"
msgstr "Précédent"
@@ -1107,7 +1265,9 @@ msgstr "Mot de passe oublié ?"
msgid ""
"Your password has been set. You may go ahead and sign "
"in now."
-msgstr "Votre mot de passe a été défini. Vous pouvez continuer et vous connecter dès maintenant."
+msgstr ""
+"Votre mot de passe a été défini. Vous pouvez continuer et vous connecter dès maintenant."
#: templates/registration/password_reset_confirm.html:7
msgid "Change password"
@@ -1117,7 +1277,10 @@ msgstr "Changer le mot de passe"
msgid ""
"The password reset link was invalid, possibly because it has already been "
"used. Please request a new password reset."
-msgstr "Le lien de réinitialisation du mot de passe était invalide, probablement parce qu'il a déjà été utilisé. Merci de demander une nouvelle réinitialisation de mot de passe."
+msgstr ""
+"Le lien de réinitialisation du mot de passe était invalide, probablement "
+"parce qu'il a déjà été utilisé. Merci de demander une nouvelle "
+"réinitialisation de mot de passe."
#: templates/registration/password_reset_confirm_code.html:20
msgid "Enter the code you've just received by SMS"
@@ -1133,20 +1296,29 @@ msgid ""
"exists with the email you entered. You should receive them shortly. "
"
If you don't receive an email, please make sure you've entered your "
"primary address, and check your spam folder.
"
-msgstr "
Nous vous avons envoyé par email les instructions pour définir votre mot de passe, pour peu qu'un compte avec l'email que vous avez renseigné existe. Vous devriez les recevoir rapidement.
Si vous ne recevez pas d'email, merci de vérifier que vous avez renseigné votre adresse principale et de vérifier votre dossier spam.
"
+msgstr ""
+"
Nous vous avons envoyé par email les instructions pour définir votre mot "
+"de passe, pour peu qu'un compte avec l'email que vous avez renseigné existe. "
+"Vous devriez les recevoir rapidement.
Si vous ne recevez pas d'email, "
+"merci de vérifier que vous avez renseigné votre adresse principale et de "
+"vérifier votre dossier spam.
"
#: templates/registration/password_reset_email.html:4
#, python-format
msgid ""
"To initiate the password reset process for your %(username)s Modoboa "
"account, click the link below:"
-msgstr "Pour initier la procédure de réinitialisation du mot de passe de votre compte Modoboa %(username)s, cliquez sur le lien ci-dessous :"
+msgstr ""
+"Pour initier la procédure de réinitialisation du mot de passe de votre "
+"compte Modoboa %(username)s, cliquez sur le lien ci-dessous :"
#: templates/registration/password_reset_email.html:10
msgid ""
"If clicking the link above doesn't work, please copy and paste the URL in a "
"new browser window instead."
-msgstr "Si cliquer sur lien ci-dessous ne fonctionne pas, merci de copier / coller cette URL dans une nouvelle fenêtre navigateur à la place."
+msgstr ""
+"Si cliquer sur lien ci-dessous ne fonctionne pas, merci de copier / coller "
+"cette URL dans une nouvelle fenêtre navigateur à la place."
#: templates/registration/password_reset_email.html:14
msgid "Sincerely, The Modoboa Team."
diff --git a/modoboa/locale/fr/LC_MESSAGES/djangojs.po b/modoboa/locale/fr/LC_MESSAGES/djangojs.po
index 2574ef4e2..76b21d816 100644
--- a/modoboa/locale/fr/LC_MESSAGES/djangojs.po
+++ b/modoboa/locale/fr/LC_MESSAGES/djangojs.po
@@ -2,23 +2,22 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR , YEAR.
-#
+#
# Translators:
# Antoine Nguyen , 2020
-#
-#, fuzzy
+#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-03-09 16:48+0100\n"
-"PO-Revision-Date: 2020-05-11 18:45+0000\n"
+"POT-Creation-Date: 2020-11-05 15:47+0100\n"
+"PO-Revision-Date: 2020-11-05 15:48+0100\n"
"Last-Translator: Antoine Nguyen , 2020\n"
"Language-Team: French (https://www.transifex.com/tonio/teams/13749/fr/)\n"
+"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Language: fr\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: bower_components/jquery-ui/jquery-ui.min.js:8
@@ -41,7 +40,7 @@ msgstr "Avertissement"
msgid "Cancel"
msgstr "Annuler"
-#: static/js/global.js:342
+#: static/js/global.js:347
msgid "Internal error"
msgstr "Erreur interne"
@@ -56,3 +55,11 @@ msgstr "Chercher"
#: static/js/searchbar.js:28
msgid "Search..."
msgstr "Chercher..."
+
+#: static/js/twocols_nav.js:170
+msgid "Are you sure?"
+msgstr "Etes vous certain ?"
+
+#: static/js/twocols_nav.js:171
+msgid "This will invalidate your registered application."
+msgstr "Cela annulera votre application enregistrée."
From b6b07f2d15b14f21e71ec2c26f083b184a8dc040 Mon Sep 17 00:00:00 2001
From: Antoine Nguyen
Date: Thu, 5 Nov 2020 15:57:54 +0100
Subject: [PATCH 30/44] Removed old reference to stats plugin in doc.
---
doc/index.rst | 5 -----
1 file changed, 5 deletions(-)
diff --git a/doc/index.rst b/doc/index.rst
index 4ae989fcc..1a3a01322 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -53,10 +53,6 @@ It is extensible by nature and comes with a lot of additional extensions:
|`modoboa-sievefilters |A Sieve filters (rules) |https://modoboa-sievefilters.readthedocs.io |
|`_ |editor | |
+---------------------------------------------------------+-------------------------+------------------------------------------------------+
-|`modoboa-stats |Graphical statistics |https://modoboa-stats.readthedocs.io |
-|`_ |(message traffic and | |
-| |more) | |
-+---------------------------------------------------------+-------------------------+------------------------------------------------------+
|`modoboa-webmail |A simple webmail |https://modoboa-webmail.readthedocs.io |
|`_ | | |
+---------------------------------------------------------+-------------------------+------------------------------------------------------+
@@ -74,4 +70,3 @@ Table of contents
rest_api
contributing
contributors
-
From 02efd7f0e3ca8bd4abd135ce2ae1b8eb37352d80 Mon Sep 17 00:00:00 2001
From: Christophe CHAUVET
Date: Mon, 9 Nov 2020 20:44:48 +0100
Subject: [PATCH 31/44] POC replace travis by Github Actions (#2066)
* POC replace travis by Github Actions
* add libldap2-dev
* add libsasl2-dev libssl-dev
* Delete .travis.yml
* Add specific configuration for PostgreSQL
* Retrieve PostgreSQL or MySQL port from env var
* Print affected port for the docker service
* Add Database type and dburl
* Fix dbtype
* Use environment variable to define the port in use for tests.
* Configured password for postgres connection.
* Added redis service.
* Enabled OpenLDAP service.
* Use a container for OpenLDAP too.
* Removed wrong option.
* Fixed volume syntax.
* Try using the option directly.
* Try using an absolute path.
* Fixed wrong syntax.
* Try different format for env variable.
* Try a different way to load data.
* Added missing method call.
* Fix envar
* Try to wait a bit before starting tests.
* Display openldap service logs.
* Fixed ldif scripts path.
* Try to use a custom docker image.
* Try to provide credentials.
* Try with github token.
* use main reference
* Changed LDAP Admin password.
* Added debug.
* Added more debug
* Removed debug.
* dd test for MySQL
* Fix name
* Test is independant
* Link build
* add envar DB for MySQL
* remove depends
* fix fast failed
* fix mysql user
* Use 127.0.0.1 to force for IPv4
* For parameters for MySQL
* Database name test_modoboa
* change mysql user to launch test
* Move to the last mysql version
lose connection on 5.7
* TEst some timout parameters
* remove bad parameters
* Add CONN_MAX_AGE parameters
* Add docker logs
* Try to reset db connections before we spawn processes.
* POC replace travis by Github Actions
* add libldap2-dev
* add libsasl2-dev libssl-dev
* Delete .travis.yml
* Add specific configuration for PostgreSQL
* Retrieve PostgreSQL or MySQL port from env var
* Print affected port for the docker service
* Add Database type and dburl
* Fix dbtype
* Use environment variable to define the port in use for tests.
* Configured password for postgres connection.
* Added redis service.
* Enabled OpenLDAP service.
* Use a container for OpenLDAP too.
* Removed wrong option.
* Fixed volume syntax.
* Try using the option directly.
* Try using an absolute path.
* Fixed wrong syntax.
* Try different format for env variable.
* Try a different way to load data.
* Added missing method call.
* Fix envar
* Try to wait a bit before starting tests.
* Display openldap service logs.
* Fixed ldif scripts path.
* Try to use a custom docker image.
* Try to provide credentials.
* Try with github token.
* use main reference
* Changed LDAP Admin password.
* Added debug.
* Added more debug
* Removed debug.
* dd test for MySQL
* Fix name
* Test is independant
* Link build
* add envar DB for MySQL
* remove depends
* fix fast failed
* fix mysql user
* Use 127.0.0.1 to force for IPv4
* For parameters for MySQL
* Database name test_modoboa
* change mysql user to launch test
* Move to the last mysql version
lose connection on 5.7
* TEst some timout parameters
* remove bad parameters
* Add CONN_MAX_AGE parameters
* Add docker logs
* Try to reset db connections before we spawn processes.
* Add relase on pypi (test server first)
* Fix setuptools scm to fix upload on Pypi test
* Retrieve all repos when publish on pypi
* if file exists, skip it
* Deploy only on master
* Added python 3.5 in matrix.
* Removed comments.
* Add translation and codecov
* Missing argument for upload in production
* fix bad indentation
* move codecov
* Codecov only in one build
* fix command
* Try to run codecov after PG tests.
* Fixed expressions syntax.
* Fixed path issue.
* Fixed path issue.
* Try workflow_run statement.
* Removed useless triggers.
* Test trigger on one workflow
* Another test
* Exclude master and main branch
* Regroup all steps in one workflow.
* Fixed typo
* Fixed bad syntax
* Added missing requirement.
* Push on Pypi Test only on master branch
Co-authored-by: Antoine Nguyen
---
.github/workflows/modoboa.yml | 180 ++++++++++++++++++++++++++
.travis.yml | 77 -----------
modoboa/core/tests/test_ldap.py | 3 +-
modoboa/ldapsync/tests.py | 5 +-
modoboa/policyd/tests.py | 2 +
modoboa/test_settings.py | 19 +--
setup.py | 7 +-
test_project/test_project/settings.py | 13 +-
tests.py | 17 ++-
9 files changed, 226 insertions(+), 97 deletions(-)
create mode 100644 .github/workflows/modoboa.yml
delete mode 100644 .travis.yml
diff --git a/.github/workflows/modoboa.yml b/.github/workflows/modoboa.yml
new file mode 100644
index 000000000..cfd765302
--- /dev/null
+++ b/.github/workflows/modoboa.yml
@@ -0,0 +1,180 @@
+# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
+# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
+
+name: Modoboa App
+
+on:
+ push:
+ branches: [ master ]
+ pull_request:
+ branches: [ master ]
+
+env:
+ POSTGRES_HOST: localhost
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ services:
+ postgres:
+ image: postgres:11
+ env:
+ POSTGRES_USER: postgres
+ POSTGRES_PASSWORD: postgres
+ POSTGRES_DB: postgres
+ ports:
+ # will assign a random free host port
+ - 5432/tcp
+ # needed because the postgres container does not provide a healthcheck
+ options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
+ mysql:
+ image: mysql:8.0
+ env:
+ MYSQL_ROOT_PASSWORD: root
+ MYSQL_USER: modoboa
+ MYSQL_PASSWORD: modoboa
+ MYSQL_DATABASE: modoboa
+ ports:
+ - 3306/tcp
+ options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
+ redis:
+ image: redis
+ ports:
+ - 6379/tcp
+ openldap:
+ image: docker.pkg.github.com/modoboa/docker-openldap/docker-openldap
+ ports:
+ - 389/tcp
+ env:
+ LDAP_DOMAIN: example.com
+ LDAP_ADMIN_PASSWORD: test
+ credentials:
+ username: tonioo
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ strategy:
+ matrix:
+ database: ['postgres', 'mysql']
+ python-version: [3.6, 3.7, 3.8]
+ fail-fast: false
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v2
+ with:
+ python-version: ${{ matrix.python-version }}
+ - name: Install dependencies
+ run: |
+ sudo apt-get install postfix librrd-dev rrdtool libldap2-dev libsasl2-dev libssl-dev
+ python -m pip install --upgrade pip
+ pip install -r requirements.txt
+ pip install -r ldap-requirements.txt
+ pip install -r test-requirements.txt
+ python setup.py develop
+ - name: Install postgres requirements
+ if: ${{ matrix.database == 'postgres' }}
+ run: |
+ pip install -r postgresql-requirements.txt
+ pip install coverage
+ echo "DB=postgres" >> $GITHUB_ENV
+ - name: Install mysql requirements
+ if: ${{ matrix.database == 'mysql' }}
+ run: |
+ pip install -r mysql-requirements.txt
+ echo "DB=mysql" >> $GITHUB_ENV
+ - name: Test with pytest
+ if: ${{ matrix.python-version != '3.8' || matrix.database != 'postgres' }}
+ run: |
+ python ./tests.py
+ cd test_project
+ python3 manage.py test modoboa.core modoboa.lib modoboa.admin modoboa.limits modoboa.transport modoboa.relaydomains modoboa.dnstools modoboa.ldapsync modoboa.policyd modoboa.maillog
+ env:
+ # use localhost for the host here because we are running the job on the VM.
+ # If we were running the job on in a container this would be postgres
+ POSTGRES_PORT: ${{ job.services.postgres.ports[5432] }} # get randomly assigned published port
+ MYSQL_HOST: 127.0.0.1
+ MYSQL_PORT: ${{ job.services.mysql.ports[3306] }} # get randomly assigned published port
+ MYSQL_USER: root
+ REDIS_PORT: ${{ job.services.redis.ports[6379] }}
+ LDAP_SERVER_PORT: ${{ job.services.openldap.ports[389] }}
+
+ - name: Test with pytest and coverage
+ if: ${{ matrix.python-version == '3.8' && matrix.database == 'postgres' }}
+ run: |
+ python ./tests.py
+ cd test_project
+ coverage run manage.py test modoboa.core modoboa.lib modoboa.admin modoboa.limits modoboa.transport modoboa.relaydomains modoboa.dnstools modoboa.ldapsync modoboa.policyd modoboa.maillog
+ coverage combine
+ env:
+ # use localhost for the host here because we are running the job on the VM.
+ # If we were running the job on in a container this would be postgres
+ POSTGRES_PORT: ${{ job.services.postgres.ports[5432] }} # get randomly assigned published port
+ MYSQL_HOST: 127.0.0.1
+ MYSQL_PORT: ${{ job.services.mysql.ports[3306] }} # get randomly assigned published port
+ MYSQL_USER: root
+ REDIS_PORT: ${{ job.services.redis.ports[6379] }}
+ LDAP_SERVER_PORT: ${{ job.services.openldap.ports[389] }}
+ - name: Upload coverage result
+ if: ${{ matrix.python-version == '3.8' }}
+ uses: actions/upload-artifact@v2
+ with:
+ name: coverage-results
+ path: test_project/.coverage
+
+ coverage:
+ needs: test
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up Python 3.8
+ uses: actions/setup-python@v2
+ with:
+ python-version: '3.8'
+ - name: Install dependencies
+ run: |
+ pip install codecov
+ - name: Download coverage results
+ uses: actions/download-artifact@v2
+ with:
+ name: coverage-results
+ - name: Report coverage
+ run: |
+ coverage report
+ codecov
+
+ release:
+ needs: coverage
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
+ - name: Set up Python 3.8
+ uses: actions/setup-python@v2
+ with:
+ python-version: '3.8'
+ - name: Install dependencies
+ run: |
+ sudo apt-get install librrd-dev rrdtool libssl-dev gettext
+ python -m pip install --upgrade pip setuptools wheel
+ pip install -r requirements.txt
+ cd modoboa
+ django-admin compilemessages
+ cd ..
+ python setup.py sdist bdist_wheel
+ - name: Publish to Test PyPI
+ if: endsWith(github.event.ref, '/master')
+ uses: pypa/gh-action-pypi-publish@master
+ with:
+ user: __token__
+ password: ${{ secrets.test_pypi_password }}
+ repository_url: https://test.pypi.org/legacy/
+ skip_existing: true
+ - name: Publish distribution to PyPI
+ if: startsWith(github.event.ref, 'refs/tags') || github.event_name == 'release'
+ uses: pypa/gh-action-pypi-publish@master
+ with:
+ user: __token__
+ password: ${{ secrets.pypi_password }}
+ skip_existing: true
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 41ae74815..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,77 +0,0 @@
-language: python
-python:
- - '3.5'
- - '3.6'
- - '3.7'
- - '3.8'
-
-env:
- global:
- - PYTHONWARNINGS="default,ignore::PendingDeprecationWarning,ignore::ResourceWarning"
- matrix:
- - DB="POSTGRESQL"
- - DB="MYSQL"
-
-sudo: false
-
-addons:
- postgresql: '9.6'
- mysql: '5.5'
- apt:
- packages:
- - ldap-utils
- - postfix
- - slapd
- - librrd-dev
- - rrdtool
-
-cache: pip
-
-services:
- - postgres
- - mysql
- - redis-server
-
-before_install:
- - pip install codecov
-
-install:
- - pip install -r requirements.txt
- - pip install -r ldap-requirements.txt
- - pip install -r test-requirements.txt
- - if [ $DB = POSTGRESQL ]; then pip install -r postgresql-requirements.txt ; fi
- - if [ $DB = MYSQL ]; then pip install -r mysql-requirements.txt ; fi
- - python setup.py develop
-
-before_script:
- - mkdir /tmp/slapd
- - slapd -f test_data/slapd.conf -h ldap://localhost:3389 &
- - sleep 3
- - ldapadd -h localhost:3389 -D cn=admin,dc=example,dc=com -w test -f test_data/base.ldif
-
-script:
- - python ./tests.py
- - cd test_project
- - coverage run manage.py test modoboa.core modoboa.lib modoboa.admin modoboa.limits modoboa.transport modoboa.relaydomains modoboa.dnstools modoboa.ldapsync modoboa.policyd modoboa.maillog
-
-after_success:
- - coverage combine
- - coverage report
- - codecov
-
-before_deploy:
- - cd ../modoboa
- - django-admin compilemessages
- - cd ..
-
-deploy:
- provider: pypi
- user: tonio
- password:
- secure: SKFrH4cri56YQziqMZ4uvbh5Vto9YrQuBlYRnO9BwcjXbcp6jMpZ+9j+aytMdvcN+xG5of6DmgSIiZsLCOl4LDoPn2oPwWMzZA9T8knSVYt9v1uiBTwDmssIt9QH3wD/o3edpTsSoKw+O2cTT2GaE75+3aTK01+CX4ZsUtkGbTk=
- skip_cleanup: true
- distributions: sdist bdist_wheel
- on:
- tags: true
- python: '3.8'
- condition: "$DB = POSTGRESQL"
diff --git a/modoboa/core/tests/test_ldap.py b/modoboa/core/tests/test_ldap.py
index a1b843319..bc666ccca 100644
--- a/modoboa/core/tests/test_ldap.py
+++ b/modoboa/core/tests/test_ldap.py
@@ -2,6 +2,7 @@
from unittest import skipIf
+from django.conf import settings
from django.test import override_settings
from django.urls import reverse
from django.utils.functional import cached_property
@@ -25,7 +26,7 @@ class LDAPTestCaseMixin(object):
"""Modify settings."""
self.set_global_parameters({
"authentication_type": "ldap",
- "ldap_server_port": 3389
+ "ldap_server_port": settings.LDAP_SERVER_PORT
})
def restore_user_password(self, username, new_password):
diff --git a/modoboa/ldapsync/tests.py b/modoboa/ldapsync/tests.py
index 398de8603..0429cebdb 100644
--- a/modoboa/ldapsync/tests.py
+++ b/modoboa/ldapsync/tests.py
@@ -2,6 +2,7 @@
from unittest import skipIf
+from django.conf import settings
from django.core.management import call_command
from django.utils.encoding import force_bytes, force_str
@@ -23,7 +24,7 @@ class LDAPExportTestCase(ModoTestCase):
super().setUp()
self.set_global_parameters({
"ldap_enable_sync": True,
- "ldap_server_port": 3389,
+ "ldap_server_port": settings.LDAP_SERVER_PORT,
"ldap_sync_bind_dn": "cn=admin,dc=example,dc=com",
"ldap_sync_bind_password": "test",
"ldap_sync_account_dn_template": (
@@ -111,7 +112,7 @@ class LDAPImportTestCase(ModoTestCase):
super().setUp()
self.set_global_parameters({
"ldap_enable_import": True,
- "ldap_server_port": 3389,
+ "ldap_server_port": settings.LDAP_SERVER_PORT,
"ldap_sync_bind_dn": "cn=admin,dc=example,dc=com",
"ldap_sync_bind_password": "test",
"ldap_import_search_base": "ou=users,dc=example,dc=com",
diff --git a/modoboa/policyd/tests.py b/modoboa/policyd/tests.py
index a53b5b790..1461b7e47 100644
--- a/modoboa/policyd/tests.py
+++ b/modoboa/policyd/tests.py
@@ -9,6 +9,7 @@ import time
import redis
+from django import db
from django.conf import settings
from django.core.management import call_command
from django.test import TransactionTestCase
@@ -55,6 +56,7 @@ class PolicyDaemonTestCase(
self.admin = core_models.User.objects.get(username="user@test2.com")
self.admin.role = "SuperAdmins"
+ db.connections.close_all()
patcher = patch("aiosmtplib.send")
self.send_mock = patcher.start()
self.process = Process(target=start_policy_daemon)
diff --git a/modoboa/test_settings.py b/modoboa/test_settings.py
index cee94b28b..669959437 100644
--- a/modoboa/test_settings.py
+++ b/modoboa/test_settings.py
@@ -3,17 +3,17 @@ import os
# Database
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
-DB = os.environ.get("DB", "POSTGRESQL")
+DB = os.environ.get("DB", "postgres").lower()
-if DB == "MYSQL":
+if DB == "mysql":
DATABASES = {
"default": {
"ENGINE": "django.db.backends.mysql",
"NAME": "modoboa",
- "USER": "root",
- "PASSWORD": "",
- "HOST": "localhost",
- "PORT": "",
+ "USER": os.environ.get("MYSQL_USER", "root"),
+ "PASSWORD": os.environ.get("MYSQL_PASSWORD", "root"),
+ "HOST": "127.0.0.1",
+ "PORT": os.environ.get("MYSQL_PORT", "3306"),
"ATOMIC_REQUESTS": True,
# MySQL's Strict Mode fixes many data integrity problems in MySQL,
# such as data truncation upon insertion, by escalating warnings
@@ -27,6 +27,7 @@ if DB == "MYSQL":
"SET innodb_strict_mode = ON;"
),
"charset": "utf8",
+ "connect_timeout": 10,
},
"TEST": {
"CHARSET": "utf8",
@@ -34,7 +35,7 @@ if DB == "MYSQL":
},
},
}
-elif DB == "SQLITE":
+elif DB == "sqlite":
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
@@ -49,9 +50,9 @@ else:
"ENGINE": "django.db.backends.postgresql",
"NAME": "modoboa",
"USER": "postgres",
- "PASSWORD": "",
+ "PASSWORD": "postgres",
"HOST": "localhost",
- "PORT": "",
+ "PORT": os.environ.get("POSTGRES_PORT", "5432"),
"ATOMIC_REQUESTS": True,
"OPTIONS": {
"client_encoding": "UTF8",
diff --git a/setup.py b/setup.py
index 19e19ac07..654824d25 100644
--- a/setup.py
+++ b/setup.py
@@ -45,6 +45,11 @@ if __name__ == "__main__":
with open(path.join(HERE, "README.rst")) as readme:
LONG_DESCRIPTION = readme.read()
+ def local_scheme(version):
+ """Skip the local version (eg. +xyz of 0.6.1.dev4+gdf99fe2)
+ to be able to upload to Test PyPI"""
+ return ""
+
setup(
name="modoboa",
description="Mail hosting made simple",
@@ -74,7 +79,7 @@ if __name__ == "__main__":
zip_safe=False,
scripts=["bin/modoboa-admin.py"],
install_requires=INSTALL_REQUIRES,
- use_scm_version=True,
+ use_scm_version={"local_scheme": local_scheme},
python_requires=">=3.4",
setup_requires=["setuptools_scm"],
extras_require={
diff --git a/test_project/test_project/settings.py b/test_project/test_project/settings.py
index c626b04de..bd94c34a7 100644
--- a/test_project/test_project/settings.py
+++ b/test_project/test_project/settings.py
@@ -196,7 +196,7 @@ MODOBOA_API_URL = 'https://api.modoboa.org/1/'
# REDIS
REDIS_HOST = 'localhost'
-REDIS_PORT = 6379
+REDIS_PORT = os.environ.get('REDIS_PORT', 6379)
REDIS_QUOTA_DB = 0
REDIS_URL = 'redis://{}:{}/{}'.format(REDIS_HOST, REDIS_PORT, REDIS_QUOTA_DB)
@@ -281,6 +281,9 @@ LOGGING = {
},
'modoboa': {
'class': 'modoboa.core.loggers.SQLHandler',
+ },
+ 'console': {
+ 'class': 'logging.StreamHandler'
}
},
'loggers': {
@@ -298,7 +301,11 @@ LOGGING = {
'handlers': ['modoboa'],
'level': 'INFO',
'propagate': False
- }
+ },
+ # 'django_auth_ldap': {
+ # 'level': 'DEBUG',
+ # 'handlers': ['console']
+ # },
}
}
@@ -308,3 +315,5 @@ SILENCED_SYSTEM_CHECKS = [
DISABLE_DASHBOARD_EXTERNAL_QUERIES = False
# Load settings from extensions
+
+LDAP_SERVER_PORT = os.environ.get('LDAP_SERVER_PORT', 3389)
diff --git a/tests.py b/tests.py
index d34d331d3..df463c12e 100644
--- a/tests.py
+++ b/tests.py
@@ -5,22 +5,29 @@ import unittest
from modoboa.lib.sysutils import exec_cmd
DB = os.environ.get("DB", "postgres")
+if DB.lower() == "postgres":
+ PORT = os.environ.get("POSTGRES_PORT", "5432")
+ DB = "postgres"
+else:
+ PORT = os.environ.get("MYSQL_PORT", "3306")
+ DB = "mysql"
class DeployTest(unittest.TestCase):
- dbtype = DB.lower()
+ dbtype = DB
dbhost = "localhost"
+ dbport = PORT
projname = "modoboa_test"
- dbuser = DB == "MYSQL" and "modoboa" or "postgres"
- dbpassword = DB == "MYSQL" and "modoboa" or ""
+ dbuser = DB == "mysql" and "modoboa" or "postgres"
+ dbpassword = DB == "mysql" and "modoboa" or ""
def setUp(self):
self.workdir = tempfile.mkdtemp()
def test_silent(self):
- dburl = "default:%s://%s:%s@%s/%s" \
+ dburl = "default:%s://%s:%s@%s:%s/%s" \
% (self.dbtype, self.dbuser, self.dbpassword,
- self.dbhost, self.projname)
+ self.dbhost, self.dbport, self.projname)
cmd = (
"modoboa-admin.py deploy --collectstatic "
"--dburl %s --domain %s --admin-username admin %s"
From 3c5db03a6596f83fa721a81041a2e957577a8bbf Mon Sep 17 00:00:00 2001
From: Antoine Nguyen
Date: Mon, 9 Nov 2020 20:52:48 +0100
Subject: [PATCH 32/44] Updated badges.
---
README.rst | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/README.rst b/README.rst
index e5ec8a035..f04c87da1 100644
--- a/README.rst
+++ b/README.rst
@@ -2,7 +2,7 @@
`Modoboa `_
################################
-|travis| |codecov| |latest-version|
+|workflow| |codecov| |latest-version|
Modoboa is a mail hosting and management platform including a modern
and simplified Web User Interface. It provides useful components such
@@ -73,7 +73,6 @@ The following external libraries are provided with Modoboa:
.. |latest-version| image:: https://img.shields.io/pypi/v/modoboa.svg
:target: https://pypi.python.org/pypi/modoboa/
:alt: Latest version on Pypi
-.. |travis| image:: https://travis-ci.org/modoboa/modoboa.png?branch=master
- :target: https://travis-ci.org/modoboa/modoboa
+.. |workflow| image:: https://github.com/modoboa/modoboa/workflows/Modoboa%20App/badge.svg
.. |codecov| image:: http://codecov.io/github/modoboa/modoboa/coverage.svg?branch=master
:target: http://codecov.io/github/modoboa/modoboa?branch=master
From 9075eb4d0a283e5edd4876e0ab3bc2a7ca3257d6 Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Mon, 9 Nov 2020 19:53:38 +0000
Subject: [PATCH 33/44] Update mysqlclient requirement from <=1.4.99 to <2.0.2
Updates the requirements on [mysqlclient](https://github.com/PyMySQL/mysqlclient-python) to permit the latest version.
- [Release notes](https://github.com/PyMySQL/mysqlclient-python/releases)
- [Changelog](https://github.com/PyMySQL/mysqlclient-python/blob/master/HISTORY.rst)
- [Commits](https://github.com/PyMySQL/mysqlclient-python/commits)
Signed-off-by: dependabot-preview[bot]
---
mysql-requirements.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mysql-requirements.txt b/mysql-requirements.txt
index ea498b097..4b7bd761c 100644
--- a/mysql-requirements.txt
+++ b/mysql-requirements.txt
@@ -1 +1 @@
-mysqlclient<=1.4.99
+mysqlclient<2.0.2
From 591f9b9a1d40af46183bc884079d12bff1c339f4 Mon Sep 17 00:00:00 2001
From: Antoine Nguyen
Date: Tue, 27 Oct 2020 17:12:48 +0100
Subject: [PATCH 34/44] Added drf-spectacular.
fix #2071
---
modoboa/admin/api.py | 11 ++--
modoboa/admin/serializers.py | 3 +
.../core/commands/templates/settings.py.tpl | 7 +++
modoboa/core/viewsets.py | 5 ++
modoboa/templates/swagger-ui.html | 57 -------------------
modoboa/urls.py | 18 ++----
requirements.txt | 1 +
7 files changed, 26 insertions(+), 76 deletions(-)
delete mode 100644 modoboa/templates/swagger-ui.html
diff --git a/modoboa/admin/api.py b/modoboa/admin/api.py
index 2c7ee274c..e9a334758 100644
--- a/modoboa/admin/api.py
+++ b/modoboa/admin/api.py
@@ -18,14 +18,13 @@ from . import lib, models, serializers
class DomainViewSet(viewsets.ModelViewSet):
"""
- retrieve:
- Return the given domain.
+ Domain viewset.
- list:
- Return a list of all existing domains.
+ retrieve: Return the given domain.
- create:
- Create a new domain instance.
+ list: Return a list of all existing domains.
+
+ create: Create a new domain instance.
"""
permission_classes = [IsAuthenticated, DjangoModelPermissions, ]
diff --git a/modoboa/admin/serializers.py b/modoboa/admin/serializers.py
index 8a68d184e..2a66a020e 100644
--- a/modoboa/admin/serializers.py
+++ b/modoboa/admin/serializers.py
@@ -7,6 +7,8 @@ from django.shortcuts import get_object_or_404
from django.utils.encoding import force_text
from django.utils.translation import ugettext as _, ugettext_lazy
+from drf_spectacular.types import OpenApiTypes
+from drf_spectacular.utils import extend_schema_field
from rest_framework import serializers
from modoboa.admin import models as admin_models
@@ -186,6 +188,7 @@ class AccountSerializer(serializers.ModelSerializer):
if not user.is_superuser:
del self.fields["master_user"]
+ @extend_schema_field(OpenApiTypes.STR)
def get_role(self, account):
"""Return role."""
return account.role
diff --git a/modoboa/core/commands/templates/settings.py.tpl b/modoboa/core/commands/templates/settings.py.tpl
index c604ca92b..243658309 100644
--- a/modoboa/core/commands/templates/settings.py.tpl
+++ b/modoboa/core/commands/templates/settings.py.tpl
@@ -64,6 +64,7 @@ INSTALLED_APPS = (
'ckeditor_uploader',
'rest_framework',
'rest_framework.authtoken',
+ 'drf_spectacular',
'phonenumber_field',
'django_otp',
'django_otp.plugins.otp_totp',
@@ -192,6 +193,12 @@ REST_FRAMEWORK = {
),
}
+SPECTACULAR_SETTINGS = {
+ 'SCHEMA_PATH_PREFIX': r'/api/v1',
+ 'TITLE': 'Modoboa API',
+ 'VERSION': '1.0.0'
+}
+
# Modoboa settings
# MODOBOA_CUSTOM_LOGO = os.path.join(MEDIA_URL, "custom_logo.png")
diff --git a/modoboa/core/viewsets.py b/modoboa/core/viewsets.py
index 177160688..1014c2e4d 100644
--- a/modoboa/core/viewsets.py
+++ b/modoboa/core/viewsets.py
@@ -7,6 +7,7 @@ from django_otp.plugins.otp_static.models import StaticDevice, StaticToken
from django_otp.plugins.otp_totp.models import TOTPDevice
from rest_framework import permissions, response, viewsets
from rest_framework.decorators import action
+from drf_spectacular.utils import extend_schema
from . import serializers
@@ -28,6 +29,9 @@ class AccountViewSet(viewsets.ViewSet):
)
return response.Response()
+ @extend_schema(
+ request=serializers.CheckTFASetupSerializer
+ )
@action(methods=["post"], detail=False, url_path="tfa/setup/check")
def tfa_setup_check(self, request):
"""Check TFA setup."""
@@ -57,6 +61,7 @@ class AccountViewSet(viewsets.ViewSet):
request.user.save()
return response.Response()
+ @extend_schema(tags=['account'])
@action(methods=["post"], detail=False, url_path="tfa/reset_codes")
def tfa_reset_codes(self, request, *args, **kwargs):
"""Reset recovery codes."""
diff --git a/modoboa/templates/swagger-ui.html b/modoboa/templates/swagger-ui.html
deleted file mode 100644
index efbd02f35..000000000
--- a/modoboa/templates/swagger-ui.html
+++ /dev/null
@@ -1,57 +0,0 @@
-
-{% load static %}
-
-
-
-
- Modoboa API
-
-
-
-
-
-
-
-
-
diff --git a/modoboa/urls.py b/modoboa/urls.py
index d5a5390de..5e9e1deda 100644
--- a/modoboa/urls.py
+++ b/modoboa/urls.py
@@ -6,11 +6,9 @@ from django.conf import settings
from django.contrib.auth import views as auth_views
from django.contrib.auth.decorators import login_required
from django.urls import include, path
-from django.views.generic import TemplateView
from django.views.i18n import JavaScriptCatalog
-from rest_framework.renderers import JSONOpenAPIRenderer
-from rest_framework.schemas import get_schema_view
+from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView
from modoboa.admin.views import user as user_views
from modoboa.core import signals as core_signals, views as core_views
@@ -59,17 +57,11 @@ if extra_routes:
urlpatterns += extra_routes
# API urls
-schema_view = get_schema_view(
- title="Modoboa API",
- version="1.0.0",
- public=False,
- renderer_classes=[JSONOpenAPIRenderer],
-)
urlpatterns += [
- path('docs/openapi.json', schema_view, name="openapi_schema"),
- path('docs/api/', login_required(
- TemplateView.as_view(template_name="swagger-ui.html")),
- name="docs-index"),
+ path('docs/openapi.json', SpectacularAPIView.as_view(), name='schema'),
+ path('docs/api/',
+ SpectacularSwaggerView.as_view(url_name='schema'),
+ name='docs-index'),
path('api/v1/', include("modoboa.urls_api")),
]
diff --git a/requirements.txt b/requirements.txt
index 8242a5aea..485d9cf23 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -9,6 +9,7 @@ django-otp==1.0.2
dj-database-url
djangorestframework>=3.11,<3.12
+drf-spectacular
uritemplate
passlib~=1.7.4
From 78a772eaf182c6c16d773922695199f11d98d438 Mon Sep 17 00:00:00 2001
From: Antoine Nguyen
Date: Mon, 9 Nov 2020 21:20:18 +0100
Subject: [PATCH 35/44] Added description for domain viewset routes.
---
modoboa/admin/api.py | 25 ++++++++++++++++---------
modoboa/urls.py | 6 +++++-
2 files changed, 21 insertions(+), 10 deletions(-)
diff --git a/modoboa/admin/api.py b/modoboa/admin/api.py
index e9a334758..7a1b04e6c 100644
--- a/modoboa/admin/api.py
+++ b/modoboa/admin/api.py
@@ -4,6 +4,7 @@ from django import http
from django.contrib.contenttypes.models import ContentType
from django.utils.translation import ugettext as _
+from drf_spectacular.utils import extend_schema, extend_schema_view
from rest_framework import filters, status, viewsets
from rest_framework.decorators import action
from rest_framework.exceptions import ParseError
@@ -16,16 +17,22 @@ from modoboa.core import sms_backends
from . import lib, models, serializers
+@extend_schema_view(
+ retrieve=extend_schema(
+ description="Retrieve a particular domain",
+ summary="Retrieve a particular domain"
+ ),
+ list=extend_schema(
+ description="Retrieve a list of domains",
+ summary="Retrieve a list of domains"
+ ),
+ create=extend_schema(
+ description="Create a new domain",
+ summary="Create a new domain"
+ )
+)
class DomainViewSet(viewsets.ModelViewSet):
- """
- Domain viewset.
-
- retrieve: Return the given domain.
-
- list: Return a list of all existing domains.
-
- create: Create a new domain instance.
- """
+ """Domain viewset."""
permission_classes = [IsAuthenticated, DjangoModelPermissions, ]
serializer_class = serializers.DomainSerializer
diff --git a/modoboa/urls.py b/modoboa/urls.py
index 5e9e1deda..3198d8844 100644
--- a/modoboa/urls.py
+++ b/modoboa/urls.py
@@ -8,7 +8,9 @@ from django.contrib.auth.decorators import login_required
from django.urls import include, path
from django.views.i18n import JavaScriptCatalog
-from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView
+from drf_spectacular.views import (
+ SpectacularAPIView, SpectacularSwaggerView, SpectacularRedocView
+)
from modoboa.admin.views import user as user_views
from modoboa.core import signals as core_signals, views as core_views
@@ -62,6 +64,8 @@ urlpatterns += [
path('docs/api/',
SpectacularSwaggerView.as_view(url_name='schema'),
name='docs-index'),
+ path('docs/api/redoc/', SpectacularRedocView.as_view(url_name='schema'),
+ name='redoc'),
path('api/v1/', include("modoboa.urls_api")),
]
From a15a35a62589c8d1b25c4c964508fa077ed70df3 Mon Sep 17 00:00:00 2001
From: Antoine Nguyen
Date: Mon, 9 Nov 2020 21:22:19 +0100
Subject: [PATCH 36/44] Added missing setting.
---
modoboa/core/commands/templates/settings.py.tpl | 1 +
1 file changed, 1 insertion(+)
diff --git a/modoboa/core/commands/templates/settings.py.tpl b/modoboa/core/commands/templates/settings.py.tpl
index 243658309..a404ca01d 100644
--- a/modoboa/core/commands/templates/settings.py.tpl
+++ b/modoboa/core/commands/templates/settings.py.tpl
@@ -191,6 +191,7 @@ REST_FRAMEWORK = {
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
+ 'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
}
SPECTACULAR_SETTINGS = {
From e4f5a25e64da86239bb083b1588f235f3a9f3d23 Mon Sep 17 00:00:00 2001
From: Antoine Nguyen
Date: Mon, 9 Nov 2020 21:56:48 +0100
Subject: [PATCH 37/44] Added missing test config.
---
test_project/test_project/settings.py | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/test_project/test_project/settings.py b/test_project/test_project/settings.py
index bd94c34a7..29f83a8ff 100644
--- a/test_project/test_project/settings.py
+++ b/test_project/test_project/settings.py
@@ -63,6 +63,7 @@ INSTALLED_APPS = (
'ckeditor_uploader',
'rest_framework',
'rest_framework.authtoken',
+ 'drf_spectacular',
'django_otp',
'django_otp.plugins.otp_totp',
'django_otp.plugins.otp_static',
@@ -184,6 +185,13 @@ REST_FRAMEWORK = {
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
+ 'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
+}
+
+SPECTACULAR_SETTINGS = {
+ 'SCHEMA_PATH_PREFIX': r'/api/v1',
+ 'TITLE': 'Modoboa API',
+ 'VERSION': '1.0.0'
}
# Modoboa settings
From b9720c1837cebfea845860d36a99d32e268d0bd2 Mon Sep 17 00:00:00 2001
From: Antoine Nguyen
Date: Tue, 10 Nov 2020 16:07:34 +0100
Subject: [PATCH 38/44] Fixed unit tests.
---
modoboa/core/commands/templates/settings.py.tpl | 3 ++-
modoboa/core/tests/test_api.py | 11 ++---------
test_project/test_project/settings.py | 3 ++-
3 files changed, 6 insertions(+), 11 deletions(-)
diff --git a/modoboa/core/commands/templates/settings.py.tpl b/modoboa/core/commands/templates/settings.py.tpl
index a404ca01d..cab8a30e3 100644
--- a/modoboa/core/commands/templates/settings.py.tpl
+++ b/modoboa/core/commands/templates/settings.py.tpl
@@ -197,7 +197,8 @@ REST_FRAMEWORK = {
SPECTACULAR_SETTINGS = {
'SCHEMA_PATH_PREFIX': r'/api/v1',
'TITLE': 'Modoboa API',
- 'VERSION': '1.0.0'
+ 'VERSION': '1.0.0',
+ 'SERVE_PERMISSIONS': ['rest_framework.permissions.IsAuthenticated'],
}
# Modoboa settings
diff --git a/modoboa/core/tests/test_api.py b/modoboa/core/tests/test_api.py
index ef1fe5b77..043222304 100644
--- a/modoboa/core/tests/test_api.py
+++ b/modoboa/core/tests/test_api.py
@@ -4,16 +4,13 @@ from modoboa.lib.tests import ModoTestCase
class OpenAPITestCase(ModoTestCase):
- openapi_schema_url = reverse_lazy('openapi_schema')
+ openapi_schema_url = reverse_lazy('schema')
def test_unauthorized(self):
self.client.logout()
- response = self.client.get("/docs/api/")
- self.assertRedirects(response, "/accounts/login/?next=/docs/api/")
-
response = self.client.get(self.openapi_schema_url)
- self.assertEqual(response.status_code, 403)
+ self.assertEqual(response.status_code, 401)
def test_get_schema(self):
self.assertEqual(self.openapi_schema_url, "/docs/openapi.json")
@@ -24,7 +21,3 @@ class OpenAPITestCase(ModoTestCase):
'title': "Modoboa API",
'version': "1.0.0",
})
-
- def test_get_swagger_ui(self):
- response = self.client.get("/docs/api/")
- self.assertContains(response, "Modoboa API")
diff --git a/test_project/test_project/settings.py b/test_project/test_project/settings.py
index 29f83a8ff..a2579f81b 100644
--- a/test_project/test_project/settings.py
+++ b/test_project/test_project/settings.py
@@ -191,7 +191,8 @@ REST_FRAMEWORK = {
SPECTACULAR_SETTINGS = {
'SCHEMA_PATH_PREFIX': r'/api/v1',
'TITLE': 'Modoboa API',
- 'VERSION': '1.0.0'
+ 'VERSION': '1.0.0',
+ 'SERVE_PERMISSIONS': ['rest_framework.permissions.IsAuthenticated'],
}
# Modoboa settings
From 304ee7e8fb3fc75650d93eae39008a00d4a18eb9 Mon Sep 17 00:00:00 2001
From: Antoine Nguyen
Date: Tue, 10 Nov 2020 16:25:22 +0100
Subject: [PATCH 39/44] Fixed unit test.
---
modoboa/urls.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/modoboa/urls.py b/modoboa/urls.py
index 3198d8844..8c3813902 100644
--- a/modoboa/urls.py
+++ b/modoboa/urls.py
@@ -9,7 +9,7 @@ from django.urls import include, path
from django.views.i18n import JavaScriptCatalog
from drf_spectacular.views import (
- SpectacularAPIView, SpectacularSwaggerView, SpectacularRedocView
+ SpectacularJSONAPIView, SpectacularSwaggerView, SpectacularRedocView
)
from modoboa.admin.views import user as user_views
@@ -60,7 +60,7 @@ if extra_routes:
# API urls
urlpatterns += [
- path('docs/openapi.json', SpectacularAPIView.as_view(), name='schema'),
+ path('docs/openapi.json', SpectacularJSONAPIView.as_view(), name='schema'),
path('docs/api/',
SpectacularSwaggerView.as_view(url_name='schema'),
name='docs-index'),
From bbe4528a4acc592211d26fda3e446b1b65dfe3a8 Mon Sep 17 00:00:00 2001
From: Christophe CHAUVET
Date: Tue, 10 Nov 2020 17:45:17 +0100
Subject: [PATCH 40/44] Use GH Actions instead of travis
---
.mergify.yml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/.mergify.yml b/.mergify.yml
index 9cc823a39..803677c60 100644
--- a/.mergify.yml
+++ b/.mergify.yml
@@ -1,7 +1,7 @@
pull_request_rules:
- name: automatic merge on CI success and review
conditions:
- - check-success=Travis CI - Pull Request
+ - check-success=test (postgres, 3.7)
- "#approved-reviews-by>=1"
- "#review-requested=0"
- "#changes-requested-reviews-by=0"
@@ -19,7 +19,7 @@ pull_request_rules:
- name: automatic merge for pyUp pull requests
conditions:
- author=pyup-bot
- - check-success=Travis CI - Pull Request
+ - check-success=test (postgres, 3.7)
- label=dependencies
- "#approved-reviews-by>=1"
actions:
@@ -30,7 +30,7 @@ pull_request_rules:
- name: automatic merge for dependabot pull requests
conditions:
- author~=^dependabot(|-preview)\[bot\]$
- - check-success=Travis CI - Pull Request
+ - check-success=test (postgres, 3.7)
- label=dependencies
- "#approved-reviews-by>=1"
actions:
From 21d101b6d66ed2f2f116dfd6618f44c08ebd9114 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 10 Nov 2020 17:16:35 +0000
Subject: [PATCH 41/44] Bump jsonfield from 2.0.2 to 3.1.0 (#2053)
Bumps [jsonfield](https://github.com/rpkilby/jsonfield) from 2.0.2 to 3.1.0.
- [Release notes](https://github.com/rpkilby/jsonfield/releases)
- [Changelog](https://github.com/rpkilby/jsonfield/blob/master/CHANGES.rst)
- [Commits](https://github.com/rpkilby/jsonfield/compare/2.0.2...3.1.0)
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
requirements.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/requirements.txt b/requirements.txt
index 485d9cf23..42e76857a 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -19,7 +19,7 @@ dnspython==1.16.0
feedparser==5.2.1
greenlet==0.4.17
gevent==20.9.0
-jsonfield==2.0.2
+jsonfield==3.1.0
Pillow # Optional dependency for django-ckeditor
progressbar33==2.4
py-dateutil==2.2
From 2ab3bc3956f12d7311b8e7ad2a5ce285abdd7dba Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 10 Nov 2020 18:55:39 +0000
Subject: [PATCH 42/44] Bump feedparser from 5.2.1 to 6.0.2 (#2068)
Bumps [feedparser](https://github.com/kurtmckee/feedparser) from 5.2.1 to 6.0.2.
- [Release notes](https://github.com/kurtmckee/feedparser/releases)
- [Changelog](https://github.com/kurtmckee/feedparser/blob/develop/CHANGELOG.rst)
- [Commits](https://github.com/kurtmckee/feedparser/compare/5.2.1...6.0.2)
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Christophe CHAUVET
---
requirements.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/requirements.txt b/requirements.txt
index 42e76857a..46c1c972d 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -16,7 +16,7 @@ passlib~=1.7.4
bcrypt # Requires libffi-dev and python-dev
dnspython==1.16.0
-feedparser==5.2.1
+feedparser==6.0.2
greenlet==0.4.17
gevent==20.9.0
jsonfield==3.1.0
From eca303ee30232e351331a8bda842c754c1140913 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 10 Nov 2020 20:17:55 +0000
Subject: [PATCH 43/44] Bump django-reversion from 3.0.5 to 3.0.8 (#2060)
Bumps [django-reversion](https://github.com/etianen/django-reversion) from 3.0.5 to 3.0.8.
- [Release notes](https://github.com/etianen/django-reversion/releases)
- [Changelog](https://github.com/etianen/django-reversion/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/etianen/django-reversion/compare/v3.0.5...v3.0.8)
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Christophe CHAUVET
---
requirements.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/requirements.txt b/requirements.txt
index 46c1c972d..3edf7add3 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -2,7 +2,7 @@ django>=2.2,<2.3
django-braces==1.14.0
django-ckeditor==6.0.0
django-phonenumber-field[phonenumbers]==5.0.0
-django-reversion==3.0.5
+django-reversion==3.0.8
django-xforwardedfor-middleware==2.0
django-otp==1.0.2
From 268414ace8a7ae6adb4da97616c4b6307d13bb06 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 10 Nov 2020 20:29:31 +0000
Subject: [PATCH 44/44] Update djangorestframework requirement from
<3.12,>=3.11 to >=3.11,<3.13 (#2052)
Updates the requirements on [djangorestframework](https://github.com/encode/django-rest-framework) to permit the latest version.
- [Release notes](https://github.com/encode/django-rest-framework/releases)
- [Commits](https://github.com/encode/django-rest-framework/compare/3.11.0...3.12.1)
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Christophe CHAUVET
---
requirements.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/requirements.txt b/requirements.txt
index 3edf7add3..3e9a0cccf 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -8,7 +8,7 @@ django-otp==1.0.2
dj-database-url
-djangorestframework>=3.11,<3.12
+djangorestframework>=3.11,<3.13
drf-spectacular
uritemplate