diff --git a/modoboa/admin/forms/account.py b/modoboa/admin/forms/account.py index 50b2dda21..3c9686aba 100644 --- a/modoboa/admin/forms/account.py +++ b/modoboa/admin/forms/account.py @@ -334,8 +334,12 @@ class AccountFormMail(forms.Form, DynamicForm): self.mb = models.Mailbox( address=self.locpart, domain=self.domain, user=account, use_domain_quota=self.cleaned_data["quota_act"]) - self.mb.set_quota(self.cleaned_data["quota"], - user.has_perm("admin.add_domain")) + override_rules = ( + user.is_superuser or + user.has_perm("admin.add_domain") and + not user.userobjectlimit_set.get(name="quota").max_value + ) + self.mb.set_quota(self.cleaned_data["quota"], override_rules) self.mb.save(creator=user) def _update_aliases(self, user, account): diff --git a/modoboa/admin/models/mailbox.py b/modoboa/admin/models/mailbox.py index a3929a555..10bc59a9c 100644 --- a/modoboa/admin/models/mailbox.py +++ b/modoboa/admin/models/mailbox.py @@ -317,9 +317,11 @@ class Mailbox(AdminObject): raise lib_exceptions.PermDeniedException if "use_domain_quota" in values: self.use_domain_quota = values["use_domain_quota"] - override_rules = True \ - if not self.quota or user.has_perm("admin.add_domain") \ - else False + override_rules = ( + not self.quota or user.is_superuser or + user.has_perm("admin.add_domain") and + not user.userobjectlimit_set.get(name="quota").max_value + ) self.set_quota(values["quota"], override_rules) if newaddress: self.rename(local_part, domain) diff --git a/modoboa/limits/tests/test_user_limits.py b/modoboa/limits/tests/test_user_limits.py index a7ce5c33b..2d87d0a72 100644 --- a/modoboa/limits/tests/test_user_limits.py +++ b/modoboa/limits/tests/test_user_limits.py @@ -59,13 +59,15 @@ class ResourceTestCase(lib_tests.ModoTestCase): cls.localconfig.save() populate_database() - def _create_account(self, username, role='SimpleUsers', status=200): + def _create_account( + self, username, role='SimpleUsers', status=200, **kwargs): values = dict( username=username, first_name="Tester", last_name="Toto", password1="Toto1234", password2="Toto1234", role=role, quota_act=True, is_active=True, email=username, stepid='step2', ) + values.update(kwargs) return self.ajax_post( reverse("admin:account_add"), values, status ) @@ -322,8 +324,32 @@ class ResellerTestCase(ResourceTestCase): self.assertEqual( response["form_errors"]["default_mailbox_quota"][0], "You can't define an unlimited quota.") + self.user.userobjectlimit_set.filter(name="quota").update(max_value=0) - response = self._create_domain("domain1.tld", quota=0) + response = self._create_domain("domain2.tld", quota=0) + + def test_quota_propagation(self): + """Check that quota is applied everywhere.""" + # Try to assign an unlimited quota to an admin + # See https://github.com/modoboa/modoboa/issues/1223 + self._create_domain("domain1.tld") + self._create_account( + "admin@domain1.tld", role="DomainAdmins", + quota_act=False, quota=0, status=400) + + self._create_domain("domain2.tld", withtpl=True) + admin = User.objects.get(username="admin@domain2.tld") + values = { + "username": admin.username, "role": admin.role, + "is_active": admin.is_active, "email": admin.email, + "mailboxes_limit": 1, "mailbox_aliases_limit": 2, + "language": "en", "quota_act": False, "quota": 0 + } + self.ajax_post( + reverse("admin:account_change", args=[admin.pk]), + values, + 400 + ) def test_reseller_deletes_domain(self): """Check if all resources are restored after the deletion."""