All parameters are migrated.

This commit is contained in:
Antoine Nguyen
2018-10-05 14:06:59 +02:00
parent 865c9226c1
commit 6d17cb4f30
9 changed files with 371 additions and 39 deletions
@@ -18,18 +18,11 @@
>
<v-card>
<v-card-text>
<v-text-field v-for="(param, index) in element.parameters"
:label="param.label"
:key="index"
:hint="param.help_text"
v-model="parameters[param.name]"
:error="formErrors[param.name] !== undefined"
:error-messages="formErrors[param.name]"
v-if="(param.widget === 'CharField' || param.widget === 'IntegerField') && display(param)">
</v-text-field>
<v-checkbox :label="param.label"
<v-checkbox v-for="(param, index) in element.parameters"
:key="index"
:label="param.label"
v-model="parameters[param.name]"
v-else-if="param.widget === 'BooleanField' && display(param)"
v-if="param.widget === 'BooleanField' && display(param)"
>
</v-checkbox>
<v-select :label="param.label"
@@ -37,6 +30,15 @@
:items="param.choices"
v-else-if="param.widget === 'ChoiceField' && display(param)">
</v-select>
<v-text-field
:label="param.label"
:hint="param.help_text"
v-model="parameters[param.name]"
:error="formErrors[param.name] !== undefined"
:error-messages="formErrors[param.name]"
v-else-if="display(param)"
>
</v-text-field>
</v-card-text>
</v-card>
</v-tab-item>
@@ -69,20 +71,30 @@ export default {
}
},
created () {
var app = this.$route.params.app
api.getParametersStructure(app).then(response => {
this.structure = response.data
})
api.getParametersForApplication(app).then(response => {
this.parameters = response.data
})
this.loadParams(this.$route.params.app)
},
watch: {
'$route' (to, from) {
this.loadParams(to.params.app)
}
},
methods: {
loadParams (app) {
api.getParametersStructure(app).then(response => {
this.structure = response.data
})
api.getParametersForApplication(app).then(response => {
this.parameters = response.data
})
},
display (element) {
if (element.display === '') {
return true
}
var [field, value] = element.display.split('=')
if (value === 'true' || value === 'false') {
value = Boolean(value)
}
return this.parameters[field] === value
},
save () {
+114
View File
@@ -4,6 +4,7 @@
from __future__ import unicode_literals
import collections
import os
from django import forms
@@ -14,6 +15,7 @@ from django.utils.translation import ugettext as _, ugettext_lazy
from modoboa.lib.form_utils import SeparatorField, YesNoField
from modoboa.lib.sysutils import exec_cmd
from modoboa.parameters import forms as param_forms
from . import constants
@@ -227,9 +229,121 @@ class AdminParametersForm(param_forms.AdminParametersForm):
return cleaned_data
GLOBAL_PARAMETERS_STRUCT = collections.OrderedDict([
("domains", {
"label": ugettext_lazy("Domains"),
"params": collections.OrderedDict([
("enable_mx_checks", {
"label": ugettext_lazy("Enable MX checks"),
"help_text": ugettext_lazy(
"Check that every domain has a valid MX record"
)
}),
("valid_mxs", {
"label": ugettext_lazy("Valid MXs"),
"display": "enable_mx_checks=true",
"help_text": ugettext_lazy(
"A list of IP or network address every MX record should "
"match. A warning will be sent if a record does not "
"respect it."
),
}),
("domains_must_have_authorized_mx", {
"label": ugettext_lazy("New domains must use authorized MX(s)"),
"display": "enable_mx_checks=true",
"help_text": ugettext_lazy(
"Prevent the creation of a new domain if its MX record "
"does not use one of the defined addresses."
)
}),
("enable_dnsbl_checks", {
"label": ugettext_lazy("Enable DNSBL checks"),
"help_text": ugettext_lazy(
"Check every domain against major DNSBL providers"
)
}),
("dkim_keys_storage_dir", {
"label": ugettext_lazy("DKIM keys storage directory"),
"help_text": ugettext_lazy(
"Absolute path of the directory where DKIM private keys "
"will be stored. Make sure this directory belongs to root "
"user and is not readable by the outside world."
),
}),
("dkim_default_key_length", {
"label": ugettext_lazy("Default DKIM key length"),
"help_text": ugettext_lazy(
"Default length in bits for newly generated DKIM keys."
)
}),
])
}),
("mailboxes", {
"label": ugettext_lazy("Mailboxes"),
"params": collections.OrderedDict([
("handle_mailboxes", {
"label": ugettext_lazy("Handle mailboxes on filesystem"),
"help_text": ugettext_lazy(
"Rename or remove mailboxes on the filesystem when they get"
" renamed or removed within Modoboa"
)
}),
("mailboxes_owner", {
"label": ugettext_lazy("Mailboxes owner"),
"display": "handle_mailboxes=true",
"help_text": ugettext_lazy(
"The UNIX account who owns mailboxes on the filesystem"
)
}),
("default_domain_quota", {
"label": ugettext_lazy("Default domain quota"),
"help_text": ugettext_lazy(
"Default quota (in MB) applied to freshly created domains "
"with no value specified. A value of 0 means no quota."
)
}),
("default_mailbox_quota", {
"label": ugettext_lazy("Default mailbox quota"),
"help_text": ugettext_lazy(
"Default mailbox quota (in MB) applied to freshly created "
"domains with no value specified. A value of 0 means no "
"quota."
)
}),
("auto_account_removal", {
"label": ugettext_lazy("Automatic account removal"),
"help_text": ugettext_lazy(
"When a mailbox is removed, also remove the associated "
"account")
}),
("auto_create_domain_and_mailbox", {
"label": ugettext_lazy("Automatic domain/mailbox creation"),
"help_text": ugettext_lazy(
"Create a domain and a mailbox when an account is "
"automatically created."
)
}),
("create_alias_on_mbox_rename", {
"label": ugettext_lazy(
"Create an alias when a mailbox is renamed"),
"help_text": ugettext_lazy(
"Create an alias using the old address when a mailbox is "
"renamed."
)
})
])
}),
])
def load_admin_settings():
"""Load admin settings."""
from modoboa.parameters import tools as param_tools
from . import serializers
param_tools.registry.add(
"global", AdminParametersForm, ugettext_lazy("Administration"))
param_tools.registry.add2(
"global", "admin", ugettext_lazy("Administration"),
GLOBAL_PARAMETERS_STRUCT,
serializers.AdminGlobalParametersSerializer)
+24 -1
View File
@@ -22,7 +22,8 @@ from modoboa.lib import (
permissions
)
from modoboa.parameters import tools as param_tools
from . import lib, models
from . import constants, lib, models
class DomainSerializer(serializers.ModelSerializer):
@@ -443,3 +444,25 @@ class SenderAddressSerializer(serializers.ModelSerializer):
raise serializers.ValidationError(
_("You don't have access to this mailbox."))
return value
class AdminGlobalParametersSerializer(serializers.Serializer):
"""A serializer for global parameters."""
# Domain settings
enable_mx_checks = serializers.BooleanField(default=True)
valid_mxs = serializers.CharField(allow_blank=True)
domains_must_have_authorized_mx = serializers.BooleanField(default=False)
enable_dnsbl_checks = serializers.BooleanField(default=True)
dkim_keys_storage_dir = serializers.CharField(allow_blank=True)
dkim_default_key_length = serializers.ChoiceField(
default=2048, choices=constants.DKIM_KEY_LENGTHS)
# Mailboxes settings
handle_mailboxes = serializers.BooleanField(default=False)
mailboxes_owner = serializers.CharField(default="vmail")
default_domain_quota = serializers.IntegerField(default=0)
default_mailbox_quota = serializers.IntegerField(default=0)
auto_account_removal = serializers.BooleanField(default=False)
auto_create_domain_and_mailbox = serializers.BooleanField(default=True)
create_alias_on_mbox_rename = serializers.BooleanField(default=False)
+67
View File
@@ -595,4 +595,71 @@ GLOBAL_PARAMETERS_STRUCT = collections.OrderedDict([
}),
])
}),
("notifications", {
"label": ugettext_lazy("Notifications"),
"params": collections.OrderedDict([
("sender_address", {
"label": ugettext_lazy("Sender address"),
"help_text": ugettext_lazy(
"Email address used to send notifications.")
})
])
}),
("api", {
"label": ugettext_lazy("Public API"),
"params": collections.OrderedDict([
("enable_api_communication", {
"label": ugettext_lazy("Enable communication"),
"help_text": ugettext_lazy(
"Automatically checks if a newer version is available")
}),
("check_new_versions", {
"label": ugettext_lazy("Check new versions"),
"display": "enable_api_communication=true",
"help_text": ugettext_lazy(
"Automatically checks if a newer version is available")
}),
("send_statistics", {
"label": ugettext_lazy("Send statistics"),
"display": "enable_api_communication=true",
"help_text": ugettext_lazy(
"Send statistics to Modoboa public API "
"(counters and used extensions)")
})
])
}),
("misc", {
"label": ugettext_lazy("Miscellaneous"),
"params": collections.OrderedDict([
("inactive_account_threshold", {
"label": ugettext_lazy("Inactive account threshold"),
"help_text": ugettext_lazy(
"An account with a last login date greater than this "
"threshold (in days) will be considered as inactive"
)
}),
("top_notifications_check_interval", {
"label": ugettext_lazy("Top notifications check interval"),
"help_text": ugettext_lazy(
"Interval between two top notification checks (in seconds)"
),
}),
("log_maximum_age", {
"label": ugettext_lazy("Maximum log record age"),
"help_text": ugettext_lazy(
"The maximum age in days of a log record"),
}),
("items_per_page", {
"label": ugettext_lazy("Items per page"),
"help_text": ugettext_lazy("Number of displayed items per page")
}),
("default_top_redirection", {
"label": ugettext_lazy("Default top redirection"),
"help_text": ugettext_lazy(
"The default redirection used when no application is "
"specified"
),
})
])
})
])
+108
View File
@@ -4,6 +4,8 @@
from __future__ import unicode_literals
import collections
from django import forms
from django.utils.translation import ugettext_lazy as _
@@ -149,3 +151,109 @@ class ParametersForm(param_forms.AdminParametersForm):
"deflt_domain_domain_aliases_limit": "enable_domain_limits=True",
"deflt_domain_domain_admins_limit": "enable_domain_limits=True",
}
GLOBAL_PARAMETERS_STRUCT = collections.OrderedDict([
("per_admin_limits", {
"label": _("Default per-admin limits"),
"params": collections.OrderedDict([
("enable_admin_limits", {
"label": _("Enable per-admin limits"),
"help_text": _("Enable or disable per-admin limits")
}),
("deflt_user_domain_admins_limit", {
"label": _("Domain admins"),
"display": "enable_admin_limits=true",
"help_text": _(
"Maximum number of allowed domain administrators for a new "
"administrator. (0 to deny any creation, -1 to allow "
"unlimited creations)"
),
}),
("deflt_user_domains_limit", {
"label": _("Domains"),
"display": "enable_admin_limits=true",
"help_text": _(
"Maximum number of allowed domains for a new administrator."
" (0 to deny any creation, -1 to allow unlimited creations)"
),
}),
("deflt_user_domain_aliases_limit", {
"label": _("Domain aliases"),
"display": "enable_admin_limits=true",
"help_text": _(
"Maximum number of allowed domain aliases for a new "
"administrator. (0 to deny any creation, -1 to allow "
"unlimited creations)"
),
}),
("deflt_user_mailboxes_limit", {
"label": _("Mailboxes"),
"display": "enable_admin_limits=true",
"help_text": _(
"Maximum number of allowed mailboxes for a new "
"administrator. (0 to deny any creation, -1 to allow "
"unlimited creations)"
),
}),
("deflt_user_mailbox_aliases_limit", {
"label": _("Mailbox aliases"),
"display": "enable_admin_limits=true",
"help_text": _(
"Maximum number of allowed aliases for a new administrator."
" (0 to deny any creation, -1 to allow unlimited creations)"
),
}),
("deflt_user_quota_limit", {
"label": _("Quota"),
"help_text": _(
"The quota a reseller will be allowed to share between the "
"domains he creates. (0 means no quota)"
),
})
])
}),
("per_domain_limits", {
"label": _("Default per-domain limits"),
"params": collections.OrderedDict([
("enable_domain_limits", {
"label": _("Enable per-domain limits"),
"help_text": _("Enable or disable per-domain limits")
}),
("deflt_domain_domain_admins_limit", {
"label": _("Domain admins"),
"display": "enable_domain_limits=true",
"help_text": _(
"Maximum number of allowed domain administrators for a new "
"domain. (0 to deny any creation, -1 to allow unlimited "
"creations)"
),
}),
("deflt_domain_domain_aliases_limit", {
"label": _("Domain aliases"),
"display": "enable_domain_limits=true",
"help_text": _(
"Maximum number of allowed domain aliases for a new "
"domain. (0 to deny any creation, -1 to allow "
"unlimited creations)"
),
}),
("deflt_domain_mailboxes_limit", {
"label": _("Mailboxes"),
"display": "enable_domain_limits=true",
"help_text": _(
"Maximum number of allowed mailboxes for a new domain. "
"(0 to deny any creation, -1 to allow unlimited creations)"
),
}),
("deflt_domain_mailbox_aliases_limit", {
"label": _("Mailbox aliases"),
"display": "enable_domain_limits=true",
"help_text": _(
"Maximum number of allowed aliases for a new domain. "
"(0 to deny any creation, -1 to allow unlimited creations)"
),
})
])
})
])
+7 -2
View File
@@ -11,9 +11,14 @@ from django.utils.translation import ugettext as _
def load_limits_settings():
"""Load settings."""
from modoboa.parameters import tools as param_tools
from .app_settings import ParametersForm
from . import app_settings
from . import serializers
param_tools.registry.add("global", ParametersForm, _("Limits"))
param_tools.registry.add("global", app_settings.ParametersForm, _("Limits"))
param_tools.registry.add2(
"global", "limits", _("Limits"), app_settings.GLOBAL_PARAMETERS_STRUCT,
serializers.LimitsGlobalParemetersSerializer
)
class LimitsConfig(AppConfig):
+20
View File
@@ -36,3 +36,23 @@ class ResourcesSerializer(serializers.Serializer):
limit.max_value = max_value
limit.save(update_fields=["max_value"])
return instance
class LimitsGlobalParemetersSerializer(serializers.Serializer):
"""A serializer for global parameters."""
# Per-admin limits
enable_admin_limits = serializers.BooleanField(default=True)
deflt_user_domain_admins_limit = serializers.IntegerField(default=0)
deflt_user_domains_limit = serializers.IntegerField(default=0)
deflt_user_domain_aliases_limit = serializers.IntegerField(default=0)
deflt_user_mailboxes_limit = serializers.IntegerField(default=0)
deflt_user_mailbox_aliases_limit = serializers.IntegerField(default=0)
deflt_user_quota_limit = serializers.IntegerField(default=0)
# Per-domain limits
enable_domain_limits = serializers.BooleanField(default=False)
deflt_domain_domain_admins_limit = serializers.IntegerField(default=0)
deflt_domain_domain_aliases_limit = serializers.IntegerField(default=0)
deflt_domain_mailboxes_limit = serializers.IntegerField(default=0)
deflt_domain_mailbox_aliases_limit = serializers.IntegerField(default=0)
-17
View File
@@ -1,17 +0,0 @@
"""Parameters serializers."""
from rest_framework import serializers
from . import tools
class ParametersSerializer(serializers.Serializer):
"""Parameters serializer."""
def __init__(self, *args, **kwargs):
"""Generate serializer."""
app = kwargs.pop("app")
super(ParametersSerializer, self).__init__(*args, **kwargs)
for name, field in tools.registry.get_fields("global", app):
field.source = None
self.fields[name] = field
+1 -1
View File
@@ -28,7 +28,7 @@ urlpatterns = [
name="ckeditor_browse"),
url("", include("modoboa.core.urls", namespace="core")),
url("^user/forward/", forward, name="user_forward"),
url("admin/", include("modoboa.admin.urls", namespace="admin")),
url("^admin/", include("modoboa.admin.urls", namespace="admin")),
# No namespace
url(r'^accounts/password_reset/$', core_views.password_reset,
name="password_reset"),