mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-18 05:51:26 +02:00
wip: Big refactoring
Limits extension OK.
This commit is contained in:
@@ -63,7 +63,7 @@ def domains(request, tplname="admin/domains.html"):
|
||||
|
||||
|
||||
@login_required
|
||||
@permission_required("admin.add_user")
|
||||
@permission_required("core.add_user")
|
||||
def domains_list(request):
|
||||
doms = [dom.name for dom in Domain.objects.get_for_admin(request.user)]
|
||||
return ajax_simple_response(doms)
|
||||
|
||||
@@ -24,7 +24,7 @@ from modoboa.extensions.admin.forms import (
|
||||
|
||||
@login_required
|
||||
@user_passes_test(
|
||||
lambda u: u.has_perm("admin.add_user") or u.has_perm("admin.add_alias")
|
||||
lambda u: u.has_perm("core.add_user") or u.has_perm("admin.add_alias")
|
||||
)
|
||||
def _identities(request):
|
||||
idents_list = get_identities(request.user, request.GET)
|
||||
@@ -62,7 +62,7 @@ def identities(request, tplname="admin/identities.html"):
|
||||
|
||||
|
||||
@login_required
|
||||
@permission_required("admin.add_user")
|
||||
@permission_required("core.add_user")
|
||||
def accounts_list(request):
|
||||
accs = User.objects.filter(is_superuser=False) \
|
||||
.exclude(groups__name='SimpleUsers')
|
||||
@@ -107,7 +107,7 @@ def list_quotas(request, tplname="admin/quotas.html"):
|
||||
|
||||
|
||||
@login_required
|
||||
@permission_required("admin.add_user")
|
||||
@permission_required("core.add_user")
|
||||
@transaction.commit_on_success
|
||||
def newaccount(request, tplname='common/wizard_forms.html'):
|
||||
def create_account(steps):
|
||||
@@ -173,7 +173,7 @@ def newaccount(request, tplname='common/wizard_forms.html'):
|
||||
|
||||
|
||||
@login_required
|
||||
@permission_required("admin.change_user")
|
||||
@permission_required("core.change_user")
|
||||
@transaction.commit_on_success
|
||||
def editaccount(request, accountid, tplname="common/tabforms.html"):
|
||||
account = User.objects.get(pk=accountid)
|
||||
@@ -220,7 +220,7 @@ def editaccount(request, accountid, tplname="common/tabforms.html"):
|
||||
|
||||
|
||||
@login_required
|
||||
@permission_required("admin.delete_user")
|
||||
@permission_required("core.delete_user")
|
||||
@transaction.commit_on_success
|
||||
def delaccount(request, accountid):
|
||||
keepdir = True if request.POST.get("keepdir", "false") == "true" else False
|
||||
|
||||
@@ -10,39 +10,42 @@ from django.contrib.contenttypes.models import ContentType
|
||||
from django.utils.translation import ugettext as _, ugettext_lazy
|
||||
from django.core.urlresolvers import reverse
|
||||
from modoboa.lib import events, parameters
|
||||
from modoboa.extensions import ModoExtension, exts_pool
|
||||
from models import *
|
||||
from forms import ResourcePoolForm
|
||||
from modoboa.core.extensions import ModoExtension, exts_pool
|
||||
from .forms import ResourcePoolForm
|
||||
import controls
|
||||
import views
|
||||
|
||||
|
||||
class Limits(ModoExtension):
|
||||
name = "limits"
|
||||
label = "Limits"
|
||||
version = "1.0"
|
||||
description = ugettext_lazy("Per administrator resources to limit the number of objects they can create")
|
||||
description = ugettext_lazy(
|
||||
"Per administrator resources to limit the number of objects they can create"
|
||||
)
|
||||
|
||||
def init(self):
|
||||
from modoboa.admin.models import User, Domain
|
||||
|
||||
from modoboa.core.models import User
|
||||
from modoboa.extensions.admin.models import Domain
|
||||
|
||||
ct = ContentType.objects.get(app_label="admin", model="domain")
|
||||
dagrp = Group.objects.get(name="DomainAdmins")
|
||||
|
||||
|
||||
grp = Group(name="Resellers")
|
||||
grp.save()
|
||||
grp.permissions.add(*dagrp.permissions.all())
|
||||
|
||||
|
||||
ct = ContentType.objects.get_for_model(Permission)
|
||||
for pname in ["view_permissions"]:
|
||||
perm = Permission.objects.get(content_type=ct, codename=pname)
|
||||
grp.permissions.add(perm)
|
||||
|
||||
|
||||
ct = ContentType.objects.get_for_model(Domain)
|
||||
for pname in ["view_domains", "add_domain", "change_domain", "delete_domain"]:
|
||||
perm = Permission.objects.get(content_type=ct, codename=pname)
|
||||
grp.permissions.add(perm)
|
||||
grp.save()
|
||||
|
||||
|
||||
for user in User.objects.filter(groups__name='DomainAdmins'):
|
||||
try:
|
||||
controls.create_pool(user)
|
||||
@@ -50,7 +53,7 @@ class Limits(ModoExtension):
|
||||
pass
|
||||
|
||||
def load(self):
|
||||
from app_settings import ParametersForm
|
||||
from modoboa.extensions.limits.app_settings import ParametersForm
|
||||
parameters.register(ParametersForm, ugettext_lazy("Limits"))
|
||||
|
||||
def destroy(self):
|
||||
@@ -59,12 +62,14 @@ class Limits(ModoExtension):
|
||||
|
||||
exts_pool.register_extension(Limits)
|
||||
|
||||
|
||||
@events.observe("GetExtraRoles")
|
||||
def get_extra_roles(user):
|
||||
if user.is_superuser:
|
||||
return [("Resellers", _("Reseller")),]
|
||||
return [("Resellers", _("Reseller")), ]
|
||||
return []
|
||||
|
||||
|
||||
@events.observe("ExtraAdminContent")
|
||||
def display_pool_usage(user, target, currentpage):
|
||||
from django.template.loader import render_to_string
|
||||
@@ -82,6 +87,7 @@ def display_pool_usage(user, target, currentpage):
|
||||
return []
|
||||
return [render_to_string("limits/poolusage.html", dict(limits=limits))]
|
||||
|
||||
|
||||
@events.observe("ExtraAccountForm")
|
||||
def extra_account_form(user, account=None):
|
||||
if not user.group in ["SuperAdmins", "Resellers"]:
|
||||
@@ -95,6 +101,7 @@ def extra_account_form(user, account=None):
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
@events.observe("CheckExtraAccountForm")
|
||||
def check_form_access(account, form):
|
||||
if form["id"] != "resources":
|
||||
@@ -104,6 +111,7 @@ def check_form_access(account, form):
|
||||
return [False]
|
||||
return [True]
|
||||
|
||||
|
||||
@events.observe("FillAccountInstances")
|
||||
def fill_account_instances(user, account, instances):
|
||||
if not user.is_superuser and not user.belongs_to_group("Resellers"):
|
||||
@@ -113,6 +121,7 @@ def fill_account_instances(user, account, instances):
|
||||
return
|
||||
instances["resources"] = account
|
||||
|
||||
|
||||
@events.observe("GetStaticContent")
|
||||
def get_static_content(user):
|
||||
if user.group == "SimpleUsers":
|
||||
|
||||
@@ -5,15 +5,16 @@
|
||||
|
||||
"""
|
||||
from modoboa.lib import events
|
||||
from lib import *
|
||||
from models import *
|
||||
from modoboa.lib.permissions import get_object_owner
|
||||
from .lib import LimitReached
|
||||
from .models import limits_tpl, LimitsPool
|
||||
|
||||
|
||||
def check_limit(user, lname):
|
||||
"""Check if a user has reached a defined limit
|
||||
|
||||
We check if the user will not reach the given limit after this
|
||||
creation.
|
||||
creation.
|
||||
|
||||
Raise a ``LimitReached`` exception if the limit is reached.
|
||||
|
||||
@@ -25,12 +26,14 @@ def check_limit(user, lname):
|
||||
except LimitsPool.DoesNotExist:
|
||||
pass
|
||||
|
||||
|
||||
def inc_limit(user, lname):
|
||||
try:
|
||||
user.limitspool.inc_curvalue(lname)
|
||||
except LimitsPool.DoesNotExist:
|
||||
pass
|
||||
|
||||
|
||||
def dec_limit(user, lname):
|
||||
if user is None:
|
||||
return
|
||||
@@ -39,6 +42,7 @@ def dec_limit(user, lname):
|
||||
except LimitsPool.DoesNotExist:
|
||||
pass
|
||||
|
||||
|
||||
def move_pool_resource(owner, user):
|
||||
"""Move resource from one pool to another
|
||||
|
||||
@@ -61,10 +65,12 @@ def move_pool_resource(owner, user):
|
||||
|
||||
user.limitspool.delete()
|
||||
|
||||
|
||||
@events.observe('CreateDomain')
|
||||
def inc_nb_domains(user, domain):
|
||||
inc_limit(user, 'domains_limit')
|
||||
|
||||
|
||||
@events.observe('DeleteDomain')
|
||||
def dec_nb_domains(domain):
|
||||
owner = get_object_owner(domain)
|
||||
@@ -76,13 +82,15 @@ def dec_nb_domains(domain):
|
||||
for mbalias in domain.alias_set.all():
|
||||
dec_nb_mbaliases(mbalias)
|
||||
|
||||
|
||||
@events.observe('DomainAliasCreated')
|
||||
def inc_nb_domaliases(user, domalias):
|
||||
inc_limit(user, 'domain_aliases_limit')
|
||||
|
||||
|
||||
@events.observe('DomainAliasDeleted')
|
||||
def dec_nb_domaliases(domainaliases):
|
||||
from modoboa.admin.models import DomainAlias
|
||||
from modoboa.extensions.admin.models import DomainAlias
|
||||
|
||||
if isinstance(domainaliases, DomainAlias):
|
||||
domainaliases = [domainaliases]
|
||||
@@ -90,13 +98,15 @@ def dec_nb_domaliases(domainaliases):
|
||||
owner = get_object_owner(domainalias)
|
||||
dec_limit(owner, 'domain_aliases_limit')
|
||||
|
||||
|
||||
@events.observe('CreateMailbox')
|
||||
def inc_nb_mailboxes(user, mailbox):
|
||||
inc_limit(user, 'mailboxes_limit')
|
||||
|
||||
|
||||
@events.observe('DeleteMailbox')
|
||||
def dec_nb_mailboxes(mailboxes):
|
||||
from modoboa.admin.models import Mailbox
|
||||
from modoboa.extensions.admin.models import Mailbox
|
||||
|
||||
if isinstance(mailboxes, Mailbox):
|
||||
mailboxes = [mailboxes]
|
||||
@@ -104,21 +114,26 @@ def dec_nb_mailboxes(mailboxes):
|
||||
owner = get_object_owner(mailbox)
|
||||
dec_limit(owner, 'mailboxes_limit')
|
||||
|
||||
|
||||
@events.observe('MailboxAliasCreated')
|
||||
def inc_nb_mbaliases(user, mailboxalias):
|
||||
inc_limit(user, 'mailbox_aliases_limit')
|
||||
|
||||
|
||||
@events.observe('MailboxAliasDeleted')
|
||||
def dec_nb_mbaliases(mailboxalias):
|
||||
owner = get_object_owner(mailboxalias)
|
||||
dec_limit(owner, 'mailbox_aliases_limit')
|
||||
|
||||
|
||||
@events.observe('CanCreate')
|
||||
def can_create_new_object(user, objtype):
|
||||
check_limit(user, '%s_limit' % objtype)
|
||||
|
||||
|
||||
@events.observe("AccountCreated")
|
||||
def create_pool(user):
|
||||
print "pouet"
|
||||
owner = get_object_owner(user)
|
||||
if not owner.is_superuser and \
|
||||
not owner.belongs_to_group("Resellers"):
|
||||
@@ -133,9 +148,10 @@ def create_pool(user):
|
||||
p.save()
|
||||
p.create_limits()
|
||||
|
||||
|
||||
@events.observe("AccountModified")
|
||||
def on_account_modified(old, new):
|
||||
"""Update limits when roles are updated"""
|
||||
"""Update limits when roles are updated"""
|
||||
owner = get_object_owner(old)
|
||||
if owner.group not in ["SuperAdmins", "Resellers"]:
|
||||
# Domain admins can't change the role so nothing to check.
|
||||
@@ -158,13 +174,15 @@ def on_account_modified(old, new):
|
||||
if new.group != "DomainAdmins":
|
||||
dec_limit(owner, 'domain_admins_limit')
|
||||
return
|
||||
|
||||
|
||||
if new.group == "DomainAdmins":
|
||||
check_limit(owner, 'domain_admins_limit')
|
||||
inc_limit(owner, 'domain_admins_limit')
|
||||
|
||||
|
||||
@events.observe("AccountDeleted")
|
||||
def on_account_deleted(account):
|
||||
print "del"
|
||||
owner = get_object_owner(account)
|
||||
if not owner.group in ["SuperAdmins", "Resellers"]:
|
||||
return
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# coding: utf-8
|
||||
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import ugettext as _, ugettext_lazy
|
||||
from modoboa.lib import parameters
|
||||
from models import *
|
||||
from lib import *
|
||||
from .models import limits_tpl
|
||||
from .lib import BadLimitValue, UnsufficientResource
|
||||
|
||||
|
||||
class ResourcePoolForm(forms.Form):
|
||||
|
||||
@@ -8,6 +8,7 @@ from django.contrib.auth.models import Group
|
||||
from django.utils.translation import ugettext as _
|
||||
from modoboa.lib.exceptions import ModoboaException
|
||||
|
||||
|
||||
class LimitReached(ModoboaException):
|
||||
def __init__(self, limit):
|
||||
self.limit = limit
|
||||
@@ -15,6 +16,7 @@ class LimitReached(ModoboaException):
|
||||
def __str__(self):
|
||||
return _("%s: limit reached") % self.limit.label
|
||||
|
||||
|
||||
class UnsufficientResource(ModoboaException):
|
||||
def __init__(self, limit):
|
||||
self.limit = limit
|
||||
@@ -22,14 +24,6 @@ class UnsufficientResource(ModoboaException):
|
||||
def __str__(self):
|
||||
return _("Not enough resources")
|
||||
|
||||
|
||||
class BadLimitValue(ModoboaException):
|
||||
pass
|
||||
|
||||
def is_reseller(user):
|
||||
"""Tell if a user is a reseller or not
|
||||
|
||||
:param user: a User object
|
||||
:return: True if the user is a reseller, False otherwise.
|
||||
"""
|
||||
grp = Group.objects.get(name="Resellers")
|
||||
return grp in user.groups.all()
|
||||
|
||||
@@ -4,7 +4,7 @@ from django.db import models
|
||||
from django.contrib.contenttypes import generic
|
||||
from django.utils.translation import ugettext as _, ugettext_lazy
|
||||
from modoboa.lib import parameters
|
||||
from modoboa.admin.models import User
|
||||
from modoboa.core.models import User
|
||||
from django.conf import settings
|
||||
|
||||
limits_tpl = [
|
||||
@@ -13,7 +13,8 @@ limits_tpl = [
|
||||
("domain_aliases_limit", ugettext_lazy("Domain aliases")),
|
||||
("mailboxes_limit", ugettext_lazy("Mailboxes")),
|
||||
("mailbox_aliases_limit", ugettext_lazy("Mailbox aliases"))
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
class LimitsPool(models.Model):
|
||||
user = models.OneToOneField(settings.AUTH_USER_MODEL)
|
||||
@@ -74,6 +75,7 @@ class LimitsPool(models.Model):
|
||||
except Limit.DoesNotExist:
|
||||
return None
|
||||
|
||||
|
||||
class Limit(models.Model):
|
||||
name = models.CharField(max_length=255)
|
||||
curvalue = models.IntegerField(default=0)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from django.core.urlresolvers import reverse
|
||||
from modoboa.lib.tests import ExtTestCase
|
||||
from modoboa.admin.models import User
|
||||
from modoboa.core.models import User
|
||||
|
||||
|
||||
class PermissionsTestCase(ExtTestCase):
|
||||
@@ -21,9 +21,11 @@ class PermissionsTestCase(ExtTestCase):
|
||||
account = User.objects.get(username="reseller@test.com")
|
||||
self.clt.logout()
|
||||
self.clt.login(username="admin@test.com", password="toto")
|
||||
self.check_ajax_get(reverse("modoboa.admin.views.delaccount", args=[account.id]), {},
|
||||
status="ko", respmsg="Permission denied")
|
||||
self.check_ajax_get(reverse("modoboa.admin.views.delaccount", args=[4]), {},
|
||||
status="ko", respmsg="Permission denied")
|
||||
|
||||
|
||||
self.check_ajax_get(
|
||||
reverse("modoboa.extensions.admin.views.identity.delaccount", args=[account.id]),
|
||||
{}, status="ko", respmsg="Permission denied"
|
||||
)
|
||||
self.check_ajax_get(
|
||||
reverse("modoboa.extensions.admin.views.identity.delaccount", args=[4]),
|
||||
{}, status="ko", respmsg="Permission denied"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user