From d3e45962a27e2edd5dde560e588672a5686e1d8a Mon Sep 17 00:00:00 2001 From: Spitap Date: Tue, 13 Jun 2023 19:27:27 +0200 Subject: [PATCH 1/7] Fixed disabling message_limit --- modoboa/admin/api/v1/serializers.py | 15 +++++++++-- modoboa/admin/api/v2/serializers.py | 13 ++++++++- modoboa/admin/api/v2/tests.py | 42 +++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 3 deletions(-) diff --git a/modoboa/admin/api/v1/serializers.py b/modoboa/admin/api/v1/serializers.py index 545028bdf..418630a51 100644 --- a/modoboa/admin/api/v1/serializers.py +++ b/modoboa/admin/api/v1/serializers.py @@ -152,11 +152,14 @@ class MailboxSerializer(serializers.ModelSerializer): quota = serializers.CharField(required=False) quota_usage = serializers.SerializerMethodField() + message_limit = serializers.CharField( + required=False, allow_null=True, allow_blank=True) + class Meta: model = models.Mailbox fields = ( - "pk", "full_address", "use_domain_quota", "quota", "message_limit", - "quota_usage" + "pk", "full_address", "use_domain_quota", "quota", + "quota_usage", "message_limit" ) def get_quota_usage(self, mb) -> int: @@ -166,6 +169,14 @@ class MailboxSerializer(serializers.ModelSerializer): """Lower case address.""" return value.lower() + def validate_message_limit(self, value): + if not value: + return None + try: + return int(value) + except ValueError: + raise ValidationError(_("A valid integer is required.")) + def validate_quota(self, value): """Convert quota to MB.""" return web_utils.size2integer(value, output_unit="MB") diff --git a/modoboa/admin/api/v2/serializers.py b/modoboa/admin/api/v2/serializers.py index c4f12b446..6306663ed 100644 --- a/modoboa/admin/api/v2/serializers.py +++ b/modoboa/admin/api/v2/serializers.py @@ -389,16 +389,27 @@ class MailboxSerializer(serializers.ModelSerializer): quota = serializers.CharField(required=False) + message_limit = serializers.CharField( + required=False, allow_null=True, allow_blank=True) + class Meta: model = models.Mailbox fields = ( - "pk", "use_domain_quota", "quota", "message_limit", + "pk", "use_domain_quota", "quota", "message_limit" ) def validate_quota(self, value): """Convert quota to MB.""" return web_utils.size2integer(value, output_unit="MB") + def validate_message_limit(self, value): + if not value: + return None + try: + return int(value) + except ValueError: + raise ValidationError(_("A valid integer is required.")) + def validate(self, data): """Check if quota is required.""" method = self.context["request"].method diff --git a/modoboa/admin/api/v2/tests.py b/modoboa/admin/api/v2/tests.py index fcea7e95b..d71c9b53a 100644 --- a/modoboa/admin/api/v2/tests.py +++ b/modoboa/admin/api/v2/tests.py @@ -258,6 +258,48 @@ class AccountViewSetTestCase(ModoAPITestCase): resp = self.client.patch(url, data, format="json") self.assertEqual(resp.status_code, 200) + def test_message_limit_update(self): + account = core_models.User.objects.get(username="user@test.com") + url = reverse("v2:account-detail", args=[account.pk]) + data = { + "username": "user@test.com", + "role": "SimpleUsers", + "password": "Toto12345", + "mailbox": { + "message_limit": 10 + } + } + resp = self.client.patch(url, data, format="json") + self.assertEqual(resp.status_code, 200) + account.refresh_from_db() + self.assertEqual(account.mailbox.message_limit, 10) + + data = { + "username": "user@test.com", + "role": "SimpleUsers", + "password": "Toto12345", + "mailbox": { + "quota": 10 + } + } + resp = self.client.patch(url, data, format="json") + self.assertEqual(resp.status_code, 200) + account.refresh_from_db() + self.assertEqual(account.mailbox.message_limit, 10) + + data = { + "username": "user@test.com", + "role": "SimpleUsers", + "password": "Toto12345", + "mailbox": { + "message_limit": "" + } + } + resp = self.client.patch(url, data, format="json") + self.assertEqual(resp.status_code, 200) + account.refresh_from_db() + self.assertEqual(account.mailbox.message_limit, None) + def test_update_admin(self): account = core_models.User.objects.get(username="admin") url = reverse("v2:account-detail", args=[account.pk]) From 802d217a78bd1cd977e06418bc8ae986b888c91a Mon Sep 17 00:00:00 2001 From: Spitap Date: Tue, 13 Jun 2023 20:45:50 +0200 Subject: [PATCH 2/7] Fixed empty string on message limit --- modoboa/admin/api/v2/serializers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modoboa/admin/api/v2/serializers.py b/modoboa/admin/api/v2/serializers.py index 6306663ed..cd256e4e4 100644 --- a/modoboa/admin/api/v2/serializers.py +++ b/modoboa/admin/api/v2/serializers.py @@ -403,7 +403,7 @@ class MailboxSerializer(serializers.ModelSerializer): return web_utils.size2integer(value, output_unit="MB") def validate_message_limit(self, value): - if not value: + if value == "": return None try: return int(value) From 9c77c74c7a236bca341d9c1847d579b23a8ee405 Mon Sep 17 00:00:00 2001 From: Spitap Date: Wed, 14 Jun 2023 10:37:42 +0200 Subject: [PATCH 3/7] Fixed mailbox model update --- modoboa/admin/models/mailbox.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modoboa/admin/models/mailbox.py b/modoboa/admin/models/mailbox.py index fd2612ab1..f4159933f 100644 --- a/modoboa/admin/models/mailbox.py +++ b/modoboa/admin/models/mailbox.py @@ -322,7 +322,8 @@ class Mailbox(mixins.MessageLimitMixin, AdminObject): not user.userobjectlimit_set.get(name="quota").max_value ) self.set_quota(values["quota"], override_rules) - self.message_limit = values.get("message_limit") + if values.get("message_limit", "absent") != "absent": + self.message_limit = values["message_limit"] if newaddress: self.rename(local_part, domain) self.save() From bd862ec1f137cc361dbbc608feb870ffd926c291 Mon Sep 17 00:00:00 2001 From: Spitap Date: Wed, 14 Jun 2023 12:06:39 +0200 Subject: [PATCH 4/7] Added redis on docker, simplified changes to message_limit --- docker-compose.yml | 3 ++- .../identities/AccountMailboxForm.vue | 27 ++++++++++++------- modoboa/admin/api/v1/serializers.py | 11 -------- modoboa/admin/api/v2/serializers.py | 11 -------- 4 files changed, 20 insertions(+), 32 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 7de4e402e..d7c306b7c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -34,7 +34,8 @@ services: DEBUG: "True" REDIS_HOST: redis command: > - sh -c "cd test_project + sh -c "redis-server & + cd test_project python3 manage.py migrate python3 manage.py load_initial_data django-admin compilemessages diff --git a/frontend/src/components/identities/AccountMailboxForm.vue b/frontend/src/components/identities/AccountMailboxForm.vue index 06fd0a8db..6e69a0347 100644 --- a/frontend/src/components/identities/AccountMailboxForm.vue +++ b/frontend/src/components/identities/AccountMailboxForm.vue @@ -24,15 +24,21 @@ /> - + + + @@ -94,6 +100,9 @@ export default { if (this.form.role === 'SimpleUsers') { this.$set(this.form.mailbox, 'full_address', this.form.username) } + if (newValue.mailbox.message_limit === '') { + this.form.mailbox.message_limit = null + } }, deep: true } diff --git a/modoboa/admin/api/v1/serializers.py b/modoboa/admin/api/v1/serializers.py index 418630a51..d735455df 100644 --- a/modoboa/admin/api/v1/serializers.py +++ b/modoboa/admin/api/v1/serializers.py @@ -152,9 +152,6 @@ class MailboxSerializer(serializers.ModelSerializer): quota = serializers.CharField(required=False) quota_usage = serializers.SerializerMethodField() - message_limit = serializers.CharField( - required=False, allow_null=True, allow_blank=True) - class Meta: model = models.Mailbox fields = ( @@ -169,14 +166,6 @@ class MailboxSerializer(serializers.ModelSerializer): """Lower case address.""" return value.lower() - def validate_message_limit(self, value): - if not value: - return None - try: - return int(value) - except ValueError: - raise ValidationError(_("A valid integer is required.")) - def validate_quota(self, value): """Convert quota to MB.""" return web_utils.size2integer(value, output_unit="MB") diff --git a/modoboa/admin/api/v2/serializers.py b/modoboa/admin/api/v2/serializers.py index cd256e4e4..4e0cec594 100644 --- a/modoboa/admin/api/v2/serializers.py +++ b/modoboa/admin/api/v2/serializers.py @@ -389,9 +389,6 @@ class MailboxSerializer(serializers.ModelSerializer): quota = serializers.CharField(required=False) - message_limit = serializers.CharField( - required=False, allow_null=True, allow_blank=True) - class Meta: model = models.Mailbox fields = ( @@ -402,14 +399,6 @@ class MailboxSerializer(serializers.ModelSerializer): """Convert quota to MB.""" return web_utils.size2integer(value, output_unit="MB") - def validate_message_limit(self, value): - if value == "": - return None - try: - return int(value) - except ValueError: - raise ValidationError(_("A valid integer is required.")) - def validate(self, data): """Check if quota is required.""" method = self.context["request"].method From cc6194c3420c59ca954bc6a66a15c653241a8797 Mon Sep 17 00:00:00 2001 From: Spitap Date: Wed, 14 Jun 2023 12:13:40 +0200 Subject: [PATCH 5/7] Fixed test --- modoboa/admin/api/v2/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modoboa/admin/api/v2/tests.py b/modoboa/admin/api/v2/tests.py index d71c9b53a..819d68378 100644 --- a/modoboa/admin/api/v2/tests.py +++ b/modoboa/admin/api/v2/tests.py @@ -292,7 +292,7 @@ class AccountViewSetTestCase(ModoAPITestCase): "role": "SimpleUsers", "password": "Toto12345", "mailbox": { - "message_limit": "" + "message_limit": None } } resp = self.client.patch(url, data, format="json") From 748a61472bb979cb6afdae0a3b84d632040b6e1b Mon Sep 17 00:00:00 2001 From: Spitap Date: Mon, 19 Jun 2023 14:44:43 +0200 Subject: [PATCH 6/7] few fixes --- .gitignore | 1 + docker-compose.yml | 9 +++++++-- modoboa/admin/api/v1/serializers.py | 4 ++-- modoboa/admin/api/v2/serializers.py | 2 +- modoboa/admin/models/mailbox.py | 2 +- 5 files changed, 12 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index fbe718e92..a67024e4d 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ node_modules # TOX stuff test_project/modoboa.db +test_project/redis /.project /.pydevproject diff --git a/docker-compose.yml b/docker-compose.yml index d7c306b7c..08f81b488 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -33,15 +33,17 @@ services: DB: "SQLITE" DEBUG: "True" REDIS_HOST: redis + REDIS_PORT: 6379 command: > - sh -c "redis-server & - cd test_project + sh -c "cd test_project python3 manage.py migrate python3 manage.py load_initial_data django-admin compilemessages python3 manage.py runserver 0:8000" volumes: - .:/code + depends_on: + - redis front: container_name: modoboa_front @@ -58,3 +60,6 @@ services: DOCKER: "yes" depends_on: - api + +volumes: + redis-cache: diff --git a/modoboa/admin/api/v1/serializers.py b/modoboa/admin/api/v1/serializers.py index d735455df..545028bdf 100644 --- a/modoboa/admin/api/v1/serializers.py +++ b/modoboa/admin/api/v1/serializers.py @@ -155,8 +155,8 @@ class MailboxSerializer(serializers.ModelSerializer): class Meta: model = models.Mailbox fields = ( - "pk", "full_address", "use_domain_quota", "quota", - "quota_usage", "message_limit" + "pk", "full_address", "use_domain_quota", "quota", "message_limit", + "quota_usage" ) def get_quota_usage(self, mb) -> int: diff --git a/modoboa/admin/api/v2/serializers.py b/modoboa/admin/api/v2/serializers.py index 4e0cec594..c4f12b446 100644 --- a/modoboa/admin/api/v2/serializers.py +++ b/modoboa/admin/api/v2/serializers.py @@ -392,7 +392,7 @@ class MailboxSerializer(serializers.ModelSerializer): class Meta: model = models.Mailbox fields = ( - "pk", "use_domain_quota", "quota", "message_limit" + "pk", "use_domain_quota", "quota", "message_limit", ) def validate_quota(self, value): diff --git a/modoboa/admin/models/mailbox.py b/modoboa/admin/models/mailbox.py index f4159933f..25075b03e 100644 --- a/modoboa/admin/models/mailbox.py +++ b/modoboa/admin/models/mailbox.py @@ -322,7 +322,7 @@ class Mailbox(mixins.MessageLimitMixin, AdminObject): not user.userobjectlimit_set.get(name="quota").max_value ) self.set_quota(values["quota"], override_rules) - if values.get("message_limit", "absent") != "absent": + if "message_limit" in values: self.message_limit = values["message_limit"] if newaddress: self.rename(local_part, domain) From fc9f8250e499749fe9a4ea994e825e174fad14f8 Mon Sep 17 00:00:00 2001 From: Spitap Date: Tue, 27 Jun 2023 17:04:39 +0200 Subject: [PATCH 7/7] Rebased branch --- .gitignore | 1 - docker-compose.yml | 8 +------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index a67024e4d..fbe718e92 100644 --- a/.gitignore +++ b/.gitignore @@ -26,7 +26,6 @@ node_modules # TOX stuff test_project/modoboa.db -test_project/redis /.project /.pydevproject diff --git a/docker-compose.yml b/docker-compose.yml index 08f81b488..7de4e402e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -33,17 +33,14 @@ services: DB: "SQLITE" DEBUG: "True" REDIS_HOST: redis - REDIS_PORT: 6379 command: > - sh -c "cd test_project + sh -c "cd test_project python3 manage.py migrate python3 manage.py load_initial_data django-admin compilemessages python3 manage.py runserver 0:8000" volumes: - .:/code - depends_on: - - redis front: container_name: modoboa_front @@ -60,6 +57,3 @@ services: DOCKER: "yes" depends_on: - api - -volumes: - redis-cache: