From 75ecddf8791b1eb2722538530d9cb015e225f9a4 Mon Sep 17 00:00:00 2001 From: Antoine Nguyen Date: Fri, 18 Oct 2013 16:09:29 +0200 Subject: [PATCH] Initial support of relay domains. see #491 --- modoboa/core/templatetags/core_tags.py | 12 -- modoboa/demo/__init__.py | 9 +- modoboa/extensions/admin/__init__.py | 5 + modoboa/extensions/admin/lib.py | 30 +++- .../admin/migrations/0037_rename_tables.py | 7 + modoboa/extensions/admin/models/__init__.py | 4 +- modoboa/extensions/admin/models/domain.py | 4 + .../extensions/admin/static/admin/js/admin.js | 125 +++++++++++------ .../admin/templates/admin/domains.html | 1 + .../admin/templates/admin/domains_table.html | 21 +++ .../admin/templates/admin/identities.html | 1 + .../admin/templates/admin/listing.html | 2 +- .../admin/templatetags/admin_tags.py | 92 ++++++++++--- modoboa/extensions/admin/views/domain.py | 31 +++-- modoboa/extensions/amavis/__init__.py | 40 +++--- modoboa/extensions/limits/__init__.py | 8 +- .../postfix_relay_domains/__init__.py | 118 ++++++++++++++++ .../postfix_relay_domains/app_settings.py | 14 ++ .../extensions/postfix_relay_domains/forms.py | 12 ++ .../postfix_relay_domains/models.py | 129 ++++++++++++++++++ .../postfix_relay_domains/js/relay_domains.js | 79 +++++++++++ .../relaydomain_form.html | 7 + .../postfix_relay_domains/service_field.html | 2 + .../extensions/postfix_relay_domains/tests.py | 16 +++ .../extensions/postfix_relay_domains/urls.py | 9 ++ .../extensions/postfix_relay_domains/views.py | 87 ++++++++++++ modoboa/lib/events.py | 4 +- modoboa/lib/templatetags/lib_tags.py | 18 +++ modoboa/lib/webutils.py | 11 ++ modoboa/static/js/global.js | 77 ++++++++++- modoboa/templates/common/generic_field.html | 1 + modoboa/templates/nlayout.html | 2 +- 32 files changed, 864 insertions(+), 114 deletions(-) create mode 100644 modoboa/extensions/admin/templates/admin/domains_table.html create mode 100644 modoboa/extensions/postfix_relay_domains/__init__.py create mode 100644 modoboa/extensions/postfix_relay_domains/app_settings.py create mode 100644 modoboa/extensions/postfix_relay_domains/forms.py create mode 100644 modoboa/extensions/postfix_relay_domains/models.py create mode 100644 modoboa/extensions/postfix_relay_domains/static/postfix_relay_domains/js/relay_domains.js create mode 100644 modoboa/extensions/postfix_relay_domains/templates/postfix_relay_domains/relaydomain_form.html create mode 100644 modoboa/extensions/postfix_relay_domains/templates/postfix_relay_domains/service_field.html create mode 100644 modoboa/extensions/postfix_relay_domains/tests.py create mode 100644 modoboa/extensions/postfix_relay_domains/urls.py create mode 100644 modoboa/extensions/postfix_relay_domains/views.py diff --git a/modoboa/core/templatetags/core_tags.py b/modoboa/core/templatetags/core_tags.py index 91238b489..b424c1f9f 100644 --- a/modoboa/core/templatetags/core_tags.py +++ b/modoboa/core/templatetags/core_tags.py @@ -230,18 +230,6 @@ def get_modoboa_logo(): return logo -@register.simple_tag -def extra_head_content(user): - tpl = template.Template( - "{% for sc in static_content %}{{ sc|safe }}{% endfor %}" - ) - return tpl.render( - template.Context({ - 'static_content': events.raiseQueryEvent("GetStaticContent", user) - }) - ) - - @register.simple_tag def load_optionalmenu(user): menu = events.raiseQueryEvent("UserMenuDisplay", "top_menu_middle", user) diff --git a/modoboa/demo/__init__.py b/modoboa/demo/__init__.py index 76f5c05b4..ca8931b96 100755 --- a/modoboa/demo/__init__.py +++ b/modoboa/demo/__init__.py @@ -43,12 +43,13 @@ def password_change(user): @events.observe("GetStaticContent") -def get_static_content(user): - if not user.mailbox_set.count(): +def get_static_content(caller, user): + if caller != 'top' and not user.mailbox_set.count(): return [] - return """""" +"""] diff --git a/modoboa/extensions/admin/__init__.py b/modoboa/extensions/admin/__init__.py index 79c8fad5d..c567fc059 100644 --- a/modoboa/extensions/admin/__init__.py +++ b/modoboa/extensions/admin/__init__.py @@ -15,6 +15,11 @@ admin_events = [ "CreateDomain", "DomainModified", "DeleteDomain", + "ExtraDomainEntries", + "ExtraDomainMenuEntries", + "ExtraDomainFilters", + "GetDomainActions", + "GetDomainModifyLink", "DomainAliasCreated", "DomainAliasDeleted", diff --git a/modoboa/extensions/admin/lib.py b/modoboa/extensions/admin/lib.py index 758371f13..bf142a297 100644 --- a/modoboa/extensions/admin/lib.py +++ b/modoboa/extensions/admin/lib.py @@ -1,13 +1,16 @@ # coding: utf-8 from functools import wraps +from itertools import chain from django.db.models import Q from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.contrib.contenttypes.models import ContentType from modoboa.core.models import User -from modoboa.lib import parameters +from modoboa.lib import parameters, events from modoboa.lib.exceptions import ModoboaException from modoboa.lib.emailutils import split_mailbox -from modoboa.extensions.admin.models import Alias +from modoboa.extensions.admin.models import ( + Domain, Alias +) def needs_mailbox(): @@ -65,8 +68,6 @@ def get_identities(user, searchquery=None, idtfilter=None, grpfilter=None): :param list grpfilter: group names filters :return: a queryset """ - from itertools import chain - accounts = [] if idtfilter is None or not idtfilter or idtfilter == "account": ids = user.objectaccess_set \ @@ -104,3 +105,24 @@ def get_identities(user, searchquery=None, idtfilter=None, grpfilter=None): if idtfilter is not None and idtfilter: aliases = [al for al in aliases if al.type == idtfilter] return chain(accounts, aliases) + + +def get_domains(user, domfilter=None, searchquery=None, **extrafilters): + """Return all the domains the user can access. + + :param ``User`` user: user object + :param str searchquery: filter + :rtype: list + :return: a list of domains and/or relay domains + """ + domains = [] + if domfilter is None or not domfilter or domfilter == 'domain': + domains = Domain.objects.get_for_admin(user) + if searchquery is not None: + q = Q(name__contains=searchquery) + q |= Q(domainalias__name__contains=searchquery) + domains = domains.filter(q).distinct() + extra_domain_entries = events.raiseQueryEvent( + 'ExtraDomainEntries', user, domfilter, searchquery, **extrafilters + ) + return chain(domains, extra_domain_entries) diff --git a/modoboa/extensions/admin/migrations/0037_rename_tables.py b/modoboa/extensions/admin/migrations/0037_rename_tables.py index 077918c22..6b08aabd7 100644 --- a/modoboa/extensions/admin/migrations/0037_rename_tables.py +++ b/modoboa/extensions/admin/migrations/0037_rename_tables.py @@ -75,6 +75,13 @@ class Migration(SchemaMigration): 'use_domain_quota': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.User']"}) }, + u'admin.mailboxoperation': { + 'Meta': {'object_name': 'MailboxOperation'}, + 'argument': ('django.db.models.fields.TextField', [], {}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mailbox': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['admin.Mailbox']", 'null': 'True', 'blank': 'True'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '20'}) + }, 'admin.objectdates': { 'Meta': {'object_name': 'ObjectDates'}, 'creation': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), diff --git a/modoboa/extensions/admin/models/__init__.py b/modoboa/extensions/admin/models/__init__.py index 8edb89898..2a34185d3 100644 --- a/modoboa/extensions/admin/models/__init__.py +++ b/modoboa/extensions/admin/models/__init__.py @@ -1,8 +1,10 @@ +from .base import DatesAware from .domain import Domain from .domain_alias import DomainAlias from .mailbox import Mailbox, Quota, MailboxOperation from .alias import Alias __all__ = [ - 'Domain', 'DomainAlias', 'Mailbox', 'Quota', 'Alias', 'MailboxOperation' + 'Domain', 'DomainAlias', 'Mailbox', 'Quota', 'Alias', + 'MailboxOperation', 'DatesAware' ] diff --git a/modoboa/extensions/admin/models/domain.py b/modoboa/extensions/admin/models/domain.py index c4d7d5a36..d497d8260 100644 --- a/modoboa/extensions/admin/models/domain.py +++ b/modoboa/extensions/admin/models/domain.py @@ -56,6 +56,10 @@ class Domain(DatesAware): def mbalias_count(self): return self.alias_set.count() + @property + def tags(self): + return [{"name": "domain", "label": _("Domain"), "type": "dom"}] + @property def admins(self): """Return the domain administrators of this domain diff --git a/modoboa/extensions/admin/static/admin/js/admin.js b/modoboa/extensions/admin/static/admin/js/admin.js index 0e7c225be..f811d322b 100644 --- a/modoboa/extensions/admin/static/admin/js/admin.js +++ b/modoboa/extensions/admin/static/admin/js/admin.js @@ -1,3 +1,8 @@ +/** + * @module admin + * @desc Utility classes for the admin application + */ + var Admin = function(options) { Listing.call(this, options); }; @@ -12,6 +17,7 @@ Admin.prototype = { Listing.prototype.initialize.call(this, options); this.options = $.extend({}, this.defaults, this.options); this.options.defcallback = $.proxy(this.list_cb, this); + this.tag_handlers = {}; this.navobj = new History(this.options); @@ -37,12 +43,61 @@ Admin.prototype = { list_cb: function(data) { $("#listing").html(data.table); this.update_listing(data); + $("a.filter").click($.proxy(this.filter_by_tag, this)); }, listen: function() { $("#searchform").submit($.proxy(this.do_search, this)); }, + register_tag_handler: function(name, handler) { + this.tag_handlers[name] = handler; + if (this.navobj.getparam(name + "filter") != undefined) { + var text = this.navobj.getparam(name + "filter"); + $("#searchform").parent().after(this.make_tag(text, name)); + } + }, + + generic_tag_handler: function(tag, $link) { + if (this.navobj.getparam(tag + "filter") == undefined && $link.hasClass(tag)) { + var text = $link.attr("name"); + this.navobj.setparam(tag + "filter", text).update(); + $("#searchform").parent().after(this.make_tag(text, tag)); + return true; + } + return false; + }, + + make_tag: function(text, type) { + var $tag = $("", {"name": type, "class" : "btn btn-mini", "html": text}); + var $i = $("", {"class" : "icon-remove"}).prependTo($tag); + + $tag.click($.proxy(this.remove_tag, this)); + return $tag; + }, + + remove_tag: function(e) { + var $tag = $(e.target); + + if ($tag.is("i")) { + $tag = $tag.parent(); + } + e.preventDefault(); + this.navobj.delparam($tag.attr("name") + "filter").update(); + $tag.remove(); + }, + + filter_by_tag: function(e) { + var $link = $(e.target); + e.preventDefault(); + + for (var name in this.tag_handlers) { + if (this.tag_handlers[name].apply(this, [name, $link])) { + break; + } + } + }, + do_search: function(e) { e.preventDefault(); var squery = $("#searchquery").val(); @@ -104,6 +159,11 @@ var Domains = function(options) { }; Domains.prototype = { + initialize: function(options) { + Admin.prototype.initialize.call(this, options); + this.register_tag_handler("dom", this.generic_tag_handler); + }, + list_cb: function(data) { Admin.prototype.list_cb.call(this, data); var deloptions = (data.handle_mailboxes) @@ -120,6 +180,11 @@ Domains.prototype = { checkboxes: deloptions, success_cb: $.proxy(this.reload_listing, this) }); + $("a[name=delrelaydomain]").confirm({ + question: function() { return this.$element.attr('title'); }, + method: "DELETE", + success_cb: $.proxy(this.reload_listing, this) + }); }, change_inputs_state: function(value) { @@ -193,6 +258,17 @@ Domains.prototype = { }); }, this)); $(document).trigger('domform_init'); + }, + + rdomainform_cb: function() { + $(".submit").one('click', $.proxy(function(e) { + simple_ajax_form_post2(e, { + formid: "rdomform", + error_cb: $.proxy(this.rdomainform_cb, this), + reload_on_success: false, + success_cb: $.proxy(this.reload_listing, this) + }); + }, this)); } }; @@ -209,14 +285,8 @@ var Identities = function(options) { Identities.prototype = { initialize: function(options) { Admin.prototype.initialize.call(this, options); - if (this.navobj.getparam("idtfilter") != undefined) { - var text = this.navobj.getparam("idtfilter"); - $("#searchform").parent().after(this.make_tag(text, "idt")); - } - if (this.navobj.getparam("grpfilter") != undefined) { - var text = this.navobj.getparam("grpfilter"); - $("#searchform").parent().after(this.make_tag(text, "grp")); - } + this.register_tag_handler("idt", this.generic_tag_handler); + this.register_tag_handler("grp", this.grp_tag_handler); }, listen: function() { @@ -237,7 +307,6 @@ Identities.prototype = { if (data.handle_mailboxes == "yes") { deloptions = {keepdir: gettext("Do not delete mailbox directory")}; } - $("a.filter").click($.proxy(this.filter_by_tag, this)); $("a[name=delaccount]").confirm({ question: function() { return this.$element.attr('title'); }, @@ -252,46 +321,20 @@ Identities.prototype = { }); }, - make_tag: function(text, type) { - var $tag = $("", {"name": type, "class" : "btn btn-mini", "html": text}); - var $i = $("", {"class" : "icon-remove"}).prependTo($tag); - - $tag.click($.proxy(this.remove_tag, this)); - return $tag; - }, - - remove_tag: function(e) { - var $tag = $(e.target); - - if ($tag.is("i")) { - $tag = $tag.parent(); - } - e.preventDefault(); - this.navobj.delparam($tag.attr("name") + "filter").update(); - $tag.remove(); - }, - - filter_by_tag: function(e) { - var $link = $(e.target); - e.preventDefault(); - - if (this.navobj.getparam("idtfilter") == undefined && $link.hasClass("idt")) { - var text = $link.attr("name"); - this.navobj.setparam("idtfilter", text).update(); - $("#searchform").parent().after(this.make_tag(text, "idt")); - return; - } - if (this.navobj.getparam("grpfilter") == undefined && $link.hasClass("grp")) { + grp_tag_handler: function(tag, $link) { + if (this.navobj.getparam(tag + "filter") == undefined && $link.hasClass(tag)) { var text = $link.attr("name"); this.navobj .setparam("idtfilter", "account") - .setparam("grpfilter", text) + .setparam(tag + "filter", text) .update(); if ($("a[name=idt]").length == 0) { $("#searchform").parent().after(this.make_tag("account", "idt")); } - $("#searchform").parent().after(this.make_tag(text, "grp")); + $("#searchform").parent().after(this.make_tag(text, tag)); + return true; } + return false; }, simpleuser_mode: function() { diff --git a/modoboa/extensions/admin/templates/admin/domains.html b/modoboa/extensions/admin/templates/admin/domains.html index 65163e602..d32690232 100644 --- a/modoboa/extensions/admin/templates/admin/domains.html +++ b/modoboa/extensions/admin/templates/admin/domains.html @@ -7,5 +7,6 @@ $(document).ready(function() { admin = new Domains(); }); +{% extra_static_content "domains" user %} {% endblock %} {% block actions %}{% domains_menu "domains" user %}{% endblock %} diff --git a/modoboa/extensions/admin/templates/admin/domains_table.html b/modoboa/extensions/admin/templates/admin/domains_table.html new file mode 100644 index 000000000..b3f16ba9d --- /dev/null +++ b/modoboa/extensions/admin/templates/admin/domains_table.html @@ -0,0 +1,21 @@ +{% load i18n admin_tags lib_tags %} + + + + + + + + + + + {% for domain in domains %} + + + + + + + {% endfor %} + +
{% trans "Name" %}{% trans "Alias(es)" %}{% trans "Tags" %}{% trans "Actions" %}
{% domain_modify_link domain %}{% domain_aliases domain %} {% render_tags domain.tags %}{% domain_actions user domain %}
diff --git a/modoboa/extensions/admin/templates/admin/identities.html b/modoboa/extensions/admin/templates/admin/identities.html index 82e172a6d..632a6f31c 100644 --- a/modoboa/extensions/admin/templates/admin/identities.html +++ b/modoboa/extensions/admin/templates/admin/identities.html @@ -20,5 +20,6 @@ $(document).ready(function() { admin = new Identities(); }); +{% extra_static_content "identities" user %} {% endblock %} {% block actions %}{% identities_menu user %}{% endblock %} diff --git a/modoboa/extensions/admin/templates/admin/listing.html b/modoboa/extensions/admin/templates/admin/listing.html index 513512d17..cbcbbbc86 100644 --- a/modoboa/extensions/admin/templates/admin/listing.html +++ b/modoboa/extensions/admin/templates/admin/listing.html @@ -1,4 +1,4 @@ -{% extends "admin/header.html" %}{% load i18n admin_tags lib_tags %} +{% extends "admin/header.html" %}{% load i18n admin_tags %} {% block html_head %} {{ block.super }} diff --git a/modoboa/extensions/admin/templatetags/admin_tags.py b/modoboa/extensions/admin/templatetags/admin_tags.py index 6736fbbe9..e1fee75c9 100644 --- a/modoboa/extensions/admin/templatetags/admin_tags.py +++ b/modoboa/extensions/admin/templatetags/admin_tags.py @@ -15,6 +15,16 @@ genders = { @register.simple_tag def domains_menu(selection, user): + """Specific menu for domain related operations. + + Corresponds to the menu visible on the left column when you go to + Domains. + + :param str selection: menu entry currently selected + :param ``User`` user: connected user + :rtype: str + :return: rendered menu (as HTML) + """ if not user.has_perm("admin.add_domain"): return "" @@ -25,6 +35,9 @@ def domains_menu(selection, user): "modal": True, "modalcb": "admin.newdomain_cb", "url": reverse("modoboa.extensions.admin.views.domain.newdomain")}, + ] + entries += events.raiseQueryEvent("ExtraDomainMenuEntries", user) + entries += [ {"name": "import", "label": _("Import"), "img": "icon-folder-open", @@ -111,23 +124,28 @@ def identities_menu(user): @register.simple_tag -def domain_actions(user, domid): - from modoboa.extensions.admin.models import Domain +def domain_actions(user, domain): + actions = [] + if domain.__class__.__name__ == 'Domain': + actions = [ + {"name": "listidentities", + "url": reverse("modoboa.extensions.admin.views.identity.identities") + "#list/?searchquery=@%s" % domain.name, + "title": _("View the domain's identities"), + "img": "icon-user"} + ] + if user.has_perm("admin.delete_domain"): + actions.append({ + "name": "deldomain", + "url": reverse( + "modoboa.extensions.admin.views.domain.deldomain", + args=[domain.id] + ), + "title": _("Delete %s?" % domain.name), + "img": "icon-trash" + }) + else: + actions = events.raiseQueryEvent('GetDomainActions', user, domain) - domain = Domain.objects.get(pk=domid) - actions = [ - {"name": "listidentities", - "url": reverse("modoboa.extensions.admin.views.identity.identities") + "#list/?searchquery=@%s" % domain.name, - "title": _("View the domain's identities"), - "img": "icon-user"} - ] - if user.has_perm("admin.delete_domain"): - actions.append({ - "name": "deldomain", - "url": reverse("modoboa.extensions.admin.views.domain.deldomain", args=[domid]), - "title": _("Delete %s?" % domain.name), - "img": "icon-trash" - }) return render_actions(actions) @@ -153,8 +171,50 @@ def identity_actions(user, ident): return render_actions(actions) +@register.simple_tag +def domain_modify_link(domain): + linkdef = {"label": domain.name, "modal": True} + if domain.__class__.__name__ == "Domain": + linkdef["url"] = reverse( + "modoboa.extensions.admin.views.domain.editdomain", + args=[domain.id] + ) + linkdef["modalcb"] = "admin.domainform_cb" + else: + tmp = events.raiseDictEvent('GetDomainModifyLink', domain) + for key in ['url', 'modalcb']: + linkdef[key] = tmp[key] + return render_link(linkdef) + + +@register.simple_tag +def domain_aliases(domain): + """Display domain aliases of this domain. + + :param domain: + :rtype: str + """ + if domain.__class__.__name__ == "Domain": + if not domain.domainalias_set.count(): + return '---' + res = "" + for da in domain.domainalias_set.all(): + res += "%s
" % da.name + return res + return '---' + + @register.simple_tag def identity_modify_link(identity, active_tab='default'): + """Return the appropriate modification link. + + According to the identity type, a specific modification link (URL) + must be used. + + :param identity: a ``User`` or ``Alias`` instance + :param str active_tab: the tab to display + :rtype: str + """ linkdef = {"label": identity.identity, "modal": True} if identity.__class__.__name__ == "User": linkdef["url"] = reverse( diff --git a/modoboa/extensions/admin/views/domain.py b/modoboa/extensions/admin/views/domain.py index 91f2c1669..0b9d83ab8 100644 --- a/modoboa/extensions/admin/views/domain.py +++ b/modoboa/extensions/admin/views/domain.py @@ -15,13 +15,13 @@ from modoboa.lib.webutils import ( from modoboa.lib.formutils import CreationWizard from modoboa.lib.exceptions import PermDeniedException from modoboa.lib.templatetags.lib_tags import pagination_bar -from modoboa.extensions.admin.tables import DomainsTable from modoboa.extensions.admin.lib import get_sort_order, get_listing_page from modoboa.extensions.admin.exceptions import AdminError from modoboa.extensions.admin.models import Domain, Mailbox from modoboa.extensions.admin.forms import ( DomainForm, DomainFormGeneral, DomainFormOptions ) +from modoboa.extensions.admin.lib import get_domains @login_required @@ -35,17 +35,28 @@ def index(request): ) def _domains(request): sort_order, sort_dir = get_sort_order(request.GET, "name") - domains = Domain.objects.get_for_admin(request.user) - squery = request.GET.get("searchquery", None) - if squery is not None: - q = Q(name__contains=squery) - q |= Q(domainalias__name__contains=squery) - domains = domains.filter(q).distinct() + filters = dict( + (flt, request.GET.get(flt, None)) + for flt in ['domfilter', 'searchquery'] + + events.raiseQueryEvent('ExtraDomainFilters') + ) + domainlist = get_domains( + request.user, **filters + ) if sort_order in ["name", "domainalias__name"]: - domains = domains.order_by("%s%s" % (sort_dir, sort_order)) - page = get_listing_page(domains, request.GET.get("page", 1)) + domainlist = sorted( + domainlist, + key=lambda d: getattr(d, sort_order), reverse=sort_dir == '-' + ) + else: + domainlist = sorted(domainlist, key=lambda d: d.tags[0], + reverse=sort_dir == '-') + page = get_listing_page(domainlist, request.GET.get("page", 1)) return ajax_simple_response({ - "table": DomainsTable(request, page.object_list).render(), + "table": _render_to_string(request, 'admin/domains_table.html', { + 'domains': domainlist, + 'tableid': 'domains' + }), "page": page.number, "paginbar": pagination_bar(page), "handle_mailboxes": parameters.get_admin("HANDLE_MAILBOXES", diff --git a/modoboa/extensions/amavis/__init__.py b/modoboa/extensions/amavis/__init__.py index 9abc912ed..a376a9a34 100644 --- a/modoboa/extensions/amavis/__init__.py +++ b/modoboa/extensions/amavis/__init__.py @@ -95,13 +95,14 @@ def on_delete_domain(domain): @events.observe("GetStaticContent") -def extra_static_content(user): +def extra_static_content(caller, user): if user.group == "SimpleUsers": return [] - tpl = Template("""""") + +""") + return [tpl.render( + Context({ + 'url': reverse("modoboa.extensions.amavis.views.nbrequests"), + 'interval': int(parameters.get_admin("CHECK_REQUESTS_INTERVAL")) * 1000, + 'text': _("pending requests"), + }) + )] - return [tpl.render( - Context(dict( - url=reverse("modoboa.extensions.amavis.views.nbrequests"), - interval=int(parameters.get_admin("CHECK_REQUESTS_INTERVAL")) * 1000, - text=_("pending requests"), - user_can_release=parameters.get_admin("USER_CAN_RELEASE") - )) - )] + if caller == 'domains': + tpl = Template(""" +""") + + return [tpl.render(Context({}))] + return [] @events.observe("TopNotifications") diff --git a/modoboa/extensions/limits/__init__.py b/modoboa/extensions/limits/__init__.py index 2a22f37e8..5c991598f 100644 --- a/modoboa/extensions/limits/__init__.py +++ b/modoboa/extensions/limits/__init__.py @@ -116,10 +116,12 @@ def fill_account_instances(user, account, instances): @events.observe("GetStaticContent") -def get_static_content(user): +def get_static_content(caller, user): + if caller not in ['domains', 'identities']: + return [] if user.group == "SimpleUsers": return [] - return """