Domain admins limit added.

see #799
This commit is contained in:
Antoine Nguyen
2016-04-27 11:32:48 +02:00
parent d3c26b0f48
commit f1863e61a6
7 changed files with 94 additions and 32 deletions
+12 -5
View File
@@ -8,11 +8,13 @@ from django.utils.translation import ugettext as _, ugettext_lazy
import reversion
from .base import AdminObject
from modoboa.core.models import User, ObjectAccess
from modoboa.core import signals as core_signals
from modoboa.lib import events, parameters
from modoboa.lib.exceptions import BadRequest, Conflict
from .base import AdminObject
class DomainManager(Manager):
@@ -85,23 +87,28 @@ class Domain(AdminObject):
@property
def admins(self):
"""Return the domain administrators of this domain
"""Return the domain administrators of this domain.
:return: a list of User objects
"""
return [oa.user for oa in self.owners.filter(user__is_superuser=False)]
return User.objects.filter(
is_superuser=False,
objectaccess__content_type__model="domain",
objectaccess__object_id=self.pk)
@property
def aliases(self):
return self.domainalias_set
def add_admin(self, account):
"""Add a new administrator for this domain
"""Add a new administrator to this domain.
:param User account: the administrotor to add
:param User account: the administrator
"""
from modoboa.lib.permissions import grant_access_to_object
core_signals.can_create_object.send(
sender=self.__class__, context=self, object_type="domain_admins")
grant_access_to_object(account, self)
for mb in self.mailbox_set.all():
if mb.user.has_perm("admin.add_domain"):
+14 -11
View File
@@ -8,6 +8,8 @@ from modoboa.lib.parameters import AdminParametersForm
class ParametersForm(AdminParametersForm):
"""Available admin parameters."""
app = "limits"
defv_sep = SeparatorField(label=_("Default per-admin limits"))
@@ -79,17 +81,17 @@ class ParametersForm(AdminParametersForm):
help_text=_("Enable or disable per-domain limits")
)
# deflt_domain_domain_admins_limit = forms.IntegerField(
# label=_("Domain admins"),
# initial=0,
# help_text=_(
# "Maximum number of allowed domain administrators for a new "
# "domain. (0 to deny any creation, -1 to allow unlimited "
# "creations)"
# ),
# widget=forms.widgets.TextInput(
# attrs={"class": "col-md-1 form-control"})
# )
deflt_domain_domain_admins_limit = forms.IntegerField(
label=_("Domain admins"),
initial=0,
help_text=_(
"Maximum number of allowed domain administrators for a new "
"domain. (0 to deny any creation, -1 to allow unlimited "
"creations)"
),
widget=forms.widgets.TextInput(
attrs={"class": "col-md-1 form-control"})
)
deflt_domain_domain_aliases_limit = forms.IntegerField(
label=_("Domain aliases"),
initial=0,
@@ -131,6 +133,7 @@ class ParametersForm(AdminParametersForm):
"deflt_domain_mailboxes_limit": "enable_domain_limits=yes",
"deflt_domain_mailbox_aliases_limit": "enable_domain_limits=yes",
"deflt_domain_domain_aliases_limit": "enable_domain_limits=yes",
"deflt_domain_domain_admins_limit": "enable_domain_limits=yes",
}
def __init__(self, *args, **kwargs):
+4
View File
@@ -43,5 +43,9 @@ DEFAULT_DOMAIN_LIMITS = collections.OrderedDict((
"help": _(
"Maximum number of mailbox aliases allowed for this domain."),
"extra_filters": {"internal": False}
}),
("domain_admins", {
"relation": "admins", "label": _("Domain admins"),
"help": _("Maximum number of domain admins allowed for this domain."),
})
))
+5 -2
View File
@@ -5,7 +5,7 @@
"""
from modoboa.lib import events
from modoboa.lib import events, parameters
from modoboa.lib.permissions import get_object_owner
from . import utils
@@ -39,7 +39,10 @@ def user_can_set_role(user, role, account=None):
:param ``User`` account: account modified (None on creation)
:param str newrole: role to check
"""
if role != "DomainAdmins":
condition = (
parameters.get_admin("ENABLE_ADMIN_LIMITS") == "no" or
role != "DomainAdmins")
if condition:
return [True]
lname = "domain_admins"
condition = (
+14 -4
View File
@@ -12,7 +12,10 @@ from . import utils
def display_pool_usage(user, target, currentpage):
from django.template.loader import render_to_string
if target != "leftcol" or user.is_superuser:
condition = (
parameters.get_admin("ENABLE_ADMIN_LIMITS") == "no" or
target != "leftcol" or user.is_superuser)
if condition:
return []
if currentpage == "identities":
names = ["mailboxes", "mailbox_aliases"]
@@ -38,6 +41,8 @@ def display_pool_usage(user, target, currentpage):
@events.observe("ExtraAccountForm")
def extra_account_form(user, account=None):
if parameters.get_admin("ENABLE_ADMIN_LIMITS") == "no":
return []
if user.group not in ["SuperAdmins", "Resellers"]:
return []
if account is not None and \
@@ -85,16 +90,21 @@ def check_form_access(account, form):
@events.observe("FillAccountInstances")
def fill_account_instances(user, account, instances):
if not user.is_superuser and not user.belongs_to_group("Resellers"):
condition = (
parameters.get_admin("ENABLE_ADMIN_LIMITS") == "no" or
(not user.is_superuser and user.group != "Resellers")
)
if condition:
return
if not account.belongs_to_group("Resellers") and \
not account.belongs_to_group("DomainAdmins"):
if account.group not in ["Resellers", "DomainAdmins"]:
return
instances["resources"] = account
@events.observe("GetStaticContent")
def get_static_content(caller, st_type, user):
if parameters.get_admin("ENABLE_ADMIN_LIMITS") == "no":
return []
if caller not in ['domains', 'identities']:
return []
if user.group == "SimpleUsers":
+33 -4
View File
@@ -3,8 +3,9 @@
from django.core.urlresolvers import reverse
from modoboa.admin.factories import populate_database
from modoboa.admin import factories as admin_factories
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
@@ -19,11 +20,12 @@ class DomainLimitsTestCase(lib_tests.ModoTestCase):
def setUpTestData(cls):
"""Create test data."""
super(DomainLimitsTestCase, cls).setUpTestData()
parameters.save_admin("ENABLE_ADMIN_LIMITS", "no")
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()
admin_factories.populate_database()
def test_set_limits(self):
"""Try to set limits for a given domain."""
@@ -32,7 +34,7 @@ class DomainLimitsTestCase(lib_tests.ModoTestCase):
"name": domain.name, "quota": domain.quota,
"enabled": domain.enabled, "type": "domain",
"mailboxes_limit": 3, "mailbox_aliases_limit": 3,
"domain_aliases_limit": 3
"domain_aliases_limit": 3, "domain_admins_limit": 3
}
self.ajax_post(
reverse("admin:domain_change", args=[domain.id]),
@@ -47,6 +49,9 @@ class DomainLimitsTestCase(lib_tests.ModoTestCase):
self.assertEqual(
domain.domainobjectlimit_set.get(
name="domain_aliases").max_value, 3)
self.assertEqual(
domain.domainobjectlimit_set.get(
name="domain_admins").max_value, 3)
def test_domain_aliases_limit(self):
"""Try to exceed defined limit."""
@@ -57,7 +62,7 @@ class DomainLimitsTestCase(lib_tests.ModoTestCase):
"name": domain.name, "quota": domain.quota,
"enabled": domain.enabled, "type": "domain",
"mailboxes_limit": 2, "mailbox_aliases_limit": 2,
"domain_aliases_limit": 2,
"domain_aliases_limit": 2, "domain_admins_limit": 2,
"aliases": "alias1.com", "aliases_1": "alias2.com"
}
self.ajax_post(
@@ -71,6 +76,30 @@ class DomainLimitsTestCase(lib_tests.ModoTestCase):
values, 403
)
def test_domain_admins_limit(self):
"""Try to exceed defined limit."""
domain = Domain.objects.get(name="test.com")
limit = domain.domainobjectlimit_set.get(name="domain_admins")
self.assertFalse(limit.is_exceeded())
user = User.objects.get(username="admin@test2.com")
values = {
"username": user.username, "role": user.group,
"is_active": user.is_active, "email": user.email,
"quota_act": True, "domains": "test2.com",
"domains_1": "test.com"
}
self.ajax_post(
reverse("admin:account_change", args=[user.id]),
values
)
self.assertTrue(limit.is_exceeded())
user = core_factories.UserFactory(
username="admin1000@test.com", groups=("DomainAdmins", ))
self.ajax_post(
reverse("admin:account_change", args=[user.id]),
values, 400
)
def test_mailboxes_limit(self):
"""Try to exceed defined limits."""
domain = Domain.objects.get(name="test.com")
+12 -6
View File
@@ -50,15 +50,20 @@ domainalias; domalias2.com; {domain}; True
)
self.assertContains(response, "Domain aliases: limit reached")
def _test_domain_admins_import(self, limit):
def _test_domain_admins_import(self, limit, initial_count=0):
"""Check domain admins limit."""
self.client.login(
username=self.reseller.username, password="toto")
self.assertFalse(limit.is_exceeded())
f = ContentFile(b"""account; admin1@{domain}; toto; User; One; True; DomainAdmins; user1@{domain}; 5; {domain}
account; admin2@{domain}; toto; René; Truc; True; DomainAdmins; truc@{domain}; 5; {domain}
""".format(domain=self.domain), name="domain_admins.csv")
self.client.post(
content = ""
for cpt in xrange(initial_count, 2):
content += (
"account; admin{cpt}@{domain}; toto; User; One; True; "
"DomainAdmins; user{cpt}@{domain}; 5; {domain}\n"
.format(domain=self.domain, cpt=cpt)
)
f = ContentFile(content, name="domain_admins.csv")
response = self.client.post(
reverse("admin:identity_import"), {
"sourcefile": f
}
@@ -197,7 +202,6 @@ class DomainLimitImportTestCase(LimitImportTestCase):
user__username="user@test4.com",
domain__name="test4.com", address="user")
cls.domain = mb.domain
cls.domain.add_admin(cls.dadmin)
def test_domain_alias_import(self):
"""Check domain aliases limit."""
@@ -206,10 +210,12 @@ class DomainLimitImportTestCase(LimitImportTestCase):
def test_mailboxes_import(self):
"""Check mailboxes limit."""
self.domain.add_admin(self.dadmin)
limit = self.domain.domainobjectlimit_set.get(name="mailboxes")
self._test_mailboxes_import(limit)
def test_mailbox_aliases_import(self):
"""Check mailbox aliases limit."""
self.domain.add_admin(self.dadmin)
limit = self.domain.domainobjectlimit_set.get(name="mailbox_aliases")
self._test_mailbox_aliases_import(limit)