mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-18 05:51:26 +02:00
@@ -306,7 +306,7 @@ class AccountFormMail(forms.Form, DynamicForm):
|
||||
if not user.can_access(self.domain):
|
||||
raise lib_exceptions.PermDeniedException
|
||||
core_signals.can_create_object.send(
|
||||
self.__class__, context=user, object_type="mailboxes")
|
||||
self.__class__, context=user, klass=models.Mailbox)
|
||||
self.mb = models.Mailbox(
|
||||
address=self.locpart, domain=self.domain, user=account,
|
||||
use_domain_quota=self.cleaned_data["quota_act"])
|
||||
@@ -330,7 +330,7 @@ class AccountFormMail(forms.Form, DynamicForm):
|
||||
if not self.aliases:
|
||||
return
|
||||
core_signals.can_create_object.send(
|
||||
self.__class__, context=user, object_type="mailbox_aliases",
|
||||
self.__class__, context=user, klass=models.Alias,
|
||||
count=len(self.aliases))
|
||||
core_signals.can_create_object.send(
|
||||
self.__class__, context=self.mb.domain,
|
||||
|
||||
@@ -128,6 +128,8 @@ class DomainFormGeneral(forms.ModelForm, DynamicForm):
|
||||
|
||||
"""
|
||||
d = super(DomainFormGeneral, self).save(commit=False)
|
||||
core_signals.can_create_object.send(
|
||||
sender=self.__class__, context=user, klass=Domain, instance=d)
|
||||
if not commit:
|
||||
return d
|
||||
d.save()
|
||||
@@ -138,7 +140,7 @@ class DomainFormGeneral(forms.ModelForm, DynamicForm):
|
||||
self.aliases.remove(dalias.name)
|
||||
if self.aliases:
|
||||
core_signals.can_create_object.send(
|
||||
self.__class__, context=user, object_type="domain_aliases",
|
||||
self.__class__, context=user, klass=DomainAlias,
|
||||
count=len(self.aliases))
|
||||
core_signals.can_create_object.send(
|
||||
self.__class__, context=d, object_type="domain_aliases",
|
||||
@@ -224,7 +226,7 @@ class DomainFormOptions(forms.Form):
|
||||
else:
|
||||
raise Conflict(_("User '%s' already exists") % username)
|
||||
core_signals.can_create_object.send(
|
||||
self.__class__, context=user, object_type="mailboxes")
|
||||
self.__class__, context=user, klass=Mailbox)
|
||||
da = User(username=username, email=username, is_active=True)
|
||||
da.set_password(
|
||||
param_tools.get_global_parameter("default_password", app="core"))
|
||||
@@ -248,7 +250,7 @@ class DomainFormOptions(forms.Form):
|
||||
)
|
||||
if condition:
|
||||
core_signals.can_create_object.send(
|
||||
self.__class__, context=user, object_type="mailbox_aliases")
|
||||
self.__class__, context=user, klass=Alias)
|
||||
address = u"postmaster@{}".format(domain.name)
|
||||
alias = Alias.objects.create(
|
||||
address=address, domain=domain, enabled=True)
|
||||
|
||||
@@ -205,7 +205,7 @@ def import_account_mailbox(sender, user, account, row, **kwargs):
|
||||
if not user.can_access(domain):
|
||||
raise exceptions.PermDeniedException
|
||||
core_signals.can_create_object.send(
|
||||
sender="import", context=user, object_type="mailboxes")
|
||||
sender="import", context=user, klass=models.Mailbox)
|
||||
core_signals.can_create_object.send(
|
||||
sender="import", context=domain, object_type="mailboxes")
|
||||
account.save()
|
||||
|
||||
@@ -121,7 +121,7 @@ def import_domain(user, row, formopts):
|
||||
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")
|
||||
sender="import", context=user, klass=Domain)
|
||||
dom = Domain()
|
||||
dom.from_csv(user, row)
|
||||
|
||||
@@ -132,7 +132,7 @@ def import_domainalias(user, row, formopts):
|
||||
raise PermDeniedException(
|
||||
_("You are not allowed to import domain aliases."))
|
||||
core_signals.can_create_object.send(
|
||||
sender="import", context=user, object_type="domain_aliases")
|
||||
sender="import", context=user, klass=DomainAlias)
|
||||
domalias = DomainAlias()
|
||||
domalias.from_csv(user, row)
|
||||
|
||||
|
||||
@@ -180,7 +180,7 @@ class Alias(AdminObject):
|
||||
if not user.can_access(domain):
|
||||
raise PermDeniedException
|
||||
core_signals.can_create_object.send(
|
||||
sender="import", context=user, object_type="mailbox_aliases")
|
||||
sender="import", context=user, klass=Alias)
|
||||
core_signals.can_create_object.send(
|
||||
sender="import", context=domain, object_type="mailbox_aliases")
|
||||
if Alias.objects.filter(address=address).exists():
|
||||
|
||||
@@ -23,6 +23,18 @@ class AdminObject(models.Model):
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Custom constructor."""
|
||||
super(AdminObject, self).__init__(*args, **kwargs)
|
||||
self._loaded_values = {}
|
||||
|
||||
@classmethod
|
||||
def from_db(cls, db, field_names, values):
|
||||
"""Store loaded values."""
|
||||
instance = super(AdminObject, cls).from_db(db, field_names, values)
|
||||
instance._loaded_values = dict(zip(field_names, values))
|
||||
return instance
|
||||
|
||||
@property
|
||||
def objectname(self):
|
||||
if self._objectname is None:
|
||||
|
||||
@@ -266,6 +266,9 @@ class Domain(AdminObject):
|
||||
.format(self.name)
|
||||
)
|
||||
self.enabled = (row[4].strip() in ["True", "1", "yes", "y"])
|
||||
core_signals.can_create_object.send(
|
||||
sender=self.__class__, context=user, klass=Domain,
|
||||
instance=self)
|
||||
self.save(creator=user)
|
||||
|
||||
def to_csv(self, csvwriter):
|
||||
|
||||
@@ -30,7 +30,11 @@ class DomainSerializer(serializers.ModelSerializer):
|
||||
def create(self, validated_data):
|
||||
"""Set permissions."""
|
||||
domain = models.Domain(**validated_data)
|
||||
domain.save(creator=self.context["request"].user)
|
||||
creator = self.context["request"].user
|
||||
core_signals.can_create_object.send(
|
||||
sender=self.__class__, context=creator,
|
||||
klass=models.Domain, instance=domain)
|
||||
domain.save(creator=creator)
|
||||
return domain
|
||||
|
||||
|
||||
@@ -54,7 +58,7 @@ class DomainAliasSerializer(serializers.ModelSerializer):
|
||||
try:
|
||||
core_signals.can_create_object.send(
|
||||
sender=self.__class__, context=creator,
|
||||
object_type="domain_aliases")
|
||||
klass=models.DomainAlias)
|
||||
core_signals.can_create_object.send(
|
||||
sender=self.__class__, context=domain_alias.target,
|
||||
object_type="domain_aliases")
|
||||
@@ -231,7 +235,7 @@ class WritableAccountSerializer(AccountSerializer):
|
||||
try:
|
||||
core_signals.can_create_object.send(
|
||||
sender=self.__class__, context=creator,
|
||||
object_type="mailboxes")
|
||||
klass=admin_models.Mailbox)
|
||||
core_signals.can_create_object.send(
|
||||
sender=self.__class__, context=domain,
|
||||
object_type="mailboxes")
|
||||
@@ -324,7 +328,7 @@ class AliasSerializer(serializers.ModelSerializer):
|
||||
try:
|
||||
core_signals.can_create_object.send(
|
||||
sender=self.__class__, context=creator,
|
||||
object_type="mailbox_aliases")
|
||||
klass=admin_models.Alias)
|
||||
core_signals.can_create_object.send(
|
||||
sender=self.__class__, context=self.domain,
|
||||
object_type="mailbox_aliases")
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
{% extends "admin/header.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
{% load admin_tags %}
|
||||
{% load admin_tags i18n lib_tags %}
|
||||
|
||||
{% block extra_css %}
|
||||
{{ block.super }}
|
||||
{% extra_static_content "domains" "css" user %}
|
||||
{% endblock %}
|
||||
|
||||
{% block leftcol %}
|
||||
<ul class="nav nav-sidebar">
|
||||
|
||||
@@ -41,7 +41,7 @@ def _validate_alias(request, form, successmsg, callback=None):
|
||||
def _new_alias(request, title, action, successmsg,
|
||||
tplname="admin/aliasform.html"):
|
||||
core_signals.can_create_object.send(
|
||||
"new_alias", context=request.user, object_type="mailbox_aliases")
|
||||
"new_alias", context=request.user, klass=Alias)
|
||||
if request.method == "POST":
|
||||
def callback(user, alias):
|
||||
alias.post_create(user)
|
||||
|
||||
@@ -111,7 +111,7 @@ def domains_list(request):
|
||||
@reversion.create_revision()
|
||||
def newdomain(request):
|
||||
core_signals.can_create_object.send(
|
||||
"newdomain", context=request.user, object_type="domains")
|
||||
"newdomain", context=request.user, klass=Domain)
|
||||
return DomainWizard(request).process()
|
||||
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ account_password_updated = django.dispatch.Signal(
|
||||
providing_args=["account", "password", "created"])
|
||||
allow_password_change = django.dispatch.Signal(providing_args=["user"])
|
||||
can_create_object = django.dispatch.Signal(
|
||||
providing_args=["context", "object_type", "count"])
|
||||
providing_args=["context", "klass", "object_type", "count", "instance"])
|
||||
extra_account_actions = django.dispatch.Signal(providing_args=["account"])
|
||||
extra_admin_dashboard_widgets = django.dispatch.Signal(
|
||||
providing_args=["user"])
|
||||
|
||||
@@ -72,6 +72,16 @@ class ParametersForm(param_forms.AdminParametersForm):
|
||||
widget=forms.widgets.TextInput(
|
||||
attrs={"class": "col-md-1 form-control"})
|
||||
)
|
||||
deflt_user_quota_limit = forms.IntegerField(
|
||||
label=_("Quota"),
|
||||
initial=0,
|
||||
help_text=_(
|
||||
"The quota a reseller will be allowed to share between the "
|
||||
"domains he creates. (0 means no quota)"
|
||||
),
|
||||
widget=forms.widgets.TextInput(
|
||||
attrs={"class": "col-md-1 form-control"})
|
||||
)
|
||||
|
||||
domain_limits_sep = SeparatorField(label=_("Default per-domain limits"))
|
||||
|
||||
|
||||
@@ -26,7 +26,14 @@ DEFAULT_USER_LIMITS = collections.OrderedDict((
|
||||
"help": _("Maximum number of domain administrators this user "
|
||||
"can create"),
|
||||
"required_role": "Resellers",
|
||||
"extra_filters": {"groups__name": "DomainAdmins"}})
|
||||
"extra_filters": {"groups__name": "DomainAdmins"}}),
|
||||
("quota", {
|
||||
"content_type": "admin.domain", "label": _("Quota"),
|
||||
"help": _("Quota shared between domains of this reseller"),
|
||||
"required_role": "Resellers",
|
||||
"type": "sum",
|
||||
"field": "quota"
|
||||
})
|
||||
))
|
||||
|
||||
|
||||
|
||||
@@ -22,23 +22,25 @@ from . import utils
|
||||
|
||||
|
||||
@receiver(core_signals.can_create_object)
|
||||
def check_object_limit(sender, context, object_type, **kwargs):
|
||||
def check_object_limit(sender, context, **kwargs):
|
||||
"""Check if user can create a new object."""
|
||||
if context.__class__.__name__ == "User":
|
||||
if not param_tools.get_global_parameter("enable_admin_limits"):
|
||||
return
|
||||
if context.is_superuser:
|
||||
return True
|
||||
limit = context.userobjectlimit_set.get(name=object_type)
|
||||
ct = ContentType.objects.get_for_model(kwargs.get("klass"))
|
||||
limits = context.userobjectlimit_set.filter(content_type=ct)
|
||||
elif context.__class__.__name__ == "Domain":
|
||||
if not param_tools.get_global_parameter("enable_domain_limits"):
|
||||
return
|
||||
limit = context.domainobjectlimit_set.get(name=object_type)
|
||||
object_type = kwargs.get("object_type")
|
||||
limits = context.domainobjectlimit_set.filter(name=object_type)
|
||||
else:
|
||||
raise NotImplementedError
|
||||
count = kwargs.get("count", 1)
|
||||
if limit.is_exceeded(count):
|
||||
raise lib.LimitReached(limit)
|
||||
for limit in limits:
|
||||
if limit.is_exceeded(kwargs.get("count", 1), kwargs.get("instance")):
|
||||
raise lib.LimitReached(limit)
|
||||
|
||||
|
||||
@receiver(signals.post_save, sender=core_models.User)
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.5 on 2017-02-16 10:12
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
def create_quota_limits(apps, schema_editor):
|
||||
"""Create quota limits."""
|
||||
User = apps.get_model("core", "User")
|
||||
if not User.objects.exists():
|
||||
return
|
||||
ContentType = apps.get_model("contenttypes", "ContentType")
|
||||
UserObjectLimit = apps.get_model("limits", "UserObjectLimit")
|
||||
to_create = []
|
||||
ct = ContentType.objects.get(app_label="admin", model="domain")
|
||||
for u in User.objects.all():
|
||||
to_create.append(
|
||||
UserObjectLimit(user=u, name="quota", max_value=0, content_type=ct)
|
||||
)
|
||||
UserObjectLimit.objects.bulk_create(to_create)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('limits', '0005_auto_20160415_1654'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(create_quota_limits)
|
||||
]
|
||||
@@ -21,6 +21,11 @@ class ObjectLimitMixin(object):
|
||||
"""Return display name."""
|
||||
return self.definition["label"]
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
"""Return limit type."""
|
||||
return self.definition.get("type", "count")
|
||||
|
||||
@property
|
||||
def usage(self):
|
||||
"""Return current limit usage in %."""
|
||||
@@ -30,12 +35,21 @@ class ObjectLimitMixin(object):
|
||||
return 100
|
||||
return int(float(self.current_value) / self.max_value * 100)
|
||||
|
||||
def is_exceeded(self, count=1):
|
||||
"""Check if limit will be reached if we add count object(s)."""
|
||||
return (
|
||||
self.max_value != -1 and
|
||||
self.current_value + 1 > self.max_value
|
||||
)
|
||||
def is_exceeded(self, count=1, instance=None):
|
||||
"""Check if limit will be reached if we add this object."""
|
||||
if self.type == "count":
|
||||
if self.max_value == -1:
|
||||
return False
|
||||
return self.current_value + count > self.max_value
|
||||
if self.max_value == 0 or instance is None:
|
||||
return False
|
||||
field = self.definition["field"]
|
||||
value = getattr(instance, field)
|
||||
try:
|
||||
old_value = instance._loaded_values[field]
|
||||
except (AttributeError, KeyError):
|
||||
old_value = 0
|
||||
return self.current_value + (value - old_value) > self.max_value
|
||||
|
||||
def __str__(self):
|
||||
"""Display current usage."""
|
||||
@@ -67,7 +81,10 @@ class UserObjectLimit(ObjectLimitMixin, models.Model):
|
||||
@property
|
||||
def current_value(self):
|
||||
"""Return the current number of objects."""
|
||||
if "extra_filters" not in self.definition:
|
||||
condition = (
|
||||
self.type == "count" and
|
||||
"extra_filters" not in self.definition)
|
||||
if condition:
|
||||
return core_models.ObjectAccess.objects.filter(
|
||||
user=self.user, is_owner=True,
|
||||
content_type=self.content_type).count()
|
||||
@@ -75,8 +92,14 @@ class UserObjectLimit(ObjectLimitMixin, models.Model):
|
||||
user=self.user, is_owner=True,
|
||||
content_type=self.content_type).values_list("object_id", flat=True)
|
||||
model_class = self.content_type.model_class()
|
||||
return model_class.objects.filter(
|
||||
pk__in=id_list, **self.definition["extra_filters"]).count()
|
||||
if self.type == "count":
|
||||
return model_class.objects.filter(
|
||||
pk__in=id_list, **self.definition["extra_filters"]).count()
|
||||
qset = model_class.objects.filter(pk__in=id_list)
|
||||
if not qset.exists():
|
||||
return 0
|
||||
return qset.aggregate(
|
||||
total=models.Sum(self.definition["field"]))["total"]
|
||||
|
||||
@property
|
||||
def label(self):
|
||||
|
||||
@@ -79,16 +79,19 @@ class APIAdminLimitsTestCase(lib_tests.ModoAPITestCase):
|
||||
self.client.credentials(
|
||||
HTTP_AUTHORIZATION='Token ' + self.r_token.key)
|
||||
limit = self.reseller.userobjectlimit_set.get(name="domains")
|
||||
quota = self.reseller.userobjectlimit_set.get(name="quota")
|
||||
url = reverse("external_api:domain-list")
|
||||
data = {"name": "test3.com", "quota": 10}
|
||||
data = {"name": "test3.com", "quota": 1}
|
||||
response = self.client.post(url, data, format="json")
|
||||
self.assertEqual(response.status_code, 201)
|
||||
self.assertFalse(limit.is_exceeded())
|
||||
self.assertFalse(quota.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())
|
||||
self.assertFalse(quota.is_exceeded())
|
||||
|
||||
data["username"] = "test5.com"
|
||||
response = self.client.post(url, data, format="json")
|
||||
|
||||
@@ -26,8 +26,7 @@ class LimitImportTestCase(ModoTestCase):
|
||||
|
||||
def _test_domain_alias_import(self, limit):
|
||||
"""Check domain aliases limit."""
|
||||
self.client.login(
|
||||
username=self.reseller.username, password="toto")
|
||||
self.client.force_login(self.reseller)
|
||||
self.assertFalse(limit.is_exceeded())
|
||||
f = ContentFile(b"""domainalias; domalias1.com; {domain}; True
|
||||
domainalias; domalias2.com; {domain}; True
|
||||
@@ -51,8 +50,7 @@ domainalias; domalias2.com; {domain}; True
|
||||
|
||||
def _test_domain_admins_import(self, limit, initial_count=0):
|
||||
"""Check domain admins limit."""
|
||||
self.client.login(
|
||||
username=self.reseller.username, password="toto")
|
||||
self.client.force_login(self.reseller)
|
||||
self.assertFalse(limit.is_exceeded())
|
||||
content = ""
|
||||
for cpt in xrange(initial_count, 2):
|
||||
@@ -80,12 +78,15 @@ domainalias; domalias2.com; {domain}; True
|
||||
|
||||
def _test_mailboxes_import(self, limit):
|
||||
"""Check mailboxes limit."""
|
||||
self.client.login(
|
||||
username=self.dadmin.username, password="toto")
|
||||
self.client.force_login(self.dadmin)
|
||||
self.assertFalse(limit.is_exceeded())
|
||||
f = ContentFile(b"""account; user1@{domain}; toto; User; One; True; SimpleUsers; user1@{domain}; 5
|
||||
account; truc@{domain}; toto; René; Truc; True; SimpleUsers; truc@{domain}; 5
|
||||
""".format(domain=self.domain), name="domains.csv")
|
||||
f = ContentFile(
|
||||
"account; user1@{domain}; toto; User; One; True; SimpleUsers; "
|
||||
"user1@{domain}; 5\r\n"
|
||||
"account; truc@{domain}; toto; René; Truc; True; SimpleUsers; "
|
||||
"truc@{domain}; 5\r\n".format(domain=self.domain),
|
||||
name="domains.csv"
|
||||
)
|
||||
response = self.client.post(
|
||||
reverse("admin:identity_import"), {
|
||||
"sourcefile": f
|
||||
@@ -105,8 +106,7 @@ account; user3@{domain}; toto; User; One; True; SimpleUsers; user3@{domain}; 5
|
||||
|
||||
def _test_mailbox_aliases_import(self, limit):
|
||||
"""Check mailbox aliases limit."""
|
||||
self.client.login(
|
||||
username=self.dadmin.username, password="toto")
|
||||
self.client.force_login(self.dadmin)
|
||||
self.assertFalse(limit.is_exceeded())
|
||||
f = ContentFile(b"""alias; alias1@{domain}; True; user@{domain}
|
||||
alias; alias2@{domain}; True; user@{domain}
|
||||
@@ -143,26 +143,26 @@ class UserLimitImportTestCase(LimitImportTestCase):
|
||||
|
||||
def test_domains_import(self):
|
||||
"""Check domains limit."""
|
||||
self.client.login(
|
||||
username=self.reseller.username, password="toto")
|
||||
self.client.force_login(self.reseller)
|
||||
limit = self.reseller.userobjectlimit_set.get(name="domains")
|
||||
self.assertFalse(limit.is_exceeded())
|
||||
f = ContentFile(b"""domain; domain1.com; 1000; 100; True
|
||||
domain; domain2.com; 1000; 200; False
|
||||
""", name="domains.csv")
|
||||
f = ContentFile("domain; domain1.com; 1; 1; True", name="domains.csv")
|
||||
self.client.post(
|
||||
reverse("admin:domain_import"), {
|
||||
"sourcefile": f
|
||||
}
|
||||
reverse("admin:domain_import"), {"sourcefile": f}
|
||||
)
|
||||
self.assertTrue(limit.is_exceeded())
|
||||
self.assertFalse(limit.is_exceeded())
|
||||
|
||||
f = ContentFile(b"""domain; domain3.com; 1000; 100; True
|
||||
f = ContentFile("domain; domain2.com; 2; 1; True", name="domains.csv")
|
||||
response = self.client.post(
|
||||
reverse("admin:domain_import"), {"sourcefile": f}
|
||||
)
|
||||
self.assertContains(response, "Quota: limit reached")
|
||||
|
||||
f = ContentFile(b"""domain; domain2.com; 1; 1; True
|
||||
domain; domain3.com; 1000; 100; True
|
||||
""", name="domains.csv")
|
||||
response = self.client.post(
|
||||
reverse("admin:domain_import"), {
|
||||
"sourcefile": f
|
||||
}
|
||||
reverse("admin:domain_import"), {"sourcefile": f}
|
||||
)
|
||||
self.assertContains(response, "Domains: limit reached")
|
||||
|
||||
|
||||
@@ -76,9 +76,9 @@ class ResourceTestCase(lib_tests.ModoTestCase):
|
||||
reverse("admin:alias_add"), values, status
|
||||
)
|
||||
|
||||
def _create_domain(self, name, status=200, withtpl=False):
|
||||
def _create_domain(self, name, status=200, withtpl=False, quota=100):
|
||||
values = {
|
||||
"name": name, "quota": 100, "default_mailbox_quota": 10,
|
||||
"name": name, "quota": quota, "default_mailbox_quota": 10,
|
||||
"create_dom_admin": False,
|
||||
"create_aliases": False, "stepid": "step3", "type": "domain"
|
||||
}
|
||||
@@ -132,8 +132,7 @@ class DomainAdminTestCase(ResourceTestCase):
|
||||
def setUp(self):
|
||||
"""Test initialization."""
|
||||
super(DomainAdminTestCase, self).setUp()
|
||||
self.client.logout()
|
||||
self.client.login(username='admin@test.com', password='toto')
|
||||
self.client.force_login(self.user)
|
||||
|
||||
def test_mailboxes_limit(self):
|
||||
self._create_account('tester1@test.com')
|
||||
@@ -182,6 +181,11 @@ class DomainAdminTestCase(ResourceTestCase):
|
||||
Alias.objects.get(address='alias1@test.com')
|
||||
self._check_limit('mailbox_aliases', 2, 2)
|
||||
|
||||
def test_quota(self):
|
||||
"""Check that quota limit does not exist."""
|
||||
self.assertFalse(
|
||||
self.user.userobjectlimit_set.filter(name="quota").exists())
|
||||
|
||||
|
||||
class ResellerTestCase(ResourceTestCase):
|
||||
|
||||
@@ -189,6 +193,8 @@ class ResellerTestCase(ResourceTestCase):
|
||||
def setUpTestData(cls):
|
||||
"""Create test data."""
|
||||
super(ResellerTestCase, cls).setUpTestData()
|
||||
cls.localconfig.parameters.set_value("deflt_user_quota_limit", 1000)
|
||||
cls.localconfig.save()
|
||||
cls.user = UserFactory(
|
||||
username='reseller', groups=('Resellers',)
|
||||
)
|
||||
@@ -196,8 +202,7 @@ class ResellerTestCase(ResourceTestCase):
|
||||
def setUp(self):
|
||||
"""Test initialization."""
|
||||
super(ResellerTestCase, self).setUp()
|
||||
self.client.logout()
|
||||
self.client.login(username='reseller', password='toto')
|
||||
self.client.force_login(self.user)
|
||||
|
||||
def test_domains_limit(self):
|
||||
response = self.client.get(reverse("admin:domain_list"))
|
||||
@@ -292,9 +297,23 @@ class ResellerTestCase(ResourceTestCase):
|
||||
self._check_limit('domain_admins', 2, 2)
|
||||
self._check_limit('domains', 3, 3)
|
||||
|
||||
def test_quota(self):
|
||||
"""Check quota resource."""
|
||||
self._create_domain("domain1.tld", withtpl=True, quota=1000)
|
||||
response = self._create_domain(
|
||||
"domain2.tld", status=403, withtpl=True, quota=1000)
|
||||
self.assertEqual(response, "Quota: limit reached")
|
||||
dom1 = Domain.objects.get(name="domain1.tld")
|
||||
url = reverse("admin:domain_change", args=[dom1.pk])
|
||||
values = {
|
||||
"name": dom1.name, "type": dom1.type, "enabled": dom1.enabled,
|
||||
"default_mailbox_quota": dom1.default_mailbox_quota,
|
||||
"quota": 500
|
||||
}
|
||||
self.ajax_post(url, values)
|
||||
|
||||
def test_reseller_deletes_domain(self):
|
||||
"""Check if all resources are restored after the deletion.
|
||||
"""
|
||||
"""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(
|
||||
|
||||
Reference in New Issue
Block a user