wip: resellers and limits

I've finally started to rethink the database structure. The goal I'm trying to reach: only use User objects to manage permissions and accesses to the webui and associate other objects to them if needed (like mailboxes).

see #105
This commit is contained in:
Antoine Nguyen
2012-01-20 17:33:05 +01:00
parent 2a0e9fdf3a
commit 3681bb4198
41 changed files with 1311 additions and 478 deletions
+61 -3
View File
@@ -8,17 +8,30 @@ This module provides a simple way of managing events between Modoboa
core application and additional components.
"""
from functools import wraps
import inspect
import re
events = [
"CanCreateDomain",
"CreateDomain",
"DeleteDomain",
"CanCreateDomainAlias",
"DomainAliasCreated",
"DomainAliasDeleted",
"CanCreateMailbox",
"CreateMailbox",
"DeleteMailbox",
"ModifyMailbox",
"GetUserDomains",
"CanCreateMailboxAlias",
"MailboxAliasCreated",
"MailboxAliasDeleted",
"DomainAdminCreated",
"PasswordChange",
"UserMenuDisplay",
@@ -33,7 +46,9 @@ events = [
"UserLogin",
"UserLogout",
"GetAnnouncement"
"GetAnnouncement",
"AdminFooterDisplay",
]
callbacks = {}
@@ -54,6 +69,49 @@ def register(event, callback):
callbacks[event].append(callback)
return 1
class observe(object):
"""Event observing decorator
Automatically register the decorated function to observe the given
event. If the decorated function is located into an extension, we
check before each call if the extension is enabled or not. If
that's not the case, the callback is not called.
.. note::
That's not a really optimized behaviour but I haven't found
another solution to achieve that feature.
:param evtname: the event's name
"""
def __init__(self, evtname):
self.evtname = evtname
def __guess_extension_name(self, modname):
if modname.startswith('modoboa.extensions'):
m = re.match(r'modoboa\.extensions\.([^\.]+)', modname)
if m:
return m.group(1)
return None
def __call__(self, f):
modname = inspect.getmodule(inspect.stack()[1][0]).__name__
extname = self.__guess_extension_name(modname)
@wraps(f)
def wrapped_f(*args):
if extname:
from modoboa.admin.models import Extension
try:
ext = Extension.objects.get(name=extname)
except Extension.DoesNotExist:
return []
if not ext.enabled:
return []
return f(*args)
register(self.evtname, wrapped_f)
return wrapped_f
def unregister(event, callback):
"""Unregister a callback for a specific event
+18
View File
@@ -0,0 +1,18 @@
# coding: utf-8
"""
:mod:`exceptions` --- Custom Modoboa exceptions
-----------------------------------------------
"""
from django.utils.translation import ugettext as _
class ModoboaException(Exception):
pass
class PermDeniedException(ModoboaException):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return _("Permission denied: %s" % self.msg)
+1
View File
@@ -33,6 +33,7 @@ Extracted from `this blog
one instance to another.
"""
import sys
import ldap
import re
import base64
+13
View File
@@ -3,6 +3,8 @@
import re
from django.http import Http404, HttpResponseRedirect
from modoboa.admin.models import Extension
from modoboa.lib.webutils import _render_error, ajax_response
from modoboa.lib.exceptions import ModoboaException
class ExtControlMiddleware(object):
def process_view(self, request, view, args, kwargs):
@@ -22,3 +24,14 @@ class AjaxLoginRedirect(object):
if type(response) == HttpResponseRedirect:
response.status_code = 278
return response
class CommonExceptionCatcher(object):
def process_exception(self, request, exception):
if not isinstance(exception, ModoboaException):
return None
if not request.is_ajax():
return _render_error(request, errortpl="error_simple",
user_context=dict(error=str(exception)))
return ajax_response(request, status="ko", respmsg=str(exception))