diff --git a/data/Dockerfiles/dovecot/Dockerfile b/data/Dockerfiles/dovecot/Dockerfile index d8a61a06..5e93b503 100644 --- a/data/Dockerfiles/dovecot/Dockerfile +++ b/data/Dockerfiles/dovecot/Dockerfile @@ -119,6 +119,7 @@ COPY docker-entrypoint.sh / COPY supervisord.conf /etc/supervisor/supervisord.conf COPY stop-supervisor.sh /usr/local/sbin/stop-supervisor.sh COPY quarantine_notify.py /usr/local/bin/quarantine_notify.py +COPY quota_notify.py /usr/local/bin/quota_notify.py ENTRYPOINT ["/docker-entrypoint.sh"] CMD exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf diff --git a/data/Dockerfiles/dovecot/docker-entrypoint.sh b/data/Dockerfiles/dovecot/docker-entrypoint.sh index 7072c62e..af6d0e35 100755 --- a/data/Dockerfiles/dovecot/docker-entrypoint.sh +++ b/data/Dockerfiles/dovecot/docker-entrypoint.sh @@ -165,7 +165,8 @@ chmod +x /usr/local/lib/dovecot/sieve/rspamd-pipe-ham \ /usr/local/bin/trim_logs.sh \ /usr/local/bin/sa-rules.sh \ /usr/local/bin/maildir_gc.sh \ - /usr/local/sbin/stop-supervisor.sh + /usr/local/sbin/stop-supervisor.sh \ + /usr/local/bin/quota_notify.py # Setup cronjobs echo '* * * * * root /usr/local/bin/imapsync_cron.pl 2>&1 | /usr/bin/logger' > /etc/cron.d/imapsync diff --git a/data/Dockerfiles/dovecot/quarantine_notify.py b/data/Dockerfiles/dovecot/quarantine_notify.py index f3c497c5..64d79dc4 100755 --- a/data/Dockerfiles/dovecot/quarantine_notify.py +++ b/data/Dockerfiles/dovecot/quarantine_notify.py @@ -94,9 +94,21 @@ def notify_rcpt(rcpt, msg_count): records = query_mysql('SELECT count(id) AS counter, rcpt FROM quarantine WHERE notified = 0 GROUP BY rcpt') for record in records: - last_notification = int(r.hget('Q_LAST_NOTIFIED', record['rcpt']) or 0) + attrs = '' + attrs_json = '' + try: + last_notification = int(r.hget('Q_LAST_NOTIFIED', record['rcpt'])) + if last_notification > time_now: + print 'Last notification is > time now, assuming never' + last_notification = 0 + except Exception as ex: + print 'Could not determine last notification for %s, assuming never' % (record['rcpt']) + last_notification = 0 attrs_json = query_mysql('SELECT attributes FROM mailbox WHERE username = "%s"' % (record['rcpt'])) attrs = json.loads(str(attrs_json[0]['attributes'])) + if attrs['quarantine_notification'] not in ('hourly', 'daily', 'weekly', 'never'): + print 'Abnormal quarantine_notification value' + continue if attrs['quarantine_notification'] == 'hourly': if last_notification == 0 or (last_notification + 3600) < time_now: print "Notifying %s about %d new items in quarantine" % (record['rcpt'], record['counter']) diff --git a/data/Dockerfiles/dovecot/quota_notify.py b/data/Dockerfiles/dovecot/quota_notify.py new file mode 100755 index 00000000..20d7abb7 --- /dev/null +++ b/data/Dockerfiles/dovecot/quota_notify.py @@ -0,0 +1,70 @@ +#!/usr/bin/python + +import smtplib +import os +from email.MIMEMultipart import MIMEMultipart +from email.MIMEText import MIMEText +from email.Utils import COMMASPACE, formatdate +import jinja2 +from jinja2 import Template +import redis +import time +import sys +from subprocess import Popen, PIPE, STDOUT + +if len(sys.argv) > 2: + percent = int(sys.argv[1]) + username = str(sys.argv[2]) +else: + print "Args missing" + sys.exit(1) + +while True: + try: + r = redis.StrictRedis(host='redis', decode_responses=True, port=6379, db=0) + r.ping() + except Exception as ex: + print '%s - trying again...' % (ex) + time.sleep(3) + else: + break + +if r.get('QW_HTML'): + try: + template = Template(r.get('QW_HTML')) + except: + print "Error: Cannot parse quarantine template, falling back to default template." + with open('/templates/quota.tpl') as file_: + template = Template(file_.read()) +else: + with open('/templates/quota.tpl') as file_: + template = Template(file_.read()) + +html = template.render(username=username, percent=percent) +try: + msg = MIMEMultipart('alternative') + msg['From'] = r.get('QW_SENDER') or "quota-warning@localhost" + msg['Subject'] = r.get('QW_SUBJ') or "Quota warning" + msg['Date'] = formatdate(localtime = True) + text = "Your mailbox is almost full, currently %d%% are in use. Please consider deleting old messages." % (percent) + text_part = MIMEText(text, 'plain', 'utf-8') + html_part = MIMEText(html, 'html', 'utf-8') + msg.attach(text_part) + msg.attach(html_part) + msg['To'] = username + p = Popen(['/usr/local/libexec/dovecot/dovecot-lda', '-d', username, '-o', '"plugin/quota=maildir:User quota:noenforcing"'], stdout=PIPE, stdin=PIPE, stderr=STDOUT) + p.communicate(input=msg.as_string()) + +except Exception as ex: + print 'Failed to send quota notification: %s' % (ex) + sys.exit(1) + +try: + sys.stdout.close() +except: + pass + +try: + sys.stderr.close() +except: + pass