diff --git a/extensions/amavis_quarantine/__init__.py b/extensions/amavis_quarantine/__init__.py index 3f7a5b842..f5358ce9d 100644 --- a/extensions/amavis_quarantine/__init__.py +++ b/extensions/amavis_quarantine/__init__.py @@ -41,6 +41,8 @@ def load(): parameters.register_admin("AM_PDP_SOCKET", type="string", deflt=_("/var/amavis/amavisd.sock"), help=_("Path to the PDP server socket (if unix mode)")) + parameters.register_admin("USER_CAN_RELEASE", type="list_yesno", deflt="no", + help=_("Allow users to directly release their messages")) parameters.register_user( "MESSAGES_PER_PAGE", type="int", deflt=40, diff --git a/extensions/amavis_quarantine/sql_listing.py b/extensions/amavis_quarantine/sql_listing.py index 414b04862..c960e1528 100644 --- a/extensions/amavis_quarantine/sql_listing.py +++ b/extensions/amavis_quarantine/sql_listing.py @@ -73,6 +73,8 @@ class SQLconnector(MBconnector): m["class"] = "unseen" elif rcpt.rs == 'R': m["img_rstatus"] = static_url("pics/release.png") + elif rcpt.rs == 'p': + m["class"] = "pending" emails.append(m) return emails diff --git a/extensions/amavis_quarantine/static/css/quarantine.css b/extensions/amavis_quarantine/static/css/quarantine.css index 3c46ce99b..3aac8ced5 100644 --- a/extensions/amavis_quarantine/static/css/quarantine.css +++ b/extensions/amavis_quarantine/static/css/quarantine.css @@ -27,3 +27,7 @@ thead tr { td.unseen { font-weight: bold; } + +td.pending { + font-style: italic; +} \ No newline at end of file diff --git a/extensions/amavis_quarantine/static/js/quarantine.js b/extensions/amavis_quarantine/static/js/quarantine.js index bfc349bf1..c7b2a4eee 100644 --- a/extensions/amavis_quarantine/static/js/quarantine.js +++ b/extensions/amavis_quarantine/static/js/quarantine.js @@ -24,7 +24,7 @@ Quarantine.prototype = { $("#searchfield").searchbar({navobj: this.navobj}); } if (data.navbar) { - $("#bottom-bar-in").html(data.navbar); + $("#bottom-bar-right").html(data.navbar); } if (data.listing != undefined) { $("#listing").html(data.listing); @@ -43,6 +43,8 @@ Quarantine.prototype = { $.proxy(this.release_selection, this)); $(document).on("click", "a[name=delete-multi]", $.proxy(this.delete_selection, this)); + $(document).on("click", "a[name=viewrequests]", + $.proxy(this.view_requests, this)); $(document).on("click", "#bottom-bar a", $.proxy(this.load_page, this)); $(document).on("click", "a[name=release]", $.proxy(this.release, this)); @@ -58,6 +60,11 @@ Quarantine.prototype = { this.navobj.from_string($link.attr("href")).update(); }, + view_requests: function(e) { + e.preventDefault(); + this.navobj.setparam("viewrequests", "1").update(); + }, + viewmail_loader: function(e) { e.preventDefault(); var $tr = $(e.target).parent(); diff --git a/extensions/amavis_quarantine/templates/amavis_quarantine/index.html b/extensions/amavis_quarantine/templates/amavis_quarantine/index.html index de5331cd7..8244b47e9 100644 --- a/extensions/amavis_quarantine/templates/amavis_quarantine/index.html +++ b/extensions/amavis_quarantine/templates/amavis_quarantine/index.html @@ -18,5 +18,3 @@ $(document).ready(function() {
{% endblock %} -{% block footer %} -{% endblock %} diff --git a/extensions/amavis_quarantine/templatetags/amextras.py b/extensions/amavis_quarantine/templatetags/amextras.py index c7bc2addc..1a2ce3342 100644 --- a/extensions/amavis_quarantine/templatetags/amextras.py +++ b/extensions/amavis_quarantine/templatetags/amextras.py @@ -1,5 +1,6 @@ from django import template from django.template.loader import render_to_string +from django.template import Template, Context from django.utils.translation import ugettext as _ from django.core.urlresolvers import reverse from django.conf import settings @@ -9,7 +10,7 @@ from modoboa.extensions import amavis_quarantine register = template.Library() @register.simple_tag -def viewm_menu(selection, backurl, mail_id, rcpt, perms): +def viewm_menu(user, mail_id, rcpt): options_menu = [ {"name" : "viewmode", "label" : _("View as plain text"), @@ -35,12 +36,12 @@ def viewm_menu(selection, backurl, mail_id, rcpt, perms): {"name" : "release", "img" : "icon-ok", "url" : reverse(amavis_quarantine.views.release, args=[mail_id]) \ - + "?rcpt=%s" % rcpt, + + ("?rcpt=%s" % rcpt if rcpt else ""), "label" : _("Release")}, {"name" : "delete", "img" : "icon-remove", "url" : reverse(amavis_quarantine.views.delete, args=[mail_id]) \ - + "?rcpt=%s" % rcpt, + + ("?rcpt=%s" % rcpt if rcpt else ""), "label" : _("Delete")}, {"name" : "options", "label" : _("Options"), @@ -49,11 +50,10 @@ def viewm_menu(selection, backurl, mail_id, rcpt, perms): ] return render_to_string('common/buttons_list.html', - {"selection" : selection, "entries" : entries, - "perms" : perms}) + {"entries" : entries}) @register.simple_tag -def quar_menu(selection, user): +def quar_menu(user, nbrequests): entries = [ {"name" : "release-multi", "url" : reverse(amavis_quarantine.views.process), @@ -89,11 +89,17 @@ def quar_menu(selection, user): extraopts = [{"name" : "to", "label" : _("To")}] else: extraopts = [] - searchbar = render_to_string('common/email_searchbar.html', { + extracontent = render_to_string('common/email_searchbar.html', { "MEDIA_URL" : settings.MEDIA_URL, "extraopts" : extraopts }) + + if nbrequests != -1: + tpl = Template('
{{ label }}
') + extracontent += tpl.render(Context(dict( + label=_("%d pending requests" % nbrequests) + ))) return render_to_string('common/buttons_list.html', dict( - selection=selection, entries=entries, extracontent=searchbar + entries=entries, extracontent=extracontent )) diff --git a/extensions/amavis_quarantine/views.py b/extensions/amavis_quarantine/views.py index 1bdd586d0..621d07442 100644 --- a/extensions/amavis_quarantine/views.py +++ b/extensions/amavis_quarantine/views.py @@ -30,7 +30,7 @@ def __get_current_url(request): def empty_quarantine(request): content = "
%s
" % _("Empty quarantine") ctx = getctx("ok", level=2, listing=content, navbar="", - menu=quar_menu("", request.user)) + menu=quar_menu(request.user, -1)) return HttpResponse(simplejson.dumps(ctx), mimetype="application/json") @login_required @@ -38,8 +38,13 @@ def _listing(request): flt = None rcptfilter = None msgs = None + nbrequests = -1 - order = request.GET.has_key("order") and request.GET["order"] or "-date" + if not request.user.is_superuser and request.user.group != 'SimpleUsers': + if not len(request.user.get_domains()): + return empty_quarantine(request) + + order = request.GET.get("order", "-date") if not request.session.has_key("navparams"): request.session["navparams"] = {} request.session["navparams"]["order"] = order @@ -61,20 +66,26 @@ def _listing(request): raise Exception("unsupported search criteria %s" % c) flt = nfilter if flt is None else flt | nfilter - q = ~Q(rs='D') - if not request.user.is_superuser: - if request.user.group != 'SimpleUsers': + if request.GET.get("viewrequests", None) == "1": + q = Q(rs='p') + else: + q = ~Q(rs='D') + rq = Q(rs='p') + if request.user.group == 'SimpleUsers': + q &= Q(rid__email=request.user.email) + else: + if not request.user.is_superuser: doms = request.user.get_domains() - if not len(doms): - return empty_quarantine(request) regexp = "(%s)" % '|'.join(map(lambda dom: dom.name, doms)) - q &= Q(rid__email__regex=regexp) - else: - q &= Q(rid__email=request.user.email) + doms_q = Q(rid__email__regex=regexp) + q &= doms_q + rp &= doms_q + if rcptfilter is not None: + q &= Q(rid__email__contains=rcptfilter) + + if parameters.get_admin("USER_CAN_RELEASE") == "no": + nbrequests = len(Msgrcpt.objects.filter(rq)) - if request.user.group != 'SimpleUsers' \ - and rcptfilter is not None: - q &= Q(rid__email__contains=rcptfilter) msgs = Msgrcpt.objects.filter(q).values("mail_id") if request.GET.has_key("page"): @@ -96,7 +107,7 @@ def _listing(request): content = lst.fetch(request, page.id_start, page.id_stop) navbar = lst.render_navbar(page, "listing/?") ctx = getctx("ok", listing=content, navbar=navbar, - menu=quar_menu("", request.user)) + menu=quar_menu(request.user, nbrequests)) return HttpResponse(simplejson.dumps(ctx), mimetype="application/json") @login_required @@ -127,9 +138,9 @@ def viewmail(request, mail_id): if request.user.group != 'SimpleUsers': rcpt = request.GET["rcpt"] else: + rcpt = None mb = Mailbox.objects.get(user=request.user) - rcpt = mb.full_address - msgrcpt = Msgrcpt.objects.get(mail=mail_id, rid__email=rcpt) + msgrcpt = Msgrcpt.objects.get(mail=mail_id, rid__email=mb.full_address) msgrcpt.rs = 'V' msgrcpt.save() args = [] @@ -141,8 +152,7 @@ def viewmail(request, mail_id): """).render(Context({"url" : reverse(getmailcontent, args=[mail_id]) \ + "?%s" % "&".join(args)})) - menu = viewm_menu("", __get_current_url(request), mail_id, rcpt, - request.user.get_all_permissions()) + menu = viewm_menu(request.user, mail_id, rcpt) ctx = getctx("ok", menu=menu, listing=content) return HttpResponse(simplejson.dumps(ctx), mimetype="application/json") @@ -190,7 +200,16 @@ def release(request, mail_id): mail_id = check_mail_id(request, mail_id) if request.user.group == 'SimpleUsers': mb = Mailbox.objects.get(user=request.user) + print mail_id msgrcpts = Msgrcpt.objects.filter(mail__in=mail_id, rid__email=mb.full_address) + if parameters.get_admin("USER_CAN_RELEASE") == "no": + print msgrcpts + msgrcpts.update(rs='p') + message = ungettext("%(count)d request sent", + "%(count)d requests sent", + len(mail_id)) % {"count" : len(mail_id)} + return ajax_response(request, "ok", respmsg=message, + url=__get_current_url(request)) else: msgrcpts = [] for mid in mail_id: