Merge branch 'master' into refacto/vuejs_interface

This commit is contained in:
Antoine Nguyen
2020-11-13 14:20:46 +01:00
45 changed files with 1100 additions and 684 deletions
+4
View File
@@ -1,5 +1,9 @@
# Impacted versions
* 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
+7
View File
@@ -0,0 +1,7 @@
version: 2
updates:
- package-ecosystem: pip
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10
+28
View File
@@ -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: 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)
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
+180
View File
@@ -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
+40
View File
@@ -0,0 +1,40 @@
pull_request_rules:
- name: automatic merge on CI success and review
conditions:
- check-success=test (postgres, 3.7)
- "#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=test (postgres, 3.7)
- label=dependencies
- "#approved-reviews-by>=1"
actions:
merge:
method: squash
strict: true
strict_method: rebase
- name: automatic merge for dependabot pull requests
conditions:
- author~=^dependabot(|-preview)\[bot\]$
- check-success=test (postgres, 3.7)
- label=dependencies
- "#approved-reviews-by>=1"
actions:
merge:
method: squash
strict: true
strict_method: rebase
-77
View File
@@ -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"
+11 -9
View File
@@ -1,21 +1,23 @@
FROM python:3.6-alpine as base
MAINTAINER Antoine Nguyen <tonio@ngyn.org>
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
+2 -3
View File
@@ -2,7 +2,7 @@
`Modoboa <http://modoboa.org/>`_
################################
|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
-5
View File
@@ -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 |
|<https://github.com/modoboa/modoboa-sievefilters>`_ |editor | |
+---------------------------------------------------------+-------------------------+------------------------------------------------------+
|`modoboa-stats |Graphical statistics |https://modoboa-stats.readthedocs.io |
|<https://github.com/modoboa/modoboa-stats>`_ |(message traffic and | |
| |more) | |
+---------------------------------------------------------+-------------------------+------------------------------------------------------+
|`modoboa-webmail |A simple webmail |https://modoboa-webmail.readthedocs.io |
|<https://github.com/modoboa/modoboa-webmail>`_ | | |
+---------------------------------------------------------+-------------------------+------------------------------------------------------+
@@ -74,4 +70,3 @@ Table of contents
rest_api
contributing
contributors
+1 -1
View File
@@ -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.
+1 -1
View File
@@ -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
+16 -10
View File
@@ -5,6 +5,7 @@ from django.contrib.contenttypes.models import ContentType
from django.utils.translation import ugettext as _
from django_filters import rest_framework as dj_filters
from drf_spectacular.utils import extend_schema, extend_schema_view
from rest_framework import filters, renderers, status, viewsets
from rest_framework.decorators import action
from rest_framework.exceptions import ParseError
@@ -19,17 +20,22 @@ from modoboa.lib import viewsets as lib_viewsets
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):
"""
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
+5
View File
@@ -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
+3
View File
@@ -8,6 +8,8 @@ from django.utils.encoding import force_text
from django.utils.translation import ugettext as _, ugettext_lazy
from rest_flex_fields import FlexFieldsModelSerializer
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
@@ -193,6 +195,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
+23
View File
@@ -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")
+13
View File
@@ -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)
+26 -10
View File
@@ -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(
@@ -64,6 +64,7 @@ INSTALLED_APPS = (
'ckeditor_uploader',
'rest_framework',
'rest_framework.authtoken',
'drf_spectacular',
'phonenumber_field',
'django_otp',
'django_otp.plugins.otp_totp',
@@ -190,6 +191,14 @@ 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',
'SERVE_PERMISSIONS': ['rest_framework.permissions.IsAuthenticated'],
}
# Modoboa settings
+2 -9
View File
@@ -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")
+2 -1
View File
@@ -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):
+5
View File
@@ -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 modoboa.admin import serializers as admin_serializers
@@ -37,6 +38,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."""
@@ -66,6 +70,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."""
@@ -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 <EMAIL@ADDRESS>, YEAR.
#
#
# Translators:
# J Rosier <vertalen@tagora.nl>, 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 <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"PO-Revision-Date: 2020-05-11 18:45+0000\n"
"Last-Translator: J Rosier <vertalen@tagora.nl>, 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: {}"
@@ -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 <EMAIL@ADDRESS>, YEAR.
#
#
# Translators:
# Pedro M <zamowienia@ittf.pl>, 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 <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"PO-Revision-Date: 2020-05-11 18:45+0000\n"
"Last-Translator: Pedro M <zamowienia@ittf.pl>, 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"
@@ -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 <EMAIL@ADDRESS>, YEAR.
#
#
# Translators:
# Olle Gustafsson <olle@dalnix.se>, 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 <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"PO-Revision-Date: 2020-05-11 18:45+0000\n"
"Last-Translator: Olle Gustafsson <olle@dalnix.se>, 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: {}"
+3 -2
View File
@@ -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",
+119 -35
View File
@@ -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 <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\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 ""
+10 -2
View File
@@ -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 <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\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 ""
+261 -89
View File
@@ -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 <tonio@ngyn.org>, 2016-2017,2020
# Christophe CHAUVET <christophe.chauvet@gmail.com>, 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 <tonio@ngyn.org>\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 <a href=\"https://modoboa.org/blog/\" target=\"_blank\">official "
"weblog</a> for more information."
msgstr "Visitez le <a href=\"https://modoboa.org/blog/\" target=\"_blank\">blog officiel</a> pour plus d'information."
msgstr ""
"Visitez le <a href=\"https://modoboa.org/blog/\" target=\"_blank\">blog "
"officiel</a> 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 <strong><a href=\"%(url)s\" "
"target=\"_blank\">here</a></strong>."
msgstr "Une documentation de l'API est disponible <strong><a href=\"%(url)s\" target=\"_blank\">ici</a></strong>."
"A documentation of the API is available <strong><a href=\"%(url)s\" target="
"\"_blank\">here</a></strong>."
msgstr ""
"Une documentation de l'API est disponible <strong><a href=\"%(url)s\" target="
"\"_blank\">ici</a></strong>."
#: 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 <a href=\"%(url)s\">sign "
"in</a> now."
msgstr "Votre mot de passe a été défini. Vous pouvez continuer et vous <a href=\"%(url)s\">connecter </a> dès maintenant."
msgstr ""
"Votre mot de passe a été défini. Vous pouvez continuer et vous <a href="
"\"%(url)s\">connecter </a> 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.</p> "
"<p>If you don't receive an email, please make sure you've entered your "
"primary address, and check your spam folder.</p>"
msgstr "<p>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.</p><p>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.</p>"
msgstr ""
"<p>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.</p><p>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.</p>"
#: 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."
+14 -7
View File
@@ -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 <EMAIL@ADDRESS>, YEAR.
#
#
# Translators:
# Antoine Nguyen <tonio@ngyn.org>, 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 <tonio@ngyn.org>, 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."
+65 -64
View File
@@ -4,9 +4,10 @@
#
# Translators:
# Andrew <buddha@cryptolab.net>, 2014
# Chris de Gelder <chrisdegelder@gmail.com>, 2017
# ABC, 2017
# Fred Durst <adriaan.conijn@gmail.com>, 2019
# Harrie v.d. Vegt <hvdvegt@gmail.com>, 2016
# J Rosier <vertalen@tagora.nl>, 2020
# Peter van den Heuvel <peter@pvandenheuvel.nl>, 2017
# Remco de Hiep <remco.de.hiep@reto.nl>, 2017
# R Kloosterman <randx@zeelandnet.nl>, 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 <tonio@ngyn.org>\n"
"PO-Revision-Date: 2020-10-03 09:44+0000\n"
"Last-Translator: J Rosier <vertalen@tagora.nl>\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"
+10 -8
View File
@@ -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 <EMAIL@ADDRESS>, YEAR.
#
# Translators:
# R Kloosterman <randx@zeelandnet.nl>, 2016
# TuxBrother <vrijwilligerswerk@wij.rs>, 2014
# TuxBrother <vrijwilligerswerk@wij.rs>, 2014
# Antoine Nguyen <tonio@ngyn.org>, 2020
# J Rosier <vertalen@tagora.nl>, 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 <tonio@ngyn.org>\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 <vertalen@tagora.nl>, 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"
+10 -8
View File
@@ -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 <EMAIL@ADDRESS>, YEAR.
#
# Translators:
# sin88 <sin@sin.waw.pl>, 2016
# sin88 <sin@sin.waw.pl>, 2016
# Wojtek Gajda <vac@milowice.net>, 2018
# Antoine Nguyen <tonio@ngyn.org>, 2020
# Pedro M <zamowienia@ittf.pl>, 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 <tonio@ngyn.org>\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 <zamowienia@ittf.pl>, 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"
+106 -206
View File
@@ -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 <martin.jens.persson@gmail.com>, 2014
# Martin Persson <martin.jens.persson@gmail.com>, 2014,2017
# Olle Gustafsson <olle@dalnix.se>, 2013
# Olle Gustafsson <olle@dalnix.se>, 2013,2015-2017
# Olle Gustafsson <olle@dalnix.se>, 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 <tonio@ngyn.org>\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 <olle@dalnix.se>\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 <a href=\"https://modoboa.org/blog/\" target=\"_blank\">official "
"weblog</a> for more information."
msgstr ""
"Besök den <a href=\"https://modoboa.org/blog/\" target=\"_blank\">officiella "
"bloggen</a> för mer information."
msgstr "Besök den <a href=\"https://modoboa.org/blog/\" target=\"_blank\">officiella bloggen</a> 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 <strong><a href=\"%(url)s\" target="
"\"_blank\">here</a></strong>."
msgstr ""
"Dokumentation över API:et finns <strong><a href=\"%(url)s\" target=\"_blank"
"\">här</a></strong>."
"A documentation of the API is available <strong><a href=\"%(url)s\" "
"target=\"_blank\">here</a></strong>."
msgstr "Dokumentation över API:et finns <strong><a href=\"%(url)s\" target=\"_blank\">här</a></strong>."
#: 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 <a href=\"%(url)s\">sign "
"in</a> now."
msgstr ""
"Ditt lösenord har ändrats. Du kan fortsätta med att <a href=\"%(url)s"
"\">logga in</a>."
msgstr "Ditt lösenord har ändrats. Du kan fortsätta med att <a href=\"%(url)s\">logga in</a>."
#: 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.</p> "
"<p>If you don't receive an email, please make sure you've entered your "
"primary address, and check your spam folder.</p>"
msgstr ""
"<p>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."
"</p> <p>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.</p>"
msgstr "<p>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.</p> <p>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.</p>"
#: 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"
+10 -7
View File
@@ -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 <EMAIL@ADDRESS>, YEAR.
#
# Translators:
# Olle Gustafsson <olle@dalnix.se>, 2013
# Olle Gustafsson <olle@dalnix.se>, 2013,2015-2016
# Antoine Nguyen <tonio@ngyn.org>, 2020
# Olle Gustafsson <olle@dalnix.se>, 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 <tonio@ngyn.org>\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 <olle@dalnix.se>, 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"
@@ -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")
+2
View File
@@ -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)
-57
View File
@@ -1,57 +0,0 @@
<!DOCTYPE html>
{% load static %}
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Modoboa API</title>
<link rel="stylesheet" href="{% static 'swagger-ui/dist/swagger-ui.css' %}">
<style>
html {
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
margin: 0;
background: #fafafa;
}
.swagger-ui .highlight-code .download-contents {
right: 20px;
height: auto;
width: auto;
}
</style>
</head>
<body>
<div id="swagger-ui"></div>
<script src="{% static 'swagger-ui/dist/swagger-ui-bundle.js' %}"></script>
<script>
window.onload = function() {
const ui = SwaggerUIBundle({
url: "{% url 'openapi_schema' %}",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis
],
layout: "BaseLayout",
requestInterceptor: (request) => {
request.headers['X-CSRFToken'] = "{{ csrf_token }}"
return request;
}
});
window.ui = ui;
};
</script>
</body>
</html>
+10 -9
View File
@@ -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",
+9 -13
View File
@@ -6,11 +6,11 @@ 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 (
SpectacularJSONAPIView, SpectacularSwaggerView, SpectacularRedocView
)
from modoboa.admin.views import user as user_views
from modoboa.core import signals as core_signals, views as core_views
@@ -59,17 +59,13 @@ 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', SpectacularJSONAPIView.as_view(), name='schema'),
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", namespace="v1")),
path('api/v2/', include("modoboa.urls_api", namespace="v2")),
]
+1 -1
View File
@@ -1 +1 @@
mysqlclient<=1.4.99
mysqlclient<2.0.2
+11 -10
View File
@@ -1,25 +1,26 @@
django>=2.2,<2.3
django-braces==1.14.0
django-ckeditor==5.8.0
django-phonenumber-field[phonenumbers]==4.0.0
django-reversion==3.0.5
django-ckeditor==6.0.0
django-phonenumber-field[phonenumbers]==5.0.0
django-reversion==3.0.8
django-xforwardedfor-middleware==2.0
django-webpack-loader
django-otp==1.0.1
django-otp==1.0.2
dj-database-url
djangorestframework>=3.11,<3.12
djangorestframework>=3.11,<3.13
drf-spectacular
uritemplate
passlib==1.7.2
passlib~=1.7.4
bcrypt # Requires libffi-dev and python-dev
dnspython==1.16.0
feedparser==5.2.1
greenlet==0.4.16
gevent==1.5.0
jsonfield==2.0.2
feedparser==6.0.2
greenlet==0.4.17
gevent==20.9.0
jsonfield==3.1.0
Pillow # Optional dependency for django-ckeditor
progressbar33==2.4
py-dateutil==2.2
+6 -1
View File
@@ -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={
+2 -2
View File
@@ -1,6 +1,6 @@
argon2-cffi>=16.1.0
factory-boy<=2.12.0
httmock==1.3.0
testfixtures==6.10.3
httmock==1.4.0
testfixtures==6.15.0
tox
asynctest
+22 -4
View File
@@ -48,8 +48,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
@@ -65,6 +65,7 @@ INSTALLED_APPS = (
'ckeditor_uploader',
'rest_framework',
'rest_framework.authtoken',
'drf_spectacular',
'django_otp',
'django_otp.plugins.otp_totp',
'django_otp.plugins.otp_static',
@@ -186,6 +187,14 @@ 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',
'SERVE_PERMISSIONS': ['rest_framework.permissions.IsAuthenticated'],
}
# Modoboa settings
@@ -198,7 +207,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)
@@ -283,6 +292,9 @@ LOGGING = {
},
'modoboa': {
'class': 'modoboa.core.loggers.SQLHandler',
},
'console': {
'class': 'logging.StreamHandler'
}
},
'loggers': {
@@ -300,7 +312,11 @@ LOGGING = {
'handlers': ['modoboa'],
'level': 'INFO',
'propagate': False
}
},
# 'django_auth_ldap': {
# 'level': 'DEBUG',
# 'handlers': ['console']
# },
}
}
@@ -315,3 +331,5 @@ from modoboa.admin import settings as admin_settings # noqa
admin_settings.apply(globals())
# Load settings from extensions
LDAP_SERVER_PORT = os.environ.get('LDAP_SERVER_PORT', 3389)
+12 -5
View File
@@ -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"