mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-21 06:18:45 +02:00
@@ -3,6 +3,7 @@
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.translation import ugettext as _, ugettext_lazy
|
||||
|
||||
from modoboa.core import signals as core_signals
|
||||
from modoboa.lib import parameters, events
|
||||
from modoboa.lib.email_utils import split_mailbox
|
||||
from modoboa.lib.exceptions import PermDeniedException, BadRequest, Conflict
|
||||
@@ -103,7 +104,6 @@ def import_account_mailbox(user, account, row):
|
||||
"""
|
||||
account.email = row[0].strip()
|
||||
if account.email:
|
||||
account.save()
|
||||
mailbox, domname = split_mailbox(account.email)
|
||||
try:
|
||||
domain = Domain.objects.get(name=domname)
|
||||
@@ -114,6 +114,11 @@ def import_account_mailbox(user, account, row):
|
||||
)
|
||||
if not user.can_access(domain):
|
||||
raise PermDeniedException
|
||||
core_signals.can_create_object.send(
|
||||
sender="import", context=user, object_type="mailboxes")
|
||||
core_signals.can_create_object.send(
|
||||
sender="import", context=domain, object_type="mailboxes")
|
||||
account.save()
|
||||
if Mailbox.objects.filter(address=mailbox, domain=domain).exists():
|
||||
raise Conflict(
|
||||
_("Mailbox {} already exists").format(account.email))
|
||||
|
||||
@@ -10,6 +10,7 @@ from django.db.models import Q
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from modoboa.core.models import User
|
||||
from modoboa.core import signals as core_signals
|
||||
from modoboa.lib import events
|
||||
from modoboa.lib.exceptions import PermDeniedException
|
||||
|
||||
@@ -118,6 +119,8 @@ def import_domain(user, row, formopts):
|
||||
"""Specific code for domains import"""
|
||||
if not user.has_perm("admin.add_domain"):
|
||||
raise PermDeniedException(_("You are not allowed to import domains"))
|
||||
core_signals.can_create_object.send(
|
||||
sender="import", context=user, object_type="domains")
|
||||
dom = Domain()
|
||||
dom.from_csv(user, row)
|
||||
|
||||
@@ -127,6 +130,8 @@ def import_domainalias(user, row, formopts):
|
||||
if not user.has_perm("admin.add_domainalias"):
|
||||
raise PermDeniedException(
|
||||
_("You are not allowed to import domain aliases."))
|
||||
core_signals.can_create_object.send(
|
||||
sender="import", context=user, object_type="domain_aliases")
|
||||
domalias = DomainAlias()
|
||||
domalias.from_csv(user, row)
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ from django.utils.translation import ugettext as _, ugettext_lazy
|
||||
|
||||
import reversion
|
||||
|
||||
from modoboa.core import signals as core_signals
|
||||
from modoboa.lib.email_utils import split_mailbox
|
||||
from modoboa.lib.exceptions import (
|
||||
PermDeniedException, BadRequest, Conflict, NotFound
|
||||
@@ -171,6 +172,10 @@ class Alias(AdminObject):
|
||||
raise BadRequest(_("Domain '%s' does not exist" % domname))
|
||||
if not user.can_access(domain):
|
||||
raise PermDeniedException
|
||||
core_signals.can_create_object.send(
|
||||
sender="import", context=user, object_type="mailbox_aliases")
|
||||
core_signals.can_create_object.send(
|
||||
sender="import", context=domain, object_type="mailbox_aliases")
|
||||
if Alias.objects.filter(address=address).exists():
|
||||
raise Conflict
|
||||
self.address = address
|
||||
|
||||
@@ -0,0 +1,237 @@
|
||||
# coding: utf-8
|
||||
"""Test cases for the limits extension."""
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from rest_framework.authtoken.models import Token
|
||||
|
||||
from modoboa.admin.factories import populate_database
|
||||
from modoboa.admin.models import Domain
|
||||
from modoboa.core import factories as core_factories
|
||||
from modoboa.core.models import User
|
||||
from modoboa.lib import parameters
|
||||
from modoboa.lib import tests as lib_tests
|
||||
|
||||
from .. import utils
|
||||
|
||||
|
||||
class APIAdminLimitsTestCase(lib_tests.ModoAPITestCase):
|
||||
"""Check that limits are used also by the API."""
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
"""Create test data."""
|
||||
super(APIAdminLimitsTestCase, cls).setUpTestData()
|
||||
for name, tpl in utils.get_user_limit_templates():
|
||||
parameters.save_admin(
|
||||
"DEFLT_USER_{}_LIMIT".format(name.upper()), 2)
|
||||
populate_database()
|
||||
cls.user = User.objects.get(username="admin@test.com")
|
||||
cls.da_token = Token.objects.create(user=cls.user)
|
||||
cls.reseller = core_factories.UserFactory(
|
||||
username="reseller", groups=("Resellers", ),
|
||||
)
|
||||
cls.r_token = Token.objects.create(user=cls.reseller)
|
||||
|
||||
def test_domadmins_limit(self):
|
||||
"""Check domain admins limit."""
|
||||
self.client.credentials(
|
||||
HTTP_AUTHORIZATION='Token ' + self.r_token.key)
|
||||
|
||||
limit = self.reseller.userobjectlimit_set.get(name="domain_admins")
|
||||
url = reverse("external_api:account-list")
|
||||
data = {
|
||||
"username": "fromapi@test.com",
|
||||
"role": "DomainAdmins",
|
||||
"password": "Toto1234",
|
||||
}
|
||||
response = self.client.post(url, data, format="json")
|
||||
self.assertEqual(response.status_code, 201)
|
||||
self.assertFalse(limit.is_exceeded())
|
||||
|
||||
data["username"] = "fromapi2@test.com"
|
||||
response = self.client.post(url, data, format="json")
|
||||
self.assertEqual(response.status_code, 201)
|
||||
self.assertTrue(limit.is_exceeded())
|
||||
|
||||
data["username"] = "fromapi3@test.com"
|
||||
response = self.client.post(url, data, format="json")
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
user = User.objects.get(username="user@test.com")
|
||||
domain = Domain.objects.get(name="test.com")
|
||||
domain.add_admin(self.reseller)
|
||||
url = reverse("external_api:account-detail", args=[user.pk])
|
||||
data = {
|
||||
"username": user.username,
|
||||
"role": "DomainAdmins",
|
||||
"password": "Toto1234",
|
||||
"mailbox": {
|
||||
"full_address": user.username,
|
||||
"quota": user.mailbox.quota
|
||||
}
|
||||
}
|
||||
response = self.client.put(url, data, format="json")
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
def test_domains_limit(self):
|
||||
"""Check domains limit."""
|
||||
self.client.credentials(
|
||||
HTTP_AUTHORIZATION='Token ' + self.r_token.key)
|
||||
limit = self.reseller.userobjectlimit_set.get(name="domains")
|
||||
url = reverse("external_api:domain-list")
|
||||
data = {"name": "test3.com", "quota": 10}
|
||||
response = self.client.post(url, data, format="json")
|
||||
self.assertEqual(response.status_code, 201)
|
||||
self.assertFalse(limit.is_exceeded())
|
||||
|
||||
data["name"] = "test4.com"
|
||||
response = self.client.post(url, data, format="json")
|
||||
self.assertEqual(response.status_code, 201)
|
||||
self.assertTrue(limit.is_exceeded())
|
||||
|
||||
data["username"] = "test5.com"
|
||||
response = self.client.post(url, data, format="json")
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
def test_domain_aliases_limit(self):
|
||||
"""Check domain aliases limit."""
|
||||
self.client.credentials(
|
||||
HTTP_AUTHORIZATION='Token ' + self.r_token.key)
|
||||
domain = Domain.objects.get(name="test.com")
|
||||
domain.add_admin(self.reseller)
|
||||
limit = self.reseller.userobjectlimit_set.get(name="domain_aliases")
|
||||
url = reverse("external_api:domain_alias-list")
|
||||
data = {"name": "dalias1.com", "target": domain.pk}
|
||||
response = self.client.post(url, data, format="json")
|
||||
self.assertEqual(response.status_code, 201)
|
||||
self.assertFalse(limit.is_exceeded())
|
||||
|
||||
data["name"] = "dalias2.com"
|
||||
response = self.client.post(url, data, format="json")
|
||||
self.assertEqual(response.status_code, 201)
|
||||
self.assertTrue(limit.is_exceeded())
|
||||
|
||||
data["username"] = "dalias3.com"
|
||||
response = self.client.post(url, data, format="json")
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
def test_mailboxes_limit(self):
|
||||
"""Check mailboxes limit."""
|
||||
self.client.credentials(
|
||||
HTTP_AUTHORIZATION='Token ' + self.da_token.key)
|
||||
|
||||
limit = self.user.userobjectlimit_set.get(name="mailboxes")
|
||||
url = reverse("external_api:account-list")
|
||||
data = {
|
||||
"username": "fromapi@test.com",
|
||||
"role": "SimpleUsers",
|
||||
"password": "Toto1234",
|
||||
"mailbox": {
|
||||
"full_address": "fromapi@test.com",
|
||||
"quota": 10
|
||||
}
|
||||
}
|
||||
response = self.client.post(url, data, format="json")
|
||||
self.assertEqual(response.status_code, 201)
|
||||
self.assertFalse(limit.is_exceeded())
|
||||
|
||||
data["username"] = "fromapi2@test.com"
|
||||
data["mailbox"]["full_address"] = "fromapi2@test.com"
|
||||
response = self.client.post(url, data, format="json")
|
||||
self.assertEqual(response.status_code, 201)
|
||||
self.assertTrue(limit.is_exceeded())
|
||||
|
||||
data["username"] = "fromapi3@test.com"
|
||||
data["mailbox"]["full_address"] = "fromapi3@test.com"
|
||||
response = self.client.post(url, data, format="json")
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
def test_aliases_limit(self):
|
||||
"""Check mailbox aliases limit."""
|
||||
self.client.credentials(
|
||||
HTTP_AUTHORIZATION='Token ' + self.da_token.key)
|
||||
|
||||
limit = self.user.userobjectlimit_set.get(name="mailbox_aliases")
|
||||
url = reverse("external_api:alias-list")
|
||||
data = {
|
||||
"address": "alias_fromapi@test.com",
|
||||
"recipients": [
|
||||
"user@test.com", "postmaster@test.com", "user_éé@nonlocal.com"
|
||||
]
|
||||
}
|
||||
response = self.client.post(url, data, format="json")
|
||||
self.assertEqual(response.status_code, 201)
|
||||
self.assertFalse(limit.is_exceeded())
|
||||
|
||||
data["address"] = "alias_fromapi2@test.com"
|
||||
response = self.client.post(url, data, format="json")
|
||||
self.assertEqual(response.status_code, 201)
|
||||
self.assertTrue(limit.is_exceeded())
|
||||
|
||||
data["address"] = "alias_fromapi3@test.com"
|
||||
response = self.client.post(url, data, format="json")
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
|
||||
class APIDomainLimitsTestCase(lib_tests.ModoAPITestCase):
|
||||
"""Check that limits are used also by the API."""
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
"""Create test data."""
|
||||
super(APIDomainLimitsTestCase, cls).setUpTestData()
|
||||
parameters.save_admin("ENABLE_DOMAIN_LIMITS", "yes")
|
||||
for name, tpl in utils.get_domain_limit_templates():
|
||||
parameters.save_admin(
|
||||
"DEFLT_DOMAIN_{}_LIMIT".format(name.upper()), 2)
|
||||
populate_database()
|
||||
|
||||
def test_mailboxes_limit(self):
|
||||
"""Check mailboxes limit."""
|
||||
domain = Domain.objects.get(name="test.com")
|
||||
limit = domain.domainobjectlimit_set.get(name="mailboxes")
|
||||
self.assertTrue(limit.is_exceeded())
|
||||
url = reverse("external_api:account-list")
|
||||
data = {
|
||||
"username": "fromapi@test.com",
|
||||
"role": "SimpleUsers",
|
||||
"password": "Toto1234",
|
||||
"mailbox": {
|
||||
"full_address": "fromapi@test.com",
|
||||
"quota": 10
|
||||
}
|
||||
}
|
||||
response = self.client.post(url, data, format="json")
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
def test_domain_aliases_limit(self):
|
||||
"""Check domain_aliases limit."""
|
||||
domain = Domain.objects.get(name="test.com")
|
||||
limit = domain.domainobjectlimit_set.get(name="domain_aliases")
|
||||
url = reverse("external_api:domain_alias-list")
|
||||
data = {"name": "dalias1.com", "target": domain.pk}
|
||||
response = self.client.post(url, data, format="json")
|
||||
self.assertEqual(response.status_code, 201)
|
||||
data["name"] = "dalias2.com"
|
||||
response = self.client.post(url, data, format="json")
|
||||
self.assertEqual(response.status_code, 201)
|
||||
self.assertTrue(limit.is_exceeded())
|
||||
data["name"] = "dalias3.com"
|
||||
response = self.client.post(url, data, format="json")
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
def test_mailbox_aliases_limit(self):
|
||||
"""Check mailbox_aliases limit."""
|
||||
domain = Domain.objects.get(name="test.com")
|
||||
limit = domain.domainobjectlimit_set.get(name="mailbox_aliases")
|
||||
self.assertTrue(limit.is_exceeded())
|
||||
url = reverse("external_api:alias-list")
|
||||
data = {
|
||||
"address": "alias_fromapi@test.com",
|
||||
"recipients": [
|
||||
"user@test.com", "postmaster@test.com", "user_éé@nonlocal.com"
|
||||
]
|
||||
}
|
||||
response = self.client.post(url, data, format="json")
|
||||
self.assertEqual(response.status_code, 400)
|
||||
@@ -0,0 +1,135 @@
|
||||
# coding: utf-8
|
||||
"""Test cases for the limits extension."""
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from modoboa.admin.factories import populate_database
|
||||
from modoboa.admin.models import Domain
|
||||
from modoboa.core.models import User
|
||||
from modoboa.lib import parameters
|
||||
from modoboa.lib import tests as lib_tests
|
||||
|
||||
from .. import utils
|
||||
|
||||
|
||||
class DomainLimitsTestCase(lib_tests.ModoTestCase):
|
||||
"""Per-domain limits tests."""
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
"""Create test data."""
|
||||
super(DomainLimitsTestCase, cls).setUpTestData()
|
||||
parameters.save_admin("ENABLE_DOMAIN_LIMITS", "yes")
|
||||
for name, tpl in utils.get_domain_limit_templates():
|
||||
parameters.save_admin(
|
||||
"DEFLT_DOMAIN_{}_LIMIT".format(name.upper()), 2)
|
||||
populate_database()
|
||||
|
||||
def test_set_limits(self):
|
||||
"""Try to set limits for a given domain."""
|
||||
domain = Domain.objects.get(name="test.com")
|
||||
values = {
|
||||
"name": domain.name, "quota": domain.quota,
|
||||
"enabled": domain.enabled, "type": "domain",
|
||||
"mailboxes_limit": 3, "mailbox_aliases_limit": 3,
|
||||
"domain_aliases_limit": 3
|
||||
}
|
||||
self.ajax_post(
|
||||
reverse("admin:domain_change", args=[domain.id]),
|
||||
values
|
||||
)
|
||||
domain.refresh_from_db()
|
||||
self.assertEqual(
|
||||
domain.domainobjectlimit_set.get(name="mailboxes").max_value, 3)
|
||||
self.assertEqual(
|
||||
domain.domainobjectlimit_set.get(
|
||||
name="mailbox_aliases").max_value, 3)
|
||||
self.assertEqual(
|
||||
domain.domainobjectlimit_set.get(
|
||||
name="domain_aliases").max_value, 3)
|
||||
|
||||
def test_domain_aliases_limit(self):
|
||||
"""Try to exceed defined limit."""
|
||||
# Import
|
||||
domain = Domain.objects.get(name="test.com")
|
||||
limit = domain.domainobjectlimit_set.get(name="domain_aliases")
|
||||
self.assertFalse(limit.is_exceeded())
|
||||
values = {
|
||||
"name": domain.name, "quota": domain.quota,
|
||||
"enabled": domain.enabled, "type": "domain",
|
||||
"mailboxes_limit": 2, "mailbox_aliases_limit": 2,
|
||||
"domain_aliases_limit": 2,
|
||||
"aliases": "alias1.com", "aliases_1": "alias2.com"
|
||||
}
|
||||
self.ajax_post(
|
||||
reverse("admin:domain_change", args=[domain.id]),
|
||||
values
|
||||
)
|
||||
self.assertTrue(limit.is_exceeded())
|
||||
values["aliases_2"] = "alias3.com"
|
||||
self.ajax_post(
|
||||
reverse("admin:domain_change", args=[domain.id]),
|
||||
values, 403
|
||||
)
|
||||
|
||||
def test_mailboxes_limit(self):
|
||||
"""Try to exceed defined limits."""
|
||||
# Import
|
||||
# LDAP ?
|
||||
domain = Domain.objects.get(name="test.com")
|
||||
domain.domainobjectlimit_set.filter(name="mailboxes").update(
|
||||
max_value=3)
|
||||
limit = domain.domainobjectlimit_set.get(name="mailboxes")
|
||||
self.assertFalse(limit.is_exceeded())
|
||||
username = "toto@test.com"
|
||||
values = {
|
||||
"username": username,
|
||||
"first_name": "Tester", "last_name": "Toto",
|
||||
"password1": "Toto1234", "password2": "Toto1234",
|
||||
"role": "SimpleUsers", "quota_act": True,
|
||||
"is_active": True, "email": username, "stepid": "step2",
|
||||
}
|
||||
self.ajax_post(reverse("admin:account_add"), values, 200)
|
||||
self.assertTrue(limit.is_exceeded())
|
||||
|
||||
username = "titi@test.com"
|
||||
self.ajax_post(reverse("admin:account_add"), values, 400)
|
||||
|
||||
def test_mailbox_aliases_limit(self):
|
||||
"""Try to exceed defined limits."""
|
||||
# Import
|
||||
domain = Domain.objects.get(name="test.com")
|
||||
user = User.objects.get(username="user@test.com")
|
||||
limit = domain.domainobjectlimit_set.get(name="mailbox_aliases")
|
||||
limit.max_value = 4
|
||||
limit.save()
|
||||
self.assertFalse(limit.is_exceeded())
|
||||
values = {
|
||||
"username": user.username, "role": user.group,
|
||||
"is_active": user.is_active, "email": user.email,
|
||||
"quota_act": True,
|
||||
"aliases": "alias@test.com", "aliases_1": "alias1@test.com"
|
||||
}
|
||||
self.ajax_post(
|
||||
reverse("admin:account_change", args=[user.id]),
|
||||
values
|
||||
)
|
||||
self.assertTrue(limit.is_exceeded())
|
||||
|
||||
values["aliases_2"] = "alias2@test.com"
|
||||
self.ajax_post(
|
||||
reverse("admin:account_change", args=[user.id]),
|
||||
values, 403
|
||||
)
|
||||
|
||||
limit.max_value = 5
|
||||
limit.save()
|
||||
values = {
|
||||
"address": "forward2@test.com", "recipients": "user@test.com",
|
||||
"enabled": True
|
||||
}
|
||||
self.ajax_post(reverse("admin:alias_add"), values)
|
||||
self.assertTrue(limit.is_exceeded())
|
||||
|
||||
values["address"] = "forward3@test.com"
|
||||
self.ajax_post(reverse("admin:alias_add"), values, 400)
|
||||
@@ -0,0 +1,104 @@
|
||||
# coding: utf-8
|
||||
from django.core.files.base import ContentFile
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from modoboa.admin import factories as admin_factories
|
||||
from modoboa.core import factories as core_factories
|
||||
from modoboa.core import models as core_models
|
||||
from modoboa.lib import parameters
|
||||
from modoboa.lib.tests import ModoTestCase
|
||||
|
||||
from .. import utils
|
||||
|
||||
|
||||
class UserLimitImportTestCase(ModoTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
"""Create test data."""
|
||||
super(UserLimitImportTestCase, cls).setUpTestData()
|
||||
for name, tpl in utils.get_user_limit_templates():
|
||||
parameters.save_admin(
|
||||
"DEFLT_USER_{}_LIMIT".format(name.upper()), 2)
|
||||
admin_factories.populate_database()
|
||||
cls.reseller = core_factories.UserFactory(
|
||||
username="reseller", groups=("Resellers", ))
|
||||
cls.dadmin = core_models.User.objects.get(username="admin@test.com")
|
||||
|
||||
def test_domains_import(self):
|
||||
"""Check domains limit."""
|
||||
self.client.login(
|
||||
username=self.reseller.username, password="toto")
|
||||
limit = self.reseller.userobjectlimit_set.get(name="domains")
|
||||
self.assertFalse(limit.is_exceeded())
|
||||
f = ContentFile(b"""domain; domain1.com; 100; True
|
||||
domain; domain2.com; 200; False
|
||||
""", name="domains.csv")
|
||||
self.client.post(
|
||||
reverse("admin:domain_import"), {
|
||||
"sourcefile": f
|
||||
}
|
||||
)
|
||||
self.assertTrue(limit.is_exceeded())
|
||||
|
||||
f = ContentFile(b"""domain; domain3.com; 100; True
|
||||
""", name="domains.csv")
|
||||
response = self.client.post(
|
||||
reverse("admin:domain_import"), {
|
||||
"sourcefile": f
|
||||
}
|
||||
)
|
||||
self.assertContains(response, "Domains: limit reached")
|
||||
|
||||
def test_domain_alias_import(self):
|
||||
"""Check domain aliases limit."""
|
||||
self.client.login(
|
||||
username=self.reseller.username, password="toto")
|
||||
limit = self.reseller.userobjectlimit_set.get(name="domain_aliases")
|
||||
self.assertFalse(limit.is_exceeded())
|
||||
f = ContentFile(b"""domainalias; domalias1.com; test.com; True
|
||||
domainalias; domalias2.com; test.com; True
|
||||
""", name="domains.csv")
|
||||
self.client.post(
|
||||
reverse("admin:domain_import"), {
|
||||
"sourcefile": f
|
||||
}
|
||||
)
|
||||
self.assertTrue(limit.is_exceeded())
|
||||
|
||||
f = ContentFile(
|
||||
"domainalias; domalias3.com; test.com; True", name="domains.csv")
|
||||
response = self.client.post(
|
||||
reverse("admin:domain_import"), {
|
||||
"sourcefile": f
|
||||
}
|
||||
)
|
||||
self.assertContains(response, "Domain aliases: limit reached")
|
||||
|
||||
def test_mailboxes_import(self):
|
||||
"""Check mailboxes limit."""
|
||||
self.client.login(
|
||||
username=self.dadmin.username, password="toto")
|
||||
limit = self.dadmin.userobjectlimit_set.get(name="mailboxes")
|
||||
self.assertFalse(limit.is_exceeded())
|
||||
f = ContentFile(b"""account; user1@test.com; toto; User; One; True; SimpleUsers; user1@test.com; 5
|
||||
account; truc@test.com; toto; René; Truc; True; SimpleUsers; truc@test.com; 5
|
||||
""", name="domains.csv")
|
||||
self.client.post(
|
||||
reverse("admin:identity_import"), {
|
||||
"sourcefile": f
|
||||
}
|
||||
)
|
||||
self.assertTrue(limit.is_exceeded())
|
||||
|
||||
f = ContentFile("""
|
||||
account; user3@test.com; toto; User; One; True; SimpleUsers; user3@test.com; 5
|
||||
""", name="domains.csv")
|
||||
response = self.client.post(
|
||||
reverse("admin:identity_import"), {
|
||||
"sourcefile": f
|
||||
}
|
||||
)
|
||||
self.assertContains(response, "Mailboxes: limit reached")
|
||||
|
||||
# FIXME: aliases, domain admins
|
||||
@@ -0,0 +1,422 @@
|
||||
# coding: utf-8
|
||||
"""Test cases for the limits extension."""
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from modoboa.admin.factories import populate_database
|
||||
from modoboa.admin.models import Alias, Domain
|
||||
from modoboa.core.factories import UserFactory
|
||||
from modoboa.core.models import User
|
||||
from modoboa.lib import parameters
|
||||
from modoboa.lib import tests as lib_tests
|
||||
|
||||
from .. import utils
|
||||
|
||||
|
||||
class PermissionsTestCase(lib_tests.ModoTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
"""Create test data."""
|
||||
super(PermissionsTestCase, cls).setUpTestData()
|
||||
populate_database()
|
||||
|
||||
def test_domainadmin_deletes_reseller(self):
|
||||
"""Check if a domain admin can delete a reseller.
|
||||
|
||||
Expected result: no.
|
||||
"""
|
||||
values = dict(
|
||||
username="reseller@test.com", first_name="Reseller", last_name="",
|
||||
password1="Toto1234", password2="Toto1234", role="Resellers",
|
||||
is_active=True, email="reseller@test.com", stepid='step2'
|
||||
)
|
||||
self.ajax_post(reverse("admin:account_add"), values)
|
||||
account = User.objects.get(username="reseller@test.com")
|
||||
self.client.logout()
|
||||
self.client.login(username="admin@test.com", password="toto")
|
||||
resp = self.ajax_post(
|
||||
reverse("admin:account_delete", args=[account.id]),
|
||||
{}, status=403
|
||||
)
|
||||
self.assertEqual(resp, "Permission denied")
|
||||
|
||||
|
||||
class ResourceTestCase(lib_tests.ModoTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
"""Custom setUpTestData method."""
|
||||
super(ResourceTestCase, cls).setUpTestData()
|
||||
for name, tpl in utils.get_user_limit_templates():
|
||||
parameters.save_admin(
|
||||
"DEFLT_USER_{0}_LIMIT".format(name.upper()), 2,
|
||||
app="limits"
|
||||
)
|
||||
populate_database()
|
||||
|
||||
def _create_account(self, username, role='SimpleUsers', status=200):
|
||||
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',
|
||||
)
|
||||
return self.ajax_post(
|
||||
reverse("admin:account_add"), values, status
|
||||
)
|
||||
|
||||
def _create_alias(self, email, rcpt='user@test.com', status=200):
|
||||
values = dict(
|
||||
address=email, recipients=rcpt, enabled=True
|
||||
)
|
||||
return self.ajax_post(
|
||||
reverse("admin:alias_add"), values, status
|
||||
)
|
||||
|
||||
def _create_domain(self, name, status=200, withtpl=False):
|
||||
values = {
|
||||
"name": name, "quota": 100, "create_dom_admin": "no",
|
||||
"create_aliases": "no", "stepid": 'step3', "type": "domain"
|
||||
}
|
||||
if withtpl:
|
||||
values['create_dom_admin'] = 'yes'
|
||||
values['dom_admin_username'] = 'admin'
|
||||
values['create_aliases'] = 'yes'
|
||||
response = self.ajax_post(
|
||||
reverse("admin:domain_add"), values, status
|
||||
)
|
||||
return response
|
||||
|
||||
def _domain_alias_operation(self, optype, domain, name, status=200):
|
||||
dom = Domain.objects.get(name=domain)
|
||||
values = {
|
||||
'name': dom.name, 'quota': dom.quota, 'enabled': dom.enabled,
|
||||
"type": "domain"
|
||||
}
|
||||
aliases = [alias.name for alias in dom.domainalias_set.all()]
|
||||
if optype == 'add':
|
||||
aliases.append(name)
|
||||
else:
|
||||
aliases.remove(name)
|
||||
for cpt, alias in enumerate(aliases):
|
||||
fname = 'aliases' if not cpt else 'aliases_%d' % cpt
|
||||
values[fname] = alias
|
||||
self.ajax_post(
|
||||
reverse("admin:domain_change", args=[dom.id]),
|
||||
values, status
|
||||
)
|
||||
|
||||
def _check_limit(self, name, curvalue, maxvalue):
|
||||
l = self.user.userobjectlimit_set.get(name=name)
|
||||
self.assertEqual(l.current_value, curvalue)
|
||||
self.assertEqual(l.max_value, maxvalue)
|
||||
|
||||
|
||||
class DomainAdminTestCase(ResourceTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
"""Create test data."""
|
||||
super(DomainAdminTestCase, cls).setUpTestData()
|
||||
cls.user = User.objects.get(username='admin@test.com')
|
||||
cls.user.userobjectlimit_set.filter(
|
||||
name__in=["mailboxes", "mailbox_aliases"]).update(max_value=2)
|
||||
|
||||
def setUp(self):
|
||||
"""Test initialization."""
|
||||
super(DomainAdminTestCase, self).setUp()
|
||||
self.client.logout()
|
||||
self.client.login(username='admin@test.com', password='toto')
|
||||
|
||||
def test_mailboxes_limit(self):
|
||||
self._create_account('tester1@test.com')
|
||||
self._check_limit('mailboxes', 1, 2)
|
||||
self._create_account('tester2@test.com')
|
||||
self._check_limit('mailboxes', 2, 2)
|
||||
self._create_account('tester3@test.com', status=403)
|
||||
self._check_limit('mailboxes', 2, 2)
|
||||
self.ajax_post(
|
||||
reverse('admin:account_delete',
|
||||
args=[User.objects.get(username='tester2@test.com').id]),
|
||||
{}
|
||||
)
|
||||
self._check_limit('mailboxes', 1, 2)
|
||||
|
||||
def test_aliases_limit(self):
|
||||
self._create_alias('alias1@test.com')
|
||||
self._check_limit('mailbox_aliases', 1, 2)
|
||||
self._create_alias('alias2@test.com')
|
||||
self._check_limit('mailbox_aliases', 2, 2)
|
||||
self._create_alias('alias3@test.com', status=403)
|
||||
self._check_limit('mailbox_aliases', 2, 2)
|
||||
self.ajax_post(
|
||||
reverse('admin:alias_delete') + '?selection=%d'
|
||||
% Alias.objects.get(address='alias2@test.com').id,
|
||||
{}
|
||||
)
|
||||
self._check_limit('mailbox_aliases', 1, 2)
|
||||
|
||||
def test_aliases_limit_through_account_form(self):
|
||||
user = User.objects.get(username='user@test.com')
|
||||
values = dict(
|
||||
username=user.username, role=user.group,
|
||||
is_active=user.is_active, email=user.email, quota_act=True,
|
||||
aliases="alias1@test.com", aliases_1="alias2@test.com"
|
||||
)
|
||||
self.ajax_post(
|
||||
reverse("admin:account_change", args=[user.id]),
|
||||
values
|
||||
)
|
||||
Alias.objects.get(address='alias1@test.com')
|
||||
self._check_limit('mailbox_aliases', 2, 2)
|
||||
|
||||
|
||||
class ResellerTestCase(ResourceTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
"""Create test data."""
|
||||
super(ResellerTestCase, cls).setUpTestData()
|
||||
cls.user = UserFactory(
|
||||
username='reseller', groups=('Resellers',)
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
"""Test initialization."""
|
||||
super(ResellerTestCase, self).setUp()
|
||||
self.client.logout()
|
||||
self.client.login(username='reseller', password='toto')
|
||||
|
||||
def test_domains_limit(self):
|
||||
response = self.client.get(reverse("admin:domain_list"))
|
||||
self.assertContains(response, "Domains (0%)")
|
||||
self.assertContains(response, "Domain aliases (0%)")
|
||||
self._create_domain('domain1.tld')
|
||||
self._check_limit('domains', 1, 2)
|
||||
self._create_domain('domain2.tld')
|
||||
self._check_limit('domains', 2, 2)
|
||||
self._create_domain('domain3.tld', 403)
|
||||
self._check_limit('domains', 2, 2)
|
||||
self.ajax_post(
|
||||
reverse('admin:domain_delete',
|
||||
args=[Domain.objects.get(name='domain2.tld').id]),
|
||||
{}
|
||||
)
|
||||
self._check_limit('domains', 1, 2)
|
||||
|
||||
def test_domain_aliases_limit(self):
|
||||
self._create_domain('pouet.com')
|
||||
self._domain_alias_operation('add', 'pouet.com', 'domain-alias1.tld')
|
||||
self._check_limit('domain_aliases', 1, 2)
|
||||
self._domain_alias_operation('add', 'pouet.com', 'domain-alias2.tld')
|
||||
self._check_limit('domain_aliases', 2, 2)
|
||||
self._domain_alias_operation(
|
||||
'add', 'pouet.com', 'domain-alias3.tld', 403
|
||||
)
|
||||
self._check_limit('domain_aliases', 2, 2)
|
||||
self._domain_alias_operation(
|
||||
'delete', 'pouet.com', 'domain-alias2.tld')
|
||||
self._check_limit('domain_aliases', 1, 2)
|
||||
|
||||
def test_domain_admins_limit(self):
|
||||
response = self.client.get(reverse("admin:identity_list"))
|
||||
self.assertContains(response, "Domain admins (0%)")
|
||||
self.assertContains(response, "Mailboxes (0%)")
|
||||
self.assertContains(response, "Mailbox aliases (0%)")
|
||||
|
||||
self._create_domain('domain.tld')
|
||||
self._create_account('admin1@domain.tld', role='DomainAdmins')
|
||||
self._check_limit('domain_admins', 1, 2)
|
||||
self._create_account('admin2@domain.tld', role='DomainAdmins')
|
||||
self._check_limit('domain_admins', 2, 2)
|
||||
resp = self._create_account(
|
||||
'admin3@domain.tld',
|
||||
role='DomainAdmins',
|
||||
status=400)
|
||||
self.assertEqual(
|
||||
resp['form_errors']['role'][0],
|
||||
'Select a valid choice. DomainAdmins is not one of the available '
|
||||
'choices.'
|
||||
)
|
||||
self._check_limit('domain_admins', 2, 2)
|
||||
|
||||
self.user.userobjectlimit_set.filter(
|
||||
name="mailboxes").update(max_value=3)
|
||||
self._create_account('user1@domain.tld')
|
||||
user = User.objects.get(username='user1@domain.tld')
|
||||
values = {
|
||||
'username': user.username, 'role': 'DomainAdmins',
|
||||
'quota_act': True, 'is_active': user.is_active,
|
||||
'email': user.email
|
||||
}
|
||||
resp = self.ajax_post(
|
||||
reverse("admin:account_change", args=[user.id]),
|
||||
values, status=400
|
||||
)
|
||||
self.assertEqual(
|
||||
resp['form_errors']['role'][0],
|
||||
'Select a valid choice. DomainAdmins is not one of the available '
|
||||
'choices.'
|
||||
)
|
||||
self._check_limit('domain_admins', 2, 2)
|
||||
|
||||
def test_domain_admin_resource_are_empty(self):
|
||||
self._create_domain('domain.tld')
|
||||
self._create_account('admin1@domain.tld', role='DomainAdmins')
|
||||
domadmin = User.objects.get(username='admin1@domain.tld')
|
||||
for l in ['mailboxes', 'mailbox_aliases']:
|
||||
self.assertEqual(
|
||||
domadmin.userobjectlimit_set.get(name=l).max_value, 0
|
||||
)
|
||||
|
||||
def test_domain_admins_limit_from_domain_tpl(self):
|
||||
self.user.userobjectlimit_set.filter(
|
||||
name="domains").update(max_value=3)
|
||||
self._create_domain('domain1.tld', withtpl=True)
|
||||
self._create_domain('domain2.tld', withtpl=True)
|
||||
self._check_limit('domain_admins', 2, 2)
|
||||
self._check_limit('domains', 2, 3)
|
||||
self._create_domain('domain3.tld', status=200, withtpl=True)
|
||||
self._check_limit('domain_admins', 2, 2)
|
||||
self._check_limit('domains', 3, 3)
|
||||
|
||||
def test_reseller_deletes_domain(self):
|
||||
"""Check if all resources are restored after the deletion.
|
||||
"""
|
||||
self._create_domain('domain.tld', withtpl=True)
|
||||
dom = Domain.objects.get(name="domain.tld")
|
||||
self.ajax_post(
|
||||
reverse("admin:domain_delete", args=[dom.id]),
|
||||
{}
|
||||
)
|
||||
self._check_limit('domains', 0, 2)
|
||||
self._check_limit('domain_admins', 1, 2)
|
||||
self._check_limit('mailboxes', 0, 2)
|
||||
self._check_limit('mailbox_aliases', 0, 2)
|
||||
|
||||
def test_sadmin_removes_ownership(self):
|
||||
self._create_domain('domain.tld', withtpl=True)
|
||||
dom = Domain.objects.get(name="domain.tld")
|
||||
self.client.logout()
|
||||
self.client.login(username='admin', password='password')
|
||||
self.ajax_get(
|
||||
"{0}?domid={1}&daid={2}".format(
|
||||
reverse('admin:permission_remove'),
|
||||
dom.id, self.user.id
|
||||
), {}
|
||||
)
|
||||
self._check_limit('domains', 0, 2)
|
||||
self._check_limit('domain_admins', 0, 2)
|
||||
self._check_limit('mailboxes', 0, 2)
|
||||
self._check_limit('mailbox_aliases', 0, 2)
|
||||
|
||||
def test_allocate_from_pool(self):
|
||||
self._create_domain('domain.tld')
|
||||
self._create_account('admin1@domain.tld', role='DomainAdmins')
|
||||
user = User.objects.get(username='admin1@domain.tld')
|
||||
|
||||
# Give 1 mailbox and 2 aliases to the admin -> should work
|
||||
values = {
|
||||
'username': user.username, 'role': user.group, 'quota_act': True,
|
||||
'is_active': user.is_active, 'email': user.email,
|
||||
'mailboxes_limit': 1, 'mailbox_aliases_limit': 2
|
||||
}
|
||||
self.ajax_post(
|
||||
reverse("admin:account_change", args=[user.id]),
|
||||
values
|
||||
)
|
||||
self._check_limit('mailboxes', 1, 1)
|
||||
self._check_limit('mailbox_aliases', 0, 0)
|
||||
|
||||
# Delete the admin -> resources should go back to the
|
||||
# reseller's pool
|
||||
self.ajax_post(
|
||||
reverse("admin:account_delete", args=[user.id]),
|
||||
{}
|
||||
)
|
||||
self._check_limit('mailboxes', 0, 2)
|
||||
self._check_limit('mailbox_aliases', 0, 2)
|
||||
|
||||
def test_restore_resources(self):
|
||||
"""Give resource to a domain admin and restore them."""
|
||||
self._create_domain('domain.tld')
|
||||
dom = Domain.objects.get(name='domain.tld')
|
||||
self._create_account('admin1@domain.tld', role='DomainAdmins')
|
||||
user = User.objects.get(username='admin1@domain.tld')
|
||||
values = {
|
||||
'username': user.username, 'role': user.group, 'quota_act': True,
|
||||
'is_active': user.is_active, 'email': user.email,
|
||||
'mailboxes_limit': 1, 'mailbox_aliases_limit': 2
|
||||
}
|
||||
self.ajax_post(
|
||||
reverse("admin:account_change", args=[user.id]),
|
||||
values
|
||||
)
|
||||
dom.add_admin(user)
|
||||
self.client.logout()
|
||||
self.client.login(username='admin1@domain.tld', password='Toto1234')
|
||||
self._create_account('user1@domain.tld')
|
||||
self._create_alias('alias1@domain.tld', 'user1@domain.tld')
|
||||
self._create_alias('alias2@domain.tld', 'user1@domain.tld')
|
||||
self.client.logout()
|
||||
self.client.login(username='reseller', password='toto')
|
||||
# Delete the admin -> resources should go back to the
|
||||
# reseller's pool
|
||||
self.ajax_post(
|
||||
reverse("admin:account_delete", args=[user.id]),
|
||||
{}
|
||||
)
|
||||
self._check_limit('mailboxes', 1, 2)
|
||||
self._check_limit('mailbox_aliases', 2, 2)
|
||||
|
||||
def test_change_role(self):
|
||||
self._create_domain('domain.tld')
|
||||
self._create_account('admin1@domain.tld', role='DomainAdmins')
|
||||
user = User.objects.get(username='admin1@domain.tld')
|
||||
|
||||
# Give 1 mailbox and 2 aliases to the admin -> should work
|
||||
values = {
|
||||
'username': user.username, 'role': user.group, 'quota_act': True,
|
||||
'is_active': user.is_active, 'email': user.email,
|
||||
'mailboxes_limit': 1, 'mailbox_aliases_limit': 2
|
||||
}
|
||||
self.ajax_post(
|
||||
reverse("admin:account_change", args=[user.id]),
|
||||
values
|
||||
)
|
||||
self._check_limit('mailboxes', 1, 1)
|
||||
self._check_limit('mailbox_aliases', 0, 0)
|
||||
|
||||
# Change admin role to SimpleUser -> resources should go back
|
||||
# to the reseller.
|
||||
values = {
|
||||
'username': user.username, 'role': 'SimpleUsers',
|
||||
'quota_act': True,
|
||||
'is_active': user.is_active, 'email': user.email,
|
||||
}
|
||||
self.ajax_post(
|
||||
reverse("admin:account_change", args=[user.id]),
|
||||
values
|
||||
)
|
||||
self._check_limit('mailboxes', 1, 2)
|
||||
self._check_limit('mailbox_aliases', 0, 2)
|
||||
|
||||
def test_allocate_too_much(self):
|
||||
self._create_domain('domain.tld')
|
||||
self._create_account('admin1@domain.tld', role='DomainAdmins')
|
||||
user = User.objects.get(username='admin1@domain.tld')
|
||||
|
||||
# Give 2 mailboxes and 3 aliases to the admin -> should fail.
|
||||
values = {
|
||||
'username': user.username, 'role': user.group, 'quota_act': True,
|
||||
'is_active': user.is_active, 'email': user.email,
|
||||
'mailboxes_limit': 2, 'mailbox_aliases_limit': 3
|
||||
}
|
||||
resp = self.ajax_post(
|
||||
reverse("admin:account_change", args=[user.id]),
|
||||
values, 424
|
||||
)
|
||||
self.assertEqual(resp, 'Not enough resources')
|
||||
self._check_limit('mailboxes', 1, 2)
|
||||
self._check_limit('mailbox_aliases', 0, 2)
|
||||
Reference in New Issue
Block a user