diff --git a/modoboa/extensions/admin/models/alias.py b/modoboa/extensions/admin/models/alias.py index e8720ef5e..327e4bf0c 100644 --- a/modoboa/extensions/admin/models/alias.py +++ b/modoboa/extensions/admin/models/alias.py @@ -117,14 +117,18 @@ class Alias(AdminObject): if not t in int_rcpts: self.mboxes.remove(t) - def get_recipients(self): - """Return the recipients list + def get_recipients(self, with_external=True): + """Return the recipients list. Internal and external addresses are mixed into a single list. + + :param bool with_external: include external addresses or not + :rtype: list + :return: a list of addresses """ result = [al.full_address for al in self.aliases.all()] result += [mb.full_address for mb in self.mboxes.all()] - if self.extmboxes != "": + if with_external and self.extmboxes != "": result += self.extmboxes.split(',') return result diff --git a/modoboa/extensions/admin/models/mailbox.py b/modoboa/extensions/admin/models/mailbox.py index ed61adcbe..82abbc13a 100644 --- a/modoboa/extensions/admin/models/mailbox.py +++ b/modoboa/extensions/admin/models/mailbox.py @@ -114,6 +114,17 @@ class Mailbox(AdminObject): self.__mail_home = output.strip() return self.__mail_home + @property + def alias_addresses(self): + """Return all alias address of this mailbox. + + :rtype: list of string + """ + aliases = [] + for alias in self.alias_set.all(): + aliases += [alias.full_address] + return aliases + def rename_dir(self, old_mail_home): hm = parameters.get_admin("HANDLE_MAILBOXES", raise_error=False) if hm is None or hm == "no": diff --git a/modoboa/extensions/amavis/sql_listing.py b/modoboa/extensions/amavis/sql_listing.py index ffa5e3933..af503c83a 100644 --- a/modoboa/extensions/amavis/sql_listing.py +++ b/modoboa/extensions/amavis/sql_listing.py @@ -9,7 +9,7 @@ from modoboa.lib.webutils import static_url from modoboa.lib.email_listing import MBconnector, EmailListing from modoboa.lib.emailutils import Email from modoboa.lib.dbutils import db_type -from modoboa.extensions.admin.models import Domain +from modoboa.extensions.admin.models import Domain, Alias from .models import Quarantine, Msgrcpt @@ -34,10 +34,7 @@ class Qtable(tables.Table): cols_order = [] def parse_type(self, value): - if value in ['S', 'V']: - color = 'important' - else: - color = 'warning' + color = 'important' if value in ['S', 'V'] else 'warning' return '%s' % (color, value) def parse_date(self, value): @@ -124,22 +121,25 @@ class SQLWrapper(object): """ def get_mails(self, request, rcptfilter=None): - if request.GET.get("viewrequests", None) == "1": - q = Q(rs='p') - else: - q = ~Q(rs='D') + """Retrieve all messages visible by a user. + Simple users can only see the messages + + :rtype: QuerySet + """ + q = Q(rs='p') \ + if request.GET.get("viewrequests", None) == "1" else ~Q(rs='D') if request.user.group == 'SimpleUsers': - q &= Q(rid__email=request.user.email) - else: - if not request.user.is_superuser: - doms = Domain.objects.get_for_admin(request.user) - regexp = "(%s)" % '|'.join([dom.name for dom in doms]) - doms_q = Q(rid__email__regex=regexp) - q &= doms_q - if rcptfilter is not None: - q &= Q(rid__email__contains=rcptfilter) - + rcpts = [request.user.email] \ + + request.user.mailbox_set.all()[0].alias_addresses + q &= Q(rid__email__in=rcpts) + elif not request.user.is_superuser: + doms = Domain.objects.get_for_admin(request.user) + regexp = "(%s)" % '|'.join([dom.name for dom in doms]) + doms_q = Q(rid__email__regex=regexp) + q &= doms_q + if rcptfilter is not None: + q &= Q(rid__email__contains=rcptfilter) return Msgrcpt.objects.filter(q).values("mail_id") def get_recipient_message(self, address, mailid): @@ -179,24 +179,23 @@ class PgWrapper(SQLWrapper): """ def get_mails(self, request, rcptfilter=None): - if request.GET.get("viewrequests", None) == "1": - q = Q(rs='p') - else: - q = ~Q(rs='D') + q = Q(rs='p') \ + if request.GET.get("viewrequests", None) == "1" else ~Q(rs='D') where = ["U0.rid=maddr.id"] if request.user.group == 'SimpleUsers': - where.append("convert_from(maddr.email, 'UTF8') = '%s'" % request.user.email) - return Msgrcpt.objects.filter(q).extra( - where=where, tables=['maddr'] - ) - - if not request.user.is_superuser: + rcpts = [request.user.email] \ + + request.user.mailbox_set.all()[0].alias_addresses + where.append("convert_from(maddr.email, 'UTF8') IN (%s)" \ + % (','.join(["'%s'" % rcpt for rcpt in rcpts]))) + elif not request.user.is_superuser: doms = Domain.objects.get_for_admin(request.user) regexp = "(%s)" % '|'.join([dom.name for dom in doms]) where.append("convert_from(maddr.email, 'UTF8') ~ '%s'" % regexp) if rcptfilter is not None: - where.append("convert_from(maddr.email, 'UTF8') LIKE '%%%s%%'" % rcptfilter) - return Msgrcpt.objects.filter(q).extra(where=where, tables=['maddr']).values("mail_id") + where.append("convert_from(maddr.email, 'UTF8') LIKE '%%%s%%'" + % rcptfilter) + return Msgrcpt.objects.filter(q)\ + .extra(where=where, tables=['maddr']).values("mail_id") def get_recipient_message(self, address, mailid): qset = Msgrcpt.objects.filter(mail=mailid).extra( @@ -255,10 +254,8 @@ class SQLlisting(EmailListing): reset_wm_url = True def __init__(self, user, msgs, filter, **kwargs): - if user.group == 'SimpleUsers': - Qtable.cols_order = ['type', 'score', 'rstatus', 'from_', 'subject', 'time'] - else: - Qtable.cols_order = ['type', 'score', 'rstatus', 'to', 'from_', 'subject', 'time'] + Qtable.cols_order = ['type', 'score', 'rstatus', 'to', 'from_', + 'subject', 'time'] self.mbc = SQLconnector(msgs, filter) super(SQLlisting, self).__init__(**kwargs) self.show_listing_headers = True diff --git a/modoboa/extensions/amavis/templatetags/amavis_tags.py b/modoboa/extensions/amavis/templatetags/amavis_tags.py index 3c12e2149..7143cd8bd 100644 --- a/modoboa/extensions/amavis/templatetags/amavis_tags.py +++ b/modoboa/extensions/amavis/templatetags/amavis_tags.py @@ -99,12 +99,7 @@ def quar_menu(user): "label": _("Bad MIME")} ]} ] - - if user.group != 'SimpleUsers': - extraopts = [{"name": "to", "label": _("To")}] - else: - extraopts = [] - + extraopts = [{"name": "to", "label": _("To")}] return render_to_string('amavis/main_action_bar.html', { 'entries': entries, 'extraopts': extraopts, 'STATIC_URL': settings.STATIC_URL, 'extraclasses': 'pull-left' diff --git a/modoboa/extensions/amavis/views.py b/modoboa/extensions/amavis/views.py index 207eaf3e7..3a7ab3457 100644 --- a/modoboa/extensions/amavis/views.py +++ b/modoboa/extensions/amavis/views.py @@ -10,7 +10,7 @@ from django.contrib.auth.decorators \ import login_required, user_passes_test from django.db.models import Q from modoboa.lib import parameters -from modoboa.lib.exceptions import ModoboaException, BadRequest +from modoboa.lib.exceptions import BadRequest from modoboa.lib.webutils import ( getctx, ajax_response, render_to_json_response ) @@ -136,15 +136,11 @@ def viewmail_selfservice(request, mail_id, @selfservice(viewmail_selfservice) def viewmail(request, mail_id): - if request.user.group != 'SimpleUsers': - rcpt = request.GET["rcpt"] - else: - rcpt = None - + rcpt = request.GET["rcpt"] if request.user.mailbox_set.count(): mb = Mailbox.objects.get(user=request.user) - if not rcpt or rcpt == mb.full_address: - msgrcpt = get_wrapper().get_recipient_message(mb.full_address, mail_id) + if rcpt in mb.alias_addresses: + msgrcpt = get_wrapper().get_recipient_message(rcpt, mail_id) msgrcpt.rs = 'V' msgrcpt.save() @@ -170,8 +166,8 @@ def viewheaders(request, mail_id): def check_mail_id(request, mail_id): if type(mail_id) in [str, unicode]: - if "rcpt" in request.GET: - mail_id = ["%s %s" % (request.GET["rcpt"], mail_id)] + if "rcpt" in request.POST: + mail_id = ["%s %s" % (request.POST["rcpt"], mail_id)] else: mail_id = [mail_id] return mail_id @@ -193,21 +189,16 @@ def delete_selfservice(request, mail_id): @selfservice(delete_selfservice) def delete(request, mail_id): mail_id = check_mail_id(request, mail_id) - if request.user.group == 'SimpleUsers': - mb = Mailbox.objects.get(user=request.user) - msgrcpts = get_wrapper().get_recipient_messages(mb.full_address, mail_id) - #msgrcpts.update(rs='D') - for msgrcpt in msgrcpts: - msgrcpt.rs = 'D' - msgrcpt.save() - else: - wrapper = get_wrapper() - for mid in mail_id: - r, i = mid.split() - msgrcpt = wrapper.get_recipient_message(r, i) - msgrcpt.rs = 'D' - msgrcpt.save() - + wrapper = get_wrapper() + mb = Mailbox.objects.get(user=request.user) \ + if request.user.group == 'SimpleUsers' else None + for mid in mail_id: + r, i = mid.split() + if mb is not None and not r in mb.alias_addresses: + continue + msgrcpt = wrapper.get_recipient_message(r, i) + msgrcpt.rs = 'D' + msgrcpt.save() message = ungettext("%(count)d message deleted successfully", "%(count)d messages deleted successfully", len(mail_id)) % {"count": len(mail_id)} @@ -245,32 +236,36 @@ def release_selfservice(request, mail_id): @selfservice(release_selfservice) def release(request, mail_id): + """Release message selection. + + :param str mail_id: message unique identifier + """ mail_id = check_mail_id(request, mail_id) - if request.user.group == 'SimpleUsers': - mb = Mailbox.objects.get(user=request.user) - msgrcpts = get_wrapper().get_recipient_messages(mb.full_address, mail_id) - if parameters.get_admin("USER_CAN_RELEASE") == "no": - # FIXME : can't use this syntax because extra SQL (using - # .extra() for postgres) is not propagated (the 'tables' - # parameter is lost somewhere...) - # - # msgrcpts.update(rs='p') - for msgrcpt in msgrcpts: - msgrcpt.rs = 'p' - msgrcpt.save() - 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=QuarantineNavigationParameters(request).back_to_listing() - ) - else: - msgrcpts = [] - wrapper = get_wrapper() - for mid in mail_id: - r, i = mid.split() - msgrcpts += [wrapper.get_recipient_message(r, i)] + msgrcpts = [] + wrapper = get_wrapper() + mb = Mailbox.objects.get(user=request.user) \ + if request.user.group == 'SimpleUsers' else None + for mid in mail_id: + r, i = mid.split() + if mb is not None and not r in mb.alias_addresses: + continue + msgrcpts += [wrapper.get_recipient_message(r, i)] + if mb is not None and parameters.get_admin("USER_CAN_RELEASE") == "no": + # FIXME : can't use this syntax because extra SQL (using + # .extra() for postgres) is not propagated (the 'tables' + # parameter is lost somewhere...) + # + # msgrcpts.update(rs='p') + for msgrcpt in msgrcpts: + msgrcpt.rs = 'p' + msgrcpt.save() + 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=QuarantineNavigationParameters(request).back_to_listing() + ) amr = AMrelease() error = None diff --git a/modoboa/static/js/jquery.htmltable.js b/modoboa/static/js/jquery.htmltable.js index d428ab03b..1d719d7a7 100644 --- a/modoboa/static/js/jquery.htmltable.js +++ b/modoboa/static/js/jquery.htmltable.js @@ -25,7 +25,6 @@ }, listen: function() { - $(document) .off("click", "tbody>tr") .on("click", "tbody>tr", diff --git a/modoboa/templates/common/buttons_list.html b/modoboa/templates/common/buttons_list.html index 29cf3132e..2d4963eee 100644 --- a/modoboa/templates/common/buttons_list.html +++ b/modoboa/templates/common/buttons_list.html @@ -1,7 +1,7 @@ {% load lib_tags %}