mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-17 05:41:25 +02:00
@@ -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"):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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,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 = (
|
||||
|
||||
@@ -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":
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user