From 729ff975adb02fc156e9ae82d1627b126b2a478b Mon Sep 17 00:00:00 2001 From: Antoine Nguyen Date: Thu, 25 Apr 2013 10:19:14 +0200 Subject: [PATCH] Simple user: Rename the mailbox when the username is modified. fixes #407 --- modoboa/admin/fixtures/test_content.json | 2 +- modoboa/admin/forms.py | 86 ++++++++++++------------ modoboa/admin/models.py | 18 ++++- modoboa/admin/tests.py | 5 +- 4 files changed, 63 insertions(+), 48 deletions(-) diff --git a/modoboa/admin/fixtures/test_content.json b/modoboa/admin/fixtures/test_content.json index b6bd99c83..98782351b 100644 --- a/modoboa/admin/fixtures/test_content.json +++ b/modoboa/admin/fixtures/test_content.json @@ -1 +1 @@ -[{"pk": 2, "model": "admin.user", "fields": {"username": "user@test.com", "is_active": "True", "is_superuser": "False", "password": "{PLAIN}toto", "groups": [2]}},{"pk": 3, "model": "admin.user", "fields": {"username": "admin@test.com", "is_active": "True", "is_superuser": "False", "password": "{PLAIN}toto", "groups": [1]}},{"pk": 4, "model": "admin.user", "fields": {"username": "superadmin@test.com", "is_active": "True", "is_superuser": "True", "password": "{PLAIN}toto", "groups": []}},{"pk": 1, "model": "admin.ObjectDates", "fields": {"creation": "2011-09-07 09:27:07.579603", "last_modification": "2011-09-07 09:27:07.579603"}}, {"pk": 2, "model": "admin.ObjectDates", "fields": {"creation": "2011-09-07 09:27:07.579603", "last_modification": "2011-09-07 09:27:07.579603"}}, {"pk": 3, "model": "admin.ObjectDates", "fields": {"creation": "2011-09-07 09:27:07.579603", "last_modification": "2011-09-07 09:27:07.579603"}}, {"pk": 1, "model": "admin.Domain", "fields": {"name" : "test.com", "quota" : "100", "dates": "1"}}, {"pk": 1, "model": "admin.Mailbox", "fields": {"address": "user", "domain": "1", "dates": "1", "quota": "10", "user": "2"}}, {"pk": 2, "model": "admin.Mailbox", "fields": {"address": "admin", "domain": "1", "dates": "2", "quota": "10", "user": "3"}}, {"pk": 3, "model": "admin.Mailbox", "fields": {"address": "superadmin", "domain": "1", "dates": "3", "quota": "10", "user": "4"}}, {"pk": "user@test.com", "model": "admin.Quota", "fields": {"username": "user@test.com", "bytes": 0, "messages": 0}}, {"pk": "admin@test.com", "model": "admin.Quota", "fields": {"username": "admin@test.com", "bytes": 0, "messages": 0}}, {"pk": "superadmin@test.com", "model": "admin.Quota", "fields": {"username": "superadmin@test.com", "bytes": 0, "messages": 0}},{"pk": 2, "model": "admin.objectaccess", "fields": {"is_owner": true, "user": 1, "content_type": ["admin", "user"], "object_id": 2}},{"pk": 3, "model": "admin.objectaccess", "fields": {"is_owner": true, "user": 1, "content_type": ["admin", "user"], "object_id": 3}}] +[{"pk": 2, "model": "admin.user", "fields": {"username": "user@test.com", "is_active": "True", "is_superuser": "False", "password": "{PLAIN}toto", "groups": [2]}},{"pk": 3, "model": "admin.user", "fields": {"username": "admin@test.com", "is_active": "True", "is_superuser": "False", "password": "{PLAIN}toto", "groups": [1]}},{"pk": 4, "model": "admin.user", "fields": {"username": "superadmin@test.com", "is_active": "True", "is_superuser": "True", "password": "{PLAIN}toto", "groups": []}},{"pk": 1, "model": "admin.ObjectDates", "fields": {"creation": "2011-09-07 09:27:07.579603", "last_modification": "2011-09-07 09:27:07.579603"}}, {"pk": 2, "model": "admin.ObjectDates", "fields": {"creation": "2011-09-07 09:27:07.579603", "last_modification": "2011-09-07 09:27:07.579603"}}, {"pk": 3, "model": "admin.ObjectDates", "fields": {"creation": "2011-09-07 09:27:07.579603", "last_modification": "2011-09-07 09:27:07.579603"}}, {"pk": 1, "model": "admin.Domain", "fields": {"name" : "test.com", "quota" : "100", "dates": "1"}}, {"pk": 1, "model": "admin.Mailbox", "fields": {"address": "user", "domain": "1", "dates": "1", "quota": "10", "user": "2"}}, {"pk": 2, "model": "admin.Mailbox", "fields": {"address": "admin", "domain": "1", "dates": "2", "quota": "10", "user": "3"}}, {"pk": 3, "model": "admin.Mailbox", "fields": {"address": "superadmin", "domain": "1", "dates": "3", "quota": "10", "user": "4"}}, {"pk": "user@test.com", "model": "admin.Quota", "fields": {"mbox": 1, "username": "user@test.com", "bytes": 0, "messages": 0}}, {"pk": "admin@test.com", "model": "admin.Quota", "fields": {"mbox": 2, "username": "admin@test.com", "bytes": 0, "messages": 0}}, {"pk": "superadmin@test.com", "model": "admin.Quota", "fields": {"mbox": 3, "username": "superadmin@test.com", "bytes": 0, "messages": 0}},{"pk": 2, "model": "admin.objectaccess", "fields": {"is_owner": true, "user": 1, "content_type": ["admin", "user"], "object_id": 2}},{"pk": 3, "model": "admin.objectaccess", "fields": {"is_owner": true, "user": 1, "content_type": ["admin", "user"], "object_id": 3}}] diff --git a/modoboa/admin/forms.py b/modoboa/admin/forms.py index 033f5d14e..dd8228ec0 100644 --- a/modoboa/admin/forms.py +++ b/modoboa/admin/forms.py @@ -554,62 +554,60 @@ class AccountFormMail(forms.Form, DynamicForm): if self.cleaned_data["email"] == "": return None - locpart, domname = split_mailbox(self.cleaned_data["email"]) - try: - domain = Domain.objects.get(name=domname) - except Domain.DoesNotExist: - raise AdminError(_("Domain does not exist")) - - 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: + locpart, domname = split_mailbox(self.cleaned_data["email"]) try: - self.mb = Mailbox.objects.get(address=locpart, domain=domain) + domain = Domain.objects.get(name=domname) + except Domain.DoesNotExist: + raise AdminError(_("Domain does not exist")) + if not user.can_access(domain): + raise PermDeniedException + try: + mb = Mailbox.objects.get(address=locpart, domain=domain) except Mailbox.DoesNotExist: - events.raiseEvent("CanCreate", user, "mailboxes") - 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"): - # A super user is creating a new mailbox. Give - # access to that mailbox (and the associated - # account) to the appropriate domain admins, - # except if the new account has a more important - # role (SuperAdmin, Reseller) - for admin in self.mb.domain.admins: - grant_access_to_object(admin, self.mb) - grant_access_to_object(admin, self.mb.user) - + pass + else: + raise AdminError(_("Mailbox %s already exists" % self.cleaned_data["email"])) + events.raiseEvent("CanCreate", user, "mailboxes") + 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"): + # A super user is creating a new mailbox. Give + # access to that mailbox (and the associated + # account) to the appropriate domain admins, + # except if the new account has a more important + # role (SuperAdmin, Reseller) + for admin in self.mb.domain.admins: + grant_access_to_object(admin, self.mb) + grant_access_to_object(admin, self.mb.user) else: - old_mail_home = None + newaddress = None if self.cleaned_data["email"] != self.mb.full_address: - old_mail_home = self.mb.mail_home - q = Quota.objects.get(username=self.mb.full_address) - self.mb.domain = domain - self.mb.address = locpart - q.username = self.mb.full_address - q.save() + newaddress = self.cleaned_data["email"] + elif account.group == "SimpleUsers" and account.username != self.mb.full_address: + newaddress = account.username + if newaddress is not None: + local_part, domname = split_mailbox(newaddress) + try: + domain = Domain.objects.get(name=domname) + except Domain.DoesNotExist: + raise AdminError(_("Domain does not exist")) + if not user.can_access(domain): + raise PermDeniedException + self.mb.rename(local_part, 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, - # if the rename fails, we can't rollback! - # Maybe django-reversion could be the solution? - try: - self.mb.rename_dir(old_mail_home) - except AdminError: - # do rollback - pass account.email = self.cleaned_data["email"] account.save() diff --git a/modoboa/admin/models.py b/modoboa/admin/models.py index d1f2b215a..c3f544507 100644 --- a/modoboa/admin/models.py +++ b/modoboa/admin/models.py @@ -710,6 +710,19 @@ class Mailbox(DatesAware): if code: raise AdminError(_("Failed to rename mailbox: %s" % output)) + def rename(self, address, domain): + """Rename the mailbox + + :param string address: the new mailbox's address (local part) + :param Domain domain: the new mailbox's domain + """ + old_mail_home = self.mail_home + qs = Quota.objects.filter(username=self.full_address) + self.address = address + self.domain = domain + self.rename_dir(old_mail_home) + qs.update(username=self.full_address) + def delete_dir(self): hm = parameters.get_admin("HANDLE_MAILBOXES", raise_error=False) if hm is None or hm == "no": @@ -753,7 +766,10 @@ class Mailbox(DatesAware): def save(self, *args, **kwargs): super(Mailbox, self).save(*args, **kwargs) - quota, created = Quota.objects.get_or_create(username=self.full_address) + try: + q = self.quota_value + except Quota.DoesNotExist: + Quota.objects.create(mbox=self, username=self.full_address) def delete(self, keepdir=False): """Custom delete method diff --git a/modoboa/admin/tests.py b/modoboa/admin/tests.py index 6b3a3bae9..41ac97199 100644 --- a/modoboa/admin/tests.py +++ b/modoboa/admin/tests.py @@ -86,13 +86,14 @@ class AccountTestCase(ModoTestCase): self.assertEqual(mb.full_address, "tester@test.com") self.assertEqual(mb.quota, 100) self.assertEqual(mb.enabled, True) + self.assertEqual(mb.quota_value.username, "tester@test.com") self.assertEqual(account.username, mb.full_address) self.assertTrue(account.check_password("toto")) self.assertEqual(account.first_name, "Tester") self.assertEqual(account.last_name, "Toto") self.assertEqual(mb.domain.mailbox_count, 4) - values["email"] = "pouet@test.com" + values["username"] = "pouet@test.com" self.check_ajax_post(reverse("modoboa.admin.views.editaccount", args=[account.id]), values) mb = Mailbox.objects.get(pk=mb.id) @@ -268,7 +269,7 @@ class PermissionsTestCase(ModoTestCase): """ values = dict(username="superadmin2@test.com", first_name="Super", last_name="Admin", password1="toto", password2="toto", role="SuperAdmins", - is_active=True, email="superadmin@test.com", stepid=2) + is_active=True, email="superadmin2@test.com", stepid=2) self.check_ajax_post(reverse("modoboa.admin.views.newaccount"), values) account = User.objects.get(username="superadmin2@test.com")