WIP: update mailboxes.

see #831
This commit is contained in:
Antoine Nguyen
2016-01-30 14:58:25 +01:00
parent 3181f5df5d
commit 173e43e270
4 changed files with 72 additions and 44 deletions
+28 -40
View File
@@ -142,7 +142,7 @@ class DomainFormGeneral(forms.ModelForm, DynamicForm):
q.delete()
def save(self, user, commit=True, domalias_post_create=False):
"""Custom save method
"""Custom save method.
Updating a domain may have consequences on other objects
(domain alias, mailbox, quota). The most tricky part concerns
@@ -150,46 +150,34 @@ class DomainFormGeneral(forms.ModelForm, DynamicForm):
"""
d = super(DomainFormGeneral, self).save(commit=False)
if commit:
old_mail_homes = None
if self.oldname is not None and d.name != self.oldname:
d.name = self.oldname
old_mail_homes = \
dict((mb.id, mb.mail_home) for mb in d.mailbox_set.all())
d.name = self.cleaned_data['name']
d.save()
Mailbox.objects.filter(domain=d, use_domain_quota=True) \
.update(quota=d.quota)
aliases = []
for k, v in self.cleaned_data.iteritems():
if not k.startswith("aliases"):
continue
if v in ["", None]:
continue
aliases.append(v)
for dalias in d.domainalias_set.all():
if dalias.name not in aliases:
dalias.delete()
if not commit:
return d
d.save()
aliases = []
for k, v in self.cleaned_data.iteritems():
if not k.startswith("aliases"):
continue
if v in ["", None]:
continue
aliases.append(v)
for dalias in d.domainalias_set.all():
if dalias.name not in aliases:
dalias.delete()
else:
aliases.remove(dalias.name)
if aliases:
events.raiseEvent(
"CanCreate", user, "domain_aliases", len(aliases))
for alias in aliases:
try:
d.domainalias_set.get(name=alias)
except DomainAlias.DoesNotExist:
pass
else:
aliases.remove(dalias.name)
if aliases:
events.raiseEvent(
"CanCreate", user, "domain_aliases", len(aliases))
for alias in aliases:
try:
d.domainalias_set.get(name=alias)
except DomainAlias.DoesNotExist:
pass
else:
continue
al = DomainAlias(name=alias, target=d, enabled=d.enabled)
al.save(creator=user) if domalias_post_create else al.save()
if old_mail_homes is not None:
self.update_mailbox_quotas(d)
for mb in d.mailbox_set.all():
mb.rename_dir(old_mail_homes[mb.id])
continue
options = {"creator": user} if domalias_post_create else {}
DomainAlias(name=alias, target=d, enabled=d.enabled).save(
**options)
return d
+23
View File
@@ -6,6 +6,29 @@ from django.dispatch import receiver
from . import models
@receiver(signals.post_save, sender=models.Domain)
def update_domain_mailboxes(sender, instance, **kwargs):
"""Update associated mailboxes."""
if kwargs.get("created"):
return
instance.mailbox_set.filter(use_domain_quota=True).update(
quota=instance.quota)
if instance.old_mail_homes is None:
return
qset = (
models.Quota.objects.filter(
username__contains="@{}".format(instance.oldname))
)
for q in qset:
username = q.username.replace(
"@{}".format(instance.oldname), "@{}".format(instance.name))
models.Quota.objects.create(
username=username, bytes=q.bytes, messages=q.messages)
q.delete()
for mb in instance.mailbox_set.all():
mb.rename_dir(instance.old_mail_homes[mb.pk])
@receiver(signals.post_save, sender=models.DomainAlias)
def create_alias_for_domainalias(sender, instance, **kwargs):
"""Create a dedicated alias for domain alias."""
+15 -3
View File
@@ -29,7 +29,6 @@ class DomainManager(Manager):
@python_2_unicode_compatible
class Domain(AdminObject):
"""Mail domain."""
name = models.CharField(ugettext_lazy('name'), max_length=100, unique=True,
@@ -53,6 +52,12 @@ class Domain(AdminObject):
ordering = ["name"]
app_label = "admin"
def __init__(self, *args, **kwargs):
"""Save name for further use."""
super(Domain, self).__init__(*args, **kwargs)
self.old_mail_homes = None
self.oldname = self.name
@property
def domainalias_count(self):
return self.domainalias_set.count()
@@ -124,9 +129,16 @@ class Domain(AdminObject):
for al in self.alias_set.all():
ungrant_access_to_object(al, account)
def save(self, *args, **kwargs):
"""Store current data if domain is renamed."""
if self.oldname != self.name:
self.old_mail_homes = (
dict((mb.id, mb.mail_home) for mb in self.mailbox_set.all())
)
super(Domain, self).save(*args, **kwargs)
def delete(self, fromuser, keepdir=False):
"""Custom delete method.
"""
"""Custom delete method."""
from modoboa.lib.permissions import ungrant_access_to_objects
from .mailbox import Quota
+6 -1
View File
@@ -55,12 +55,17 @@ class APITestCase(ModoAPITestCase):
def test_update_domain(self):
"""Check domain update."""
domain = models.Domain.objects.get(name="test.com")
models.Mailbox.objects.filter(
domain__name="test.com", address="user").update(
use_domain_quota=True)
url = reverse("external_api:domain-detail", args=[domain.pk])
response = self.client.put(url, {"name": "test.com", "quota": 1000})
self.assertEqual(response.status_code, 200)
domain.refresh_from_db()
self.assertEqual(domain.quota, 1000)
mb = models.Mailbox.objects.get(
domain__name="test.com", address="user")
self.assertEqual(mb.quota, 1000)
response = self.client.put(url, {"name": "test42.com", "quota": 1000})
self.assertEqual(response.status_code, 200)