A simple user can now see all its quarantined messages.

fixes #89
This commit is contained in:
Antoine Nguyen
2013-11-20 15:17:48 +01:00
parent cd227b1433
commit 6e23c5441e
7 changed files with 97 additions and 96 deletions
+7 -3
View File
@@ -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
@@ -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":
+32 -35
View File
@@ -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 '<span class="label label-%s">%s</span>' % (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
@@ -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'
+45 -50
View File
@@ -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
-1
View File
@@ -25,7 +25,6 @@
},
listen: function() {
$(document)
.off("click", "tbody>tr")
.on("click", "tbody>tr",
+1 -1
View File
@@ -1,7 +1,7 @@
{% load lib_tags %}
<div class="btn-toolbar {{ extraclasses }}">{% for entry in entries %}
<div class="btn-group">{% if entry.menu %}
<a class="btn dropdown-toggle" data-toggle="dropdown">{% if entry.img %}<i class="{{ entry.img}}"></i>{% endif %}{{ entry.label }}<span class="caret"></span></a>
<a class="btn dropdown-toggle" data-toggle="dropdown">{% if entry.img %}<i class="{{ entry.img}}"></i>{% endif %}{{ entry.label }} <span class="caret"></span></a>
<ul class="dropdown-menu">{% for sentry in entry.menu %}
<li>{% render_link sentry %}</li>
{% endfor %}</ul>