diff --git a/modoboa/admin/forms.py b/modoboa/admin/forms.py index d9dbd52c5..033f5d14e 100644 --- a/modoboa/admin/forms.py +++ b/modoboa/admin/forms.py @@ -84,6 +84,7 @@ class DomainFormGeneral(forms.ModelForm, DynamicForm): q.save() old_mail_homes = dict((mb.id, mb.mail_home) for mb in d.mailbox_set.all()) d.save() + Mailbox.objects.filter(domain=d, use_domain_quota=True).update(quota=d.quota) if old_mail_homes is not None: for mb in d.mailbox_set.all(): mb.rename_dir(old_mail_homes[mb.id]) @@ -511,9 +512,10 @@ class AccountFormMail(forms.Form, DynamicForm): quota = forms.IntegerField( label=ugettext_lazy("Quota"), required=False, - help_text=_("Quota in MB for this mailbox. Leave empty to use the value defined at domain level."), + help_text=_("Quota in MB for this mailbox. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators)."), widget=forms.widgets.TextInput(attrs={"class": "span1"}) ) + quota_act = forms.BooleanField(required=False) aliases = forms.EmailField( label=ugettext_lazy("Alias(es)"), required=False, @@ -534,8 +536,12 @@ class AccountFormMail(forms.Form, DynamicForm): name = "aliases_%d" % cpt self._create_field(forms.EmailField, name, alias.full_address) cpt += 1 - self.fields["email"].initial = self.mb.full_address - self.fields["quota"].initial = self.mb.quota + self.fields["email"].initial = self.mb.full_address + self.fields["quota_act"].initial = self.mb.use_domain_quota + if not self.mb.use_domain_quota and self.mb.quota: + self.fields["quota"].initial = self.mb.quota + else: + self.fields["quota_act"].initial = True if len(args) and isinstance(args[0], QueryDict): self._load_from_qdict(args[0], "aliases", forms.EmailField) @@ -557,15 +563,19 @@ class AccountFormMail(forms.Form, DynamicForm): if not user.can_access(domain): raise PermDeniedException + if self.cleaned_data["quota_act"]: + self.cleaned_data["quota"] = None + if not hasattr(self, "mb") or self.mb is None: try: self.mb = Mailbox.objects.get(address=locpart, domain=domain) except Mailbox.DoesNotExist: events.raiseEvent("CanCreate", user, "mailboxes") - self.mb = Mailbox() - self.mb.save_from_user(locpart, domain, account, - self.cleaned_data["quota"], - owner=user) + self.mb = Mailbox(address=locpart, domain=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")) + self.mb.save() grant_access_to_object(user, self.mb, is_owner=True) events.raiseEvent("CreateMailbox", user, self.mb) if user.is_superuser and not self.mb.user.has_perm("admin.add_domain"): @@ -587,7 +597,9 @@ class AccountFormMail(forms.Form, DynamicForm): self.mb.address = locpart q.username = self.mb.full_address q.save() - self.mb.set_quota(self.cleaned_data["quota"], user.has_perm("admin.add_domain")) + self.mb.use_domain_quota = self.cleaned_data["quota_act"] + override_rules = True if not self.mb.quota or user.has_perm("admin.add_domain") else False + self.mb.set_quota(self.cleaned_data["quota"], override_rules) self.mb.save() if old_mail_home is not None: # Problem here: the mailbox has already been saved so, diff --git a/modoboa/admin/models.py b/modoboa/admin/models.py index 383e243d3..aee63f5a5 100644 --- a/modoboa/admin/models.py +++ b/modoboa/admin/models.py @@ -440,8 +440,9 @@ class User(DUser): raise AdminError(_("Account import failed (%s): domain does not exist" % self.username)) if not user.can_access(domain): raise PermDeniedException - mb = Mailbox() - mb.save_from_user(mailbox, domain, self, owner=user) + mb = Mailbox(address=mailbox, domain=domain, user=self, use_domain_quota=True) + mb.set_quota(override_rules=user.has_perm("admin.change_domain")) + mb.save() self.save() if grpname == "DomainAdmins": for domname in row[8:]: @@ -586,6 +587,7 @@ class Domain(DatesAware): def to_csv(self, csvwriter): csvwriter.writerow(["domain", self.name, self.quota, self.enabled]) + class DomainAlias(DatesAware): name = models.CharField(ugettext_lazy("name"), max_length=100, unique=True, help_text=ugettext_lazy("The alias name")) @@ -641,7 +643,8 @@ class Mailbox(DatesAware): ugettext_lazy('address'), max_length=100, help_text=ugettext_lazy("Mailbox address (without the @domain.tld part)") ) - quota = models.IntegerField() + quota = models.PositiveIntegerField() + use_domain_quota = models.BooleanField(default=False) domain = models.ForeignKey(Domain) user = models.ForeignKey(User) @@ -718,20 +721,25 @@ class Mailbox(DatesAware): if code: raise AdminError(_("Failed to remove mailbox: %s" % output)) - def set_quota(self, value, override_domain=False): + def set_quota(self, value=None, override_rules=False): """Set or update quota's value for this mailbox. :param integer value: the quota's value - :param bool override_domain: allow to override domain's limit or not + :param bool override_rules: allow to override defined quota rules """ if value is None: - self.quota = self.domain.quota - elif int(value) > self.domain.quota and not override_domain: + if self.use_domain_quota: + self.quota = self.domain.quota + else: + self.quota = 0 + elif int(value) > self.domain.quota and not override_rules: raise AdminError( _("Quota is greater than the allowed domain's limit (%dM)" % self.domain.quota) ) else: self.quota = value + if not self.quota and not override_rules: + raise AdminError(_("A quota is required")) def get_quota(self): q = Quota.objects.get(username=self.full_address) @@ -743,20 +751,9 @@ class Mailbox(DatesAware): q = Quota.objects.get(username=self.full_address) return int(q.bytes / float(self.quota * 1048576) * 100) - def save_from_user(self, localpart, domain, user, quota=None, owner=None): - """Simple save method called for automatic creations - - :param localpart: the mailbox - :param domain: the associated Domain object - :param user: the associated User object - """ - self.address = localpart - self.domain = domain - self.user = user - self.set_quota(quota, True if (owner and owner.has_perm("admin.add_domain")) else False) - super(Mailbox, self).save() - - Quota.objects.create(username=self.full_address) + def save(self, *args, **kwargs): + super(Mailbox, self).save(*args, **kwargs) + quota, created = Quota.objects.get_or_create(username=self.full_address) def delete(self, keepdir=False): """Custom delete method @@ -1030,8 +1027,9 @@ def populate_callback(user): try: mb = Mailbox.objects.get(domain=domain, address=localpart) except Mailbox.DoesNotExist: - mb = Mailbox() - mb.save_from_user(localpart, domain, user) + mb = Mailbox(address=localpart, domain=domain, user=user, use_domain_quota=True) + mb.set_quota() + mb.save() events.raiseEvent("CreateMailbox", sadmins[0], mb) grant_access_to_object(sadmins[0], mb, True) for su in sadmins[1:]: diff --git a/modoboa/admin/static/admin/js/admin.js b/modoboa/admin/static/admin/js/admin.js index b22b871d7..e8818199f 100644 --- a/modoboa/admin/static/admin/js/admin.js +++ b/modoboa/admin/static/admin/js/admin.js @@ -339,7 +339,7 @@ Identities.prototype = { choices: get_domains_list }) .dynamic_input(); - + activate_widget.call($("#id_quota_act")); }, accountform_init: function() { diff --git a/modoboa/admin/templates/admin/mailform.html b/modoboa/admin/templates/admin/mailform.html index 01da1c26a..57655ad28 100644 --- a/modoboa/admin/templates/admin/mailform.html +++ b/modoboa/admin/templates/admin/mailform.html @@ -1,4 +1,4 @@ {% load libextras %} {% render_field form.email %} -{% render_field_appended form.quota _("MB") %} +{% include "common/generic_field.html" with field=form.quota help_display_mode="tooltip" appended_text=_("MB") activator=True activator_value=form.quota_act.value deactivate_if_empty=False activator_label=_("Use domain default value") %} {% render_fields_group form "aliases" %} diff --git a/modoboa/admin/tests.py b/modoboa/admin/tests.py index a1d04f8e1..6b3a3bae9 100644 --- a/modoboa/admin/tests.py +++ b/modoboa/admin/tests.py @@ -77,6 +77,7 @@ class AccountTestCase(ModoTestCase): def test(self): values = dict(username="tester@test.com", first_name="Tester", last_name="Toto", password1="toto", password2="toto", role="SimpleUsers", + quota_act=True, is_active=True, email="tester@test.com", stepid=2) self.check_ajax_post(reverse("modoboa.admin.views.newaccount"), values) @@ -236,7 +237,7 @@ class PermissionsTestCase(ModoTestCase): True) admin = User.objects.get(username="admin@test.com") values = dict(username="admin@test.com", first_name="Admin", password1="", password2="", - is_active=True, email="admin@test.com") + quota=10, is_active=True, email="admin@test.com") self.check_ajax_post(reverse("modoboa.admin.views.editaccount", args=[admin.id]), values) self.assertEqual(admin.group, "DomainAdmins") self.assertEqual(admin.can_access(Domain.objects.get(name="test.com")), True) diff --git a/modoboa/extensions/amavis/__init__.py b/modoboa/extensions/amavis/__init__.py index bcd96c8fd..e8e35069a 100644 --- a/modoboa/extensions/amavis/__init__.py +++ b/modoboa/extensions/amavis/__init__.py @@ -118,10 +118,7 @@ $(document).ready(function() { }); $(document).bind('domform_init', function() { - var checked = $('#id_spam_subject_tag2_act').attr('checked'); - if (checked && checked == 'checked') { - $('#id_spam_subject_tag2').attr('disabled', true); - } + activate_widget.call($('#id_spam_subject_tag2_act')); }); }); """) diff --git a/modoboa/lib/templatetags/libextras.py b/modoboa/lib/templatetags/libextras.py index 9d8823c21..9e10c0085 100644 --- a/modoboa/lib/templatetags/libextras.py +++ b/modoboa/lib/templatetags/libextras.py @@ -107,9 +107,9 @@ def render_field_appended(field, text): @register.simple_tag def render_field_with_activator(field, activator_label=ugettext_lazy("activate")): return render_to_string("common/generic_field.html", { - "field" : field, "help_display_mode" : "tooltip", "activator" : True, - "activator_label" : activator_label - }) + "field": field, "help_display_mode": "tooltip", "activator": True, + "activator_label": activator_label, "deactivate_if_empty": True + }) @register.simple_tag def render_and_hide_field(field): diff --git a/modoboa/templates/common/generic_field.html b/modoboa/templates/common/generic_field.html index dd11f2af3..5c3ea7ec1 100644 --- a/modoboa/templates/common/generic_field.html +++ b/modoboa/templates/common/generic_field.html @@ -5,7 +5,7 @@ {% if appended_text %}
{% for error in field.errors %}{{ error|safe }}{% endfor %}
{% endif %}