@@ -41,6 +60,7 @@
-
diff --git a/frontend/src/components/tools/ChoiceField.vue b/frontend/src/components/tools/ChoiceField.vue
index b37d96e24..00f6457f3 100644
--- a/frontend/src/components/tools/ChoiceField.vue
+++ b/frontend/src/components/tools/ChoiceField.vue
@@ -5,7 +5,7 @@
{{ choice.icon }}
{{ choice.label }}
@@ -16,20 +16,39 @@
@@ -44,5 +63,9 @@ export default {
&--selected {
border-color: #046BF8 !important;
}
+
+ &--disabled {
+ cursor: unset;
+ }
}
diff --git a/frontend/src/filters/index.js b/frontend/src/filters/index.js
new file mode 100644
index 000000000..108b12c48
--- /dev/null
+++ b/frontend/src/filters/index.js
@@ -0,0 +1,7 @@
+import Vue from 'vue'
+import { translate } from 'vue-gettext'
+const { gettext: $gettext } = translate
+
+Vue.filter('yesno', function (value) {
+ return (value) ? $gettext('yes') : $gettext('no')
+})
diff --git a/frontend/src/main.js b/frontend/src/main.js
index ed0d8331c..2217a53b7 100644
--- a/frontend/src/main.js
+++ b/frontend/src/main.js
@@ -3,6 +3,7 @@ import './plugins/axios'
import './plugins/vee-validate'
import './plugins/vue-cookie'
import './plugins/vue-gettext'
+import './filters'
import App from './App.vue'
import router from './router'
import store from './store'
@@ -10,6 +11,8 @@ import vuetify from './plugins/vuetify'
Vue.config.productionTip = false
+export const bus = new Vue()
+
new Vue({
router,
store,
diff --git a/frontend/src/views/Domains.vue b/frontend/src/views/Domains.vue
index 712ab76fd..f80d0ce3b 100644
--- a/frontend/src/views/Domains.vue
+++ b/frontend/src/views/Domains.vue
@@ -30,6 +30,7 @@
diff --git a/modoboa/admin/api.py b/modoboa/admin/api.py
index 29c4845de..c3877ffc0 100644
--- a/modoboa/admin/api.py
+++ b/modoboa/admin/api.py
@@ -38,12 +38,16 @@ class DomainViewSet(viewsets.ModelViewSet):
"""Domain viewset."""
permission_classes = [IsAuthenticated, DjangoModelPermissions, ]
- serializer_class = serializers.DomainSerializer
def get_queryset(self):
"""Filter queryset based on current user."""
return models.Domain.objects.get_for_admin(self.request.user)
+ def get_serializer_class(self, *args, **kwargs):
+ if self.request.version == "v2" and self.action == "create":
+ return serializers.DomainSerializerV2
+ return serializers.DomainSerializer
+
def perform_destroy(self, instance):
"""Add custom args to delete call."""
instance.delete(self.request.user)
diff --git a/modoboa/admin/serializers.py b/modoboa/admin/serializers.py
index e78b0f82e..9deeeb0b6 100644
--- a/modoboa/admin/serializers.py
+++ b/modoboa/admin/serializers.py
@@ -110,6 +110,85 @@ class DomainSerializer(serializers.ModelSerializer):
return domain
+class CreateDomainAdminSerializer(serializers.Serializer):
+ """Sub serializer for domain administrator creation."""
+
+ username = serializers.CharField()
+ with_random_password = serializers.BooleanField(default=False)
+ with_mailbox = serializers.BooleanField(default=False)
+ with_aliases = serializers.BooleanField(default=False)
+
+
+class DomainSerializerV2(DomainSerializer):
+ """Domain serializer for v2 API."""
+
+ domain_admin = CreateDomainAdminSerializer(required=False)
+
+ class Meta(DomainSerializer.Meta):
+ fields = DomainSerializer.Meta.fields + (
+ "domain_admin",
+ )
+
+ def create(self, validated_data):
+ """Create administrator and other stuff if needed."""
+ domain_admin = validated_data.pop("domain_admin", None)
+ domain = super().create(validated_data)
+ if not domain_admin:
+ return domain
+
+ # 1. Create a domain administrator
+ username = "%s@%s" % (domain_admin["username"], domain.name)
+ try:
+ da = core_models.User.objects.get(username=username)
+ except core_models.User.DoesNotExist:
+ pass
+ else:
+ raise lib_exceptions.Conflict(
+ _("User '%s' already exists") % username)
+ user = self.context["request"].user
+ core_signals.can_create_object.send(
+ self.__class__, context=user, klass=models.Mailbox)
+ da = core_models.User(username=username, email=username, is_active=True)
+ if domain_admin["with_random_password"]:
+ password = lib.make_password()
+ else:
+ password = param_tools.get_global_parameter(
+ "default_password", app="core")
+ da.set_password(password)
+ da.save()
+ da.role = "DomainAdmins"
+ da.post_create(user)
+
+ # 2. Create mailbox if needed
+ if domain_admin["with_mailbox"]:
+ dom_admin_username = domain_admin["username"]
+ mb = models.Mailbox(
+ address=dom_admin_username, domain=domain,
+ user=da, use_domain_quota=True
+ )
+ mb.set_quota(
+ override_rules=user.has_perm("admin.change_domain"))
+ mb.save(creator=user)
+
+ # 3. Create aliases if needed
+ condition = (
+ domain.type == "domain" and
+ domain_admin["with_aliases"] and
+ dom_admin_username != "postmaster"
+ )
+ if condition:
+ core_signals.can_create_object.send(
+ self.__class__, context=user, klass=models.Alias)
+ address = u"postmaster@{}".format(domain.name)
+ alias = models.Alias.objects.create(
+ address=address, domain=domain, enabled=True)
+ alias.set_recipients([mb.full_address])
+ alias.post_create(user)
+
+ domain.add_admin(da)
+ return domain
+
+
class DomainAliasSerializer(FlexFieldsModelSerializer):
"""Base DomainAlias serializer."""