From 858fe43cddcacd5d8173eb21f4555d42ac0a2ae5 Mon Sep 17 00:00:00 2001 From: Antoine Nguyen Date: Tue, 20 Sep 2011 14:57:04 +0200 Subject: [PATCH] "Top redirection" feature. A new admin parameter is available to specify the default application that will be launched when no one is present in the url. (ie. when the top level "/" is called). fixed #165 --- admin/__init__.py | 21 +++++++++++++++++- admin/lib.py | 26 ++++++++++++---------- admin/models.py | 6 ++++- admin/views.py | 1 - extensions/__init__.py | 4 ++++ extensions/amavis_quarantine/main.py | 3 ++- extensions/postfix_autoreply/main.py | 3 ++- extensions/sievefilters/main.py | 3 ++- extensions/stats/main.py | 3 ++- extensions/webmail/main.py | 3 ++- lib/events.py | 3 +++ lib/webutils.py | 33 ++++++++++++++++++++++++++-- urls.py | 1 + 13 files changed, 88 insertions(+), 22 deletions(-) diff --git a/admin/__init__.py b/admin/__init__.py index fdfff4e76..03e469356 100644 --- a/admin/__init__.py +++ b/admin/__init__.py @@ -1,7 +1,8 @@ # -*- coding: utf-8 -*- -from modoboa.lib import parameters +from modoboa.lib import parameters, events from django.utils.translation import ugettext as _ +from models import Extension parameters.register_admin("STORAGE_PATH", type="string", deflt="/var/vmail", help=_("Path to the root directory where messages are stored")) @@ -19,3 +20,21 @@ parameters.register_admin("PASSWORD_SCHEME", type="list", deflt="crypt", help=_("Scheme used to crypt mailbox passwords")) parameters.register_admin("ITEMS_PER_PAGE", type="int", deflt=30, help=_("Number of displayed items per page")) + +parameters.register_admin("DEFAULT_TOP_REDIRECTION", type="list", deflt="admin", + app="general", + values=sorted([("admin", "admin"), ("userprefs", "userprefs")] \ + + map(lambda ext: (ext.name, ext.name), + Extension.objects.filter(enabled=True))), + help=_("The default redirection used when no application is specified")) + +def unset_default_topredirection(**kwargs): + """ + Simple callback to change the default redirection if the + corresponding extension is being disabled. + """ + topredirection = parameters.get_admin("DEFAULT_TOP_REDIRECTION", app="general") + if topredirection == kwargs["ext"].name: + parameters.save_admin("DEFAULT_TOP_REDIRECTION", "userprefs", app="general") + +events.register("ExtDisabled", unset_default_topredirection) diff --git a/admin/lib.py b/admin/lib.py index d85a4f9cd..84d838dd6 100644 --- a/admin/lib.py +++ b/admin/lib.py @@ -44,20 +44,22 @@ def good_domain(f): def dec(request, **kwargs): if request.user.is_superuser: return f(request, **kwargs) - mb = Mailbox.objects.get(user=request.user.id) - access = True - if request.GET.has_key("domid"): - dom_id = int(request.GET["domid"]) - if dom_id != mb.domain.id: - access = False - else: - q = request.GET.copy() - q["domid"] = mb.domain.id - request.GET = q - if access: - return f(request, **kwargs) + if is_domain_admin(request.user): + mb = Mailbox.objects.get(user=request.user.id) + access = True + if request.GET.has_key("domid"): + dom_id = int(request.GET["domid"]) + if dom_id != mb.domain.id: + access = False + else: + q = request.GET.copy() + q["domid"] = mb.domain.id + request.GET = q + if access: + return f(request, **kwargs) from django.conf import settings + from django.utils.http import urlquote path = urlquote(request.get_full_path()) login_url = settings.LOGIN_URL return HttpResponseRedirect("%s?next=%s" % (login_url, path)) diff --git a/admin/models.py b/admin/models.py index c127829d1..62e94cc78 100644 --- a/admin/models.py +++ b/admin/models.py @@ -3,7 +3,7 @@ from django.db import models, IntegrityError from django.contrib.auth.models import User from django.utils.translation import ugettext as _, ugettext_noop from django.conf import settings -from modoboa.lib import parameters +from modoboa.lib import parameters, events from modoboa.lib.sysutils import exec_cmd, exec_as_vuser from modoboa.lib.emailutils import split_mailbox from modoboa.auth.lib import crypt_password @@ -418,6 +418,8 @@ class Extension(models.Model): exec_cmd("ln -s %s/static %s/static/%s" % \ (extdir, settings.MODOBOA_DIR, self.name)) + events.raiseEvent("ExtEnabled", ext=self) + def off(self): self.unload() @@ -431,6 +433,8 @@ class Extension(models.Model): if os.path.exists(staticpath): exec_cmd("rm -r %s/static/%s" % (settings.MODOBOA_DIR, self.name)) + events.raiseEvent("ExtDisabled", ext=self) + # # Optional callback to execute if django-auth-ldap is enabled. # diff --git a/admin/views.py b/admin/views.py index 9edaf91c0..38ae790d3 100644 --- a/admin/views.py +++ b/admin/views.py @@ -2,7 +2,6 @@ from django.http import HttpResponse, HttpResponseRedirect from django.utils import simplejson from django.utils.translation import ugettext as _, ungettext -from django.utils.http import urlquote from django.core.urlresolvers import reverse from django.contrib.auth.decorators \ import login_required, permission_required, user_passes_test diff --git a/extensions/__init__.py b/extensions/__init__.py index aa9683894..0aa036685 100644 --- a/extensions/__init__.py +++ b/extensions/__init__.py @@ -6,6 +6,10 @@ from django.conf import settings def isinstalled(ext): return "modoboa.extensions.%s" % ext in settings.INSTALLED_APPS +def get_extension_infos(name): + ext = __import__(name, globals(), locals(), ["main"]) + return ext.main.infos() + def loadextensions(prefix): # To avoid a circular import... from modoboa.admin.models import Extension diff --git a/extensions/amavis_quarantine/main.py b/extensions/amavis_quarantine/main.py index 88c9e917b..7bf7d69a1 100644 --- a/extensions/amavis_quarantine/main.py +++ b/extensions/amavis_quarantine/main.py @@ -12,7 +12,8 @@ def infos(): return { "name" : "Amavis quarantine", "version" : "1.0", - "description" : ugettext("Simple amavis quarantine management tool") + "description" : ugettext("Simple amavis quarantine management tool"), + "url" : "quarantine" } def init(): diff --git a/extensions/postfix_autoreply/main.py b/extensions/postfix_autoreply/main.py index e3bdf5fdc..4b340ee27 100644 --- a/extensions/postfix_autoreply/main.py +++ b/extensions/postfix_autoreply/main.py @@ -18,7 +18,8 @@ def infos(): return { "name" : "Postfix autoreply", "version" : "1.0", - "description" : ugettext("Auto-reply (vacation) functionality using Postfix") + "description" : ugettext("Auto-reply (vacation) functionality using Postfix"), + "url" : "postfix_autoreply" } def init(): diff --git a/extensions/sievefilters/main.py b/extensions/sievefilters/main.py index 5edbc35c5..334d05069 100644 --- a/extensions/sievefilters/main.py +++ b/extensions/sievefilters/main.py @@ -39,7 +39,8 @@ def infos(): return { "name" : "Sieve filters", "version" : "1.0", - "description" : ugettext("Plugin to easily create server-side filters") + "description" : ugettext("Plugin to easily create server-side filters"), + "url" : "sfilters" } def urls(prefix): diff --git a/extensions/stats/main.py b/extensions/stats/main.py index 645a4a412..a6a260880 100644 --- a/extensions/stats/main.py +++ b/extensions/stats/main.py @@ -17,7 +17,8 @@ def infos(): return { "name" : "Statistics", "version" : "1.0", - "description" : ugettext("Graphical statistics about emails traffic using RRDtool") + "description" : ugettext("Graphical statistics about emails traffic using RRDtool"), + "url" : "stats" } def init(): diff --git a/extensions/webmail/main.py b/extensions/webmail/main.py index 95cb0410f..9caaf085c 100644 --- a/extensions/webmail/main.py +++ b/extensions/webmail/main.py @@ -73,7 +73,8 @@ def infos(): return { "name" : "Webmail", "version" : "1.0", - "description" : ugettext("Simple IMAP webmail") + "description" : ugettext("Simple IMAP webmail"), + "url" : "webmail" } def urls(prefix): diff --git a/lib/events.py b/lib/events.py index 6372f9be7..460e35276 100644 --- a/lib/events.py +++ b/lib/events.py @@ -18,6 +18,9 @@ events = ["CreateDomain", "PermsGetTables", "PermsGetClass", + "ExtEnabled", + "ExtDisabled", + "UserLogin", "UserLogout"] diff --git a/lib/webutils.py b/lib/webutils.py index c41b8d593..4059fa584 100644 --- a/lib/webutils.py +++ b/lib/webutils.py @@ -3,9 +3,10 @@ """ This module contains extra functions/shortcuts used to render HTML. """ -import sys +import os, sys import re -from django.http import HttpResponse +from django.http import HttpResponse, HttpResponseRedirect +from django.contrib.auth.decorators import login_required from django.shortcuts import render_to_response from django.template.loader import render_to_string from django import template @@ -141,3 +142,31 @@ def size2integer(value): if m.group(2)[0] in ["G", "g"]: return int(m.group(1)) * 2 ** 30 return 0 + +@login_required +def topredirection(request): + """Simple view to redirect the request when no application is specified + + The default "top redirection" can be specified in the *Admin > + Settings* panel. It is the application that will be launched by + default. Users that are not allowed to access this application + will be redirected to the "User preferences" application. + + :param request: a Request object + """ + from modoboa.lib import parameters + from modoboa.extensions import get_extension_infos + from modoboa.admin.lib import is_domain_admin + + topredir = parameters.get_admin("DEFAULT_TOP_REDIRECTION", app="general") + if not topredir in ["admin", "userprefs"]: + infos = get_extension_infos(topredir) + path = infos["url"] + else: + path = topredir + + if topredir in ["admin", "stats"] and \ + (not request.user.is_superuser and not is_domain_admin(request.user)): + path = "userprefs" + + return HttpResponseRedirect(path) diff --git a/urls.py b/urls.py index 5bccfd84c..351a141c7 100644 --- a/urls.py +++ b/urls.py @@ -11,6 +11,7 @@ if prefix != "": prefix += "/" urlpatterns = patterns('', + (r'^%s$' % prefix, 'modoboa.lib.webutils.topredirection'), (r'^%sadmin/' % prefix, include('modoboa.admin.urls')), (r'^%suserprefs/' % prefix, include('modoboa.userprefs.urls')), (r'^accounts/login/$', 'modoboa.auth.views.dologin'),