see #832
This commit is contained in:
Antoine Nguyen
2016-03-02 15:57:09 +01:00
parent 000aba6569
commit b6f1282c7e
6 changed files with 99 additions and 45 deletions
+4 -26
View File
@@ -124,6 +124,7 @@ class AccountFormGeneral(forms.ModelForm):
return self.cleaned_data["role"]
def clean_username(self):
"""username must be a valid email address for simple users."""
if "role" not in self.cleaned_data:
return self.cleaned_data["username"]
if self.cleaned_data["role"] != "SimpleUsers":
@@ -261,31 +262,6 @@ class AccountFormMail(forms.Form, DynamicForm):
user.has_perm("admin.add_domain"))
self.mb.save(creator=user)
def update_mailbox(self, user, account):
newaddress = None
if self.cleaned_data["email"] != self.mb.full_address:
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 NotFound(_("Domain does not exist"))
if not user.can_access(domain):
raise PermDeniedException
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 newaddress:
self.mb.rename(local_part, domain)
events.raiseEvent("MailboxModified", self.mb)
def _update_aliases(self, user, account):
"""Update mailbox aliases."""
aliases = []
@@ -334,7 +310,9 @@ class AccountFormMail(forms.Form, DynamicForm):
if not hasattr(self, "mb") or self.mb is None:
self.create_mailbox(user, account)
else:
self.update_mailbox(user, account)
self.cleaned_data["use_domain_quota"] = (
self.cleaned_data["quota_act"])
self.mb.update_from_dict(user, self.cleaned_data)
events.raiseEvent(
'SaveExtraFormFields', 'mailform', self.mb, self.cleaned_data
)
+33 -5
View File
@@ -16,7 +16,8 @@ from .base import AdminObject
from .domain import Domain
from modoboa.core.models import User
from modoboa.lib import events, parameters
from modoboa.lib.exceptions import BadRequest, Conflict, InternalError
from modoboa.lib import exceptions as lib_exceptions
from modoboa.lib.email_utils import split_mailbox
from modoboa.lib.sysutils import exec_cmd
@@ -144,7 +145,7 @@ class Mailbox(AdminObject):
"doveadm user %s -f home" % self.full_address, **options
)
if code:
raise InternalError(
raise lib_exceptions.InternalError(
_("Failed to retrieve mailbox location (%s)" % output))
self.__mail_home = output.strip()
return self.__mail_home
@@ -233,14 +234,14 @@ class Mailbox(AdminObject):
else:
self.quota = 0
elif int(value) > self.domain.quota and not override_rules:
raise BadRequest(
raise lib_exceptions.BadRequest(
_("Quota is greater than the allowed domain's limit (%dM)"
% self.domain.quota)
)
else:
self.quota = value
if not self.quota and self.domain.quota and not override_rules:
raise BadRequest(_("A quota is required"))
raise lib_exceptions.BadRequest(_("A quota is required"))
def get_quota(self):
"""Get quota limit.
@@ -279,6 +280,33 @@ class Mailbox(AdminObject):
grant_access_to_object(admin, self)
grant_access_to_object(admin, self.user)
def update_from_dict(self, user, values):
"""Update mailbox from a dictionary."""
newaddress = None
if values["email"] != self.full_address:
newaddress = values["email"]
elif (self.user.group == "SimpleUsers" and
self.user.username != self.full_address):
newaddress = self.user.username
if newaddress is not None:
local_part, domname = split_mailbox(newaddress)
try:
domain = Domain.objects.get(name=domname)
except Domain.DoesNotExist:
raise lib_exceptions.NotFound(_("Domain does not exist"))
if not user.can_access(domain):
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
self.set_quota(values["quota"], override_rules)
if newaddress:
self.rename(local_part, domain)
self.save()
events.raiseEvent("MailboxModified", self)
def save(self, *args, **kwargs):
"""Custom save.
@@ -290,7 +318,7 @@ class Mailbox(AdminObject):
if self.pk:
qset = qset.exclude(pk=self.pk)
if qset.exists():
raise Conflict(
raise lib_exceptions.Conflict(
_("Mailbox {} already exists").format(self))
if self.quota_value is None:
self.quota_value, created = Quota.objects.get_or_create(
+34 -11
View File
@@ -107,6 +107,21 @@ class CreateAccountSerializer(AccountSerializer):
})
return data
def _create_mailbox(self, creator, account, data):
"""Create a new Mailbox instance."""
full_address = data.pop("full_address")
address, domain_name = email_utils.split_mailbox(full_address)
domain = get_object_or_404(
admin_models.Domain, name=domain_name)
mb = admin_models.Mailbox(
user=account, address=address, domain=domain, **data)
mb.set_quota(
data.get("quota"), creator.has_perm("admin.add_domain")
)
mb.save(creator=creator)
account.email = full_address
return mb
def create(self, validated_data):
"""Create appropriate objects."""
creator = self.context["request"].user
@@ -116,16 +131,24 @@ class CreateAccountSerializer(AccountSerializer):
user.set_password(validated_data["password"])
user.save(creator=creator)
if mailbox_data:
full_address = mailbox_data.pop("full_address")
address, domain_name = email_utils.split_mailbox(full_address)
domain = get_object_or_404(
admin_models.Domain, name=domain_name)
mb = admin_models.Mailbox(
user=user, address=address, domain=domain, **mailbox_data)
mb.set_quota(
mailbox_data.get("quota"), creator.has_perm("admin.add_domain")
)
mb.save(creator=creator)
user.email = full_address
self._create_mailbox(creator, user, mailbox_data)
user.role = role
return user
def update(self, instance, validated_data):
"""Update account and associated objects."""
mailbox_data = validated_data.pop("mailbox")
password = validated_data.pop("password")
for key, value in validated_data.items():
setattr(instance, key, value)
instance.set_password(password)
instance.save()
if mailbox_data:
creator = self.context["request"].user
if instance.mailbox:
# FIXME: compat, to remove.
mailbox_data["email"] = mailbox_data["full_address"]
instance.mailbox.update_from_dict(creator, mailbox_data)
else:
self._create_mailbox(creator, instance, mailbox_data)
return instance
+5
View File
@@ -6,6 +6,11 @@
* @classdesc This class contains utility methods used by the admin
* application.
*/
/*global
$ Listing
*/
var Admin = function(options) {
Listing.call(this, options);
};
+3 -2
View File
@@ -44,11 +44,12 @@ class AccountTestCase(ModoTestCase):
alias__internal=True).exists()
)
values["username"] = "pouet@test.com"
values.update({
"username": "pouet@test.com", "email": "pouet@test.com"})
self.ajax_post(
reverse("admin:account_change", args=[account.id]), values
)
mb = models.Mailbox.objects.get(pk=mb.id)
mb = models.Mailbox.objects.get(pk=mb.pk)
self.assertEqual(mb.full_address, "pouet@test.com")
self.assertEqual(mb.quota_value.username, "pouet@test.com")
# Check if self alias has been updated
+20 -1
View File
@@ -124,6 +124,8 @@ class AccountAPITestCase(ModoAPITestCase):
user = core_models.User.objects.filter(pk=account["pk"]).first()
self.assertIsNot(user, None)
self.assertIsNot(user.mailbox, None)
domadmin = core_models.User.objects.get(username="admin@test.com")
self.assertTrue(domadmin.can_access(user))
data = copy.deepcopy(self.ACCOUNT_DATA)
data["username"] = "fromapi_ééé@test.com"
@@ -193,13 +195,30 @@ class AccountAPITestCase(ModoAPITestCase):
def test_update_account(self):
"""Try to update an account."""
pass
account = core_models.User.objects.get(username="user@test.com")
url = reverse("external_api:account-detail", args=[account.pk])
data = {
"username": "fromapi@test.com",
"role": account.role,
"password": "Toto1234",
"mailbox": {
"full_address": "fromapi@test.com",
"quota": account.mailbox.quota
}
}
response = self.client.put(url, data, format="json")
self.assertEqual(response.status_code, 200)
account.refresh_from_db()
self.assertEqual(account.email, account.mailbox.full_address)
def test_delete_account(self):
"""Try to delete an account."""
account = core_models.User.objects.get(username="user@test.com")
domadmin = core_models.User.objects.get(username="admin@test.com")
self.assertTrue(domadmin.can_access(account))
url = reverse("external_api:account-detail", args=[account.pk])
response = self.client.delete(url)
self.assertEqual(response.status_code, 204)
self.assertFalse(
core_models.User.objects.filter(pk=account.pk).exists())
self.assertFalse(domadmin.can_access(account))