From 233e695a55156130b276243b02858a900c10abea Mon Sep 17 00:00:00 2001 From: tonio Date: Thu, 17 Jun 2010 17:42:41 +0200 Subject: [PATCH] First fixes for 0.8-rc1. * The bigger one concerns fixtures. As django 1.2 resolves it by implementing natural keys, it's becoming a requirement. * There was also problems 0002_auto__del_field_alias_mbox, my bad... * It was possible to create aliases that point to addresses of other domains! * Some path problems in the stats module. * Some path problems with the autoreply. --- INSTALL | 38 ++++++++++------- admin/fixtures/initial_data.json | 2 +- .../0002_auto__del_field_alias_mbox.py | 4 +- admin/views.py | 6 +-- .../postfix_autoreply/scripts/autoreply | 13 +++--- .../postfix_autoreply/scripts/autoreply.py | 6 ++- .../scripts/upgrade_autoreply.py | 42 ++++++++++--------- extensions/stats/scripts/logparser.py | 2 +- extensions/stats/templates/graphs.html | 2 +- extensions/stats/views.py | 12 +----- 10 files changed, 68 insertions(+), 59 deletions(-) diff --git a/INSTALL b/INSTALL index 146ca0ccf..c13d19466 100644 --- a/INSTALL +++ b/INSTALL @@ -5,7 +5,7 @@ Requirements ------------ - Python version 2.6+ -- Django version 1.0+ (http://docs.djangoproject.com/en/dev/intro/install/#intro-install) +- Django version 1.2+ (http://docs.djangoproject.com/en/dev/intro/install/#intro-install) - south version 0.7+ (http://south.aeracode.org/) How to install @@ -13,19 +13,20 @@ How to install Download Mailng's tarball and extract it:: - tar xzf mailng-.tar.gz - mv mailng- mailng + # tar xzf mailng-.tar.gz + # mv mailng- mailng -Settings file +Then, enter the mailng directory, create a settings.py file (you can +use settings-sample.py as a model). Specify database relative +informations. You must choose between mysql and postgresql, other +types are not supported by major email projects like postfix or +dovecot. - Enter the mailng directory, create a settings.py file (you can use - settings-sample.py as a model). - Specify database relative informations. - You must choose between mysql and postgresql, other types are not supported by - major email projects like postfix or dovecot. - Create a database with the name you specified in settings.py. - you will probably need python database module backend like MySQLdb. - Modify TEMPLATE_DIRS. +Create a database with the name you specified in settings.py. Make +sure your database is using UTF8 as a default charset. If not, you +will surely have problems with MySQL. + +You will probably need to install a python database backend like MySQLdb. Initialise the database by running the following command:: @@ -187,7 +188,13 @@ Then run the following commands to update MailNG SQL schema and content:: # python manage.py syncdb # python manage.py migrate postfix-autoreply # export PYTHONPATH=$PWD/.. - # DJANGO_SETTINGS_MODULE=mailng.settings ./scripts/upgrade_autoreply.py + # DJANGO_SETTINGS_MODULE=mailng.settings ./scripts/postfix_autoreply/upgrade_autoreply.py + +The user that executes the autoreply script needs to access +settings.py. You must apply proper permissions on this file. For +example, if settings.py belongs to www-data:www-data, you can add the +vmail user to the www-data group and set the read permission for the +group. To make Postfix understand this feature, you need to update your configuration files as follow:: @@ -199,7 +206,7 @@ files as follow:: # /etc/postfix/master.cf autoreply unix - n n - - pipe - flags= user=nobody argv=/scripts/autoreply $sender $mailbox + flags= user=vmail: argv=/scripts/postfix_autoreply/autoreply $sender $mailbox Then, create new map files with the following content:: @@ -227,7 +234,8 @@ pre-defined time period. By default, this period is equal to 1 day parameter available in the admin panel. NB: Be sure that both 'autoreply' and 'autoreply.py' scripts (located -inside the 'scripts' directory) have good permissions (ie. 0755). +inside the 'scripts/postfix_autoreply' directory) have good +permissions (ie. 0755). Tips to link Mailng with dovecot -------------------------------- diff --git a/admin/fixtures/initial_data.json b/admin/fixtures/initial_data.json index 2a5cd806a..dbe3919f0 100644 --- a/admin/fixtures/initial_data.json +++ b/admin/fixtures/initial_data.json @@ -1 +1 @@ -[{"pk": 1, "model": "auth.group", "fields": {"name": "DomainAdmins", "permissions": [36, 37, 38, 40, 41, 42, 34, 39, 43]}}] +[{"pk": 1, "model": "auth.group", "fields": {"name": "DomainAdmins", "permissions": [["add_mailbox", "admin", "mailbox"], ["change_mailbox", "admin", "mailbox"], ["delete_mailbox", "admin", "mailbox"], ["add_alias", "admin", "alias"], ["change_alias", "admin", "alias"], ["delete_alias", "admin", "alias"], ["view_domain", "admin", "domain"], ["view_mailboxes", "admin", "mailbox"], ["view_aliases", "admin", "alias"]]}}] diff --git a/admin/migrations/0002_auto__del_field_alias_mbox.py b/admin/migrations/0002_auto__del_field_alias_mbox.py index 3b8370b2f..cf093d77c 100644 --- a/admin/migrations/0002_auto__del_field_alias_mbox.py +++ b/admin/migrations/0002_auto__del_field_alias_mbox.py @@ -5,7 +5,7 @@ from south.v2 import SchemaMigration from django.db import models class Migration(SchemaMigration): - no_dry_dun = True + no_dry_run = True def forwards(self, orm): @@ -18,7 +18,7 @@ class Migration(SchemaMigration): db.create_unique('admin_alias_mboxes', ['alias_id', 'mailbox_id']) for alias in orm.Alias.objects.all(): - alias.mboxes.append(alias.mbox_id) + alias.mboxes.add(alias.mbox_id) alias.save() # Deleting field 'Alias.mbox' diff --git a/admin/views.py b/admin/views.py index ee9c3ebdb..b4128c234 100644 --- a/admin/views.py +++ b/admin/views.py @@ -287,14 +287,14 @@ def aliases(request, dom_id=None, mbox_id=None): @good_domain @permission_required("admin.add_alias") def newalias(request, dom_id): + domain = Domain.objects.get(pk=dom_id) if request.method == "POST": - form = AliasForm(request.POST) + form = AliasForm(request.POST, domain=domain) error = None if form.is_valid(): if Alias.objects.filter(address=request.POST["address"]): error = _("Alias with this name already exists") else: - domain = Domain.objects.get(pk=dom_id) alias = form.save(commit=False) alias.full_address = "%s@%s" % (alias.address, domain.name) alias.save() @@ -307,7 +307,7 @@ def newalias(request, dom_id): }) return HttpResponse(simplejson.dumps(ctx), mimetype="application/json") - form = AliasForm() + form = AliasForm(domain=domain) return render_to_response('admin/newalias.html', { "domain" : dom_id, "form" : form, "noerrors" : True }) diff --git a/extensions/postfix_autoreply/scripts/autoreply b/extensions/postfix_autoreply/scripts/autoreply index f599c0912..e865ddf74 100755 --- a/extensions/postfix_autoreply/scripts/autoreply +++ b/extensions/postfix_autoreply/scripts/autoreply @@ -1,8 +1,11 @@ #!/bin/sh -BASEDIR=/home/tonio/projets/devel -export PYTHONPATH=$BASEDIR -export DJANGO_SETTINGS_MODULE=mailng.settings -#export PYTHON_EGG_CACHE=/tmp +PYTHON=python +BASEDIR=/var/www +# If the user executing this script has no homedir or no shell, you +# must need to set the above variable. +EGG_CACHE="" -$BASEDIR/mailng/scripts/postfix_autoreply/autoreply.py $1 $2 +PYTHON_EGG_CACHE=$EGG_CACHE PYTHONPATH=$BASEDIR \ + DJANGO_SETTINGS_MODULE=mailng.settings $PYTHON \ + $BASEDIR/mailng/scripts/postfix_autoreply/autoreply.py $1 $2 diff --git a/extensions/postfix_autoreply/scripts/autoreply.py b/extensions/postfix_autoreply/scripts/autoreply.py index a8ea3f596..64f8b70d6 100755 --- a/extensions/postfix_autoreply/scripts/autoreply.py +++ b/extensions/postfix_autoreply/scripts/autoreply.py @@ -7,6 +7,7 @@ from email.mime.text import MIMEText import datetime from mailng.lib import parameters from mailng.admin.models import Mailbox +from mailng.extensions.postfix_autoreply import main from mailng.extensions.postfix_autoreply.models import ARmessage, ARhistoric if __name__ == "__main__": @@ -29,8 +30,9 @@ if __name__ == "__main__": try: lastar = ARhistoric.objects.get(armessage=armessage.id, sender=sender) - parameters.get_admin("postfix_autoreply", "AUTOREPLIES_TIMEOUT") - delta = datetime.timedelta(seconds=timeout) + main.init() + timeout = parameters.get_admin("postfix_autoreply", "AUTOREPLIES_TIMEOUT") + delta = datetime.timedelta(seconds=int(timeout)) if lastar.last_sent + delta > datetime.datetime.now(): sys.exit(0) except ARhistoric.DoesNotExist: diff --git a/extensions/postfix_autoreply/scripts/upgrade_autoreply.py b/extensions/postfix_autoreply/scripts/upgrade_autoreply.py index c7ee734c2..e7ac4d64d 100755 --- a/extensions/postfix_autoreply/scripts/upgrade_autoreply.py +++ b/extensions/postfix_autoreply/scripts/upgrade_autoreply.py @@ -1,27 +1,31 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +import sys from django.conf import settings from mailng.admin.models import Domain, Mailbox if __name__ == "__main__": - if "mailng.extensions.postfix_autoreply" in settings.INSTALLED_APPS: - import mailng.extensions.postfix_autoreply.main as par - from mailng.extensions.postfix_autoreply.models import Transport, Alias - - par.init() - doms = Domain.objects.all() - for dom in doms: - try: - trans = Transport.objects.get(domain="autoreply.%s" % dom.name) - continue - except Transport.DoesNotExist: - par.onCreateDomain(dom=dom) - mboxes = Mailbox.objects.filter(domain=dom.id) - for mb in mboxes: - try: - alias = Alias.objects.get(full_address=mb.full_address) - continue - except Alias.DoesNotExist: - par.onCreateMailbox(mbox=mb) + if not "mailng.extensions.postfix_autoreply" in settings.INSTALLED_APPS: + print "Postfix autoreply extension is not activated" + sys.exit(1) + + import mailng.extensions.postfix_autoreply.main as par + from mailng.extensions.postfix_autoreply.models import Transport, Alias + + par.init() + doms = Domain.objects.all() + for dom in doms: + try: + trans = Transport.objects.get(domain="autoreply.%s" % dom.name) + continue + except Transport.DoesNotExist: + par.onCreateDomain(dom=dom) + mboxes = Mailbox.objects.filter(domain=dom.id) + for mb in mboxes: + try: + alias = Alias.objects.get(full_address=mb.full_address) + continue + except Alias.DoesNotExist: + par.onCreateMailbox(mbox=mb) diff --git a/extensions/stats/scripts/logparser.py b/extensions/stats/scripts/logparser.py index 65565a546..0894f9762 100755 --- a/extensions/stats/scripts/logparser.py +++ b/extensions/stats/scripts/logparser.py @@ -9,7 +9,7 @@ import string, pdb from optparse import OptionParser from mailng.lib import parameters from mailng.admin.models import Domain -import grapher +import mailng.extensions.stats.grapher as grapher """ Postfix log parser. diff --git a/extensions/stats/templates/graphs.html b/extensions/stats/templates/graphs.html index 1779fff3b..790380175 100644 --- a/extensions/stats/templates/graphs.html +++ b/extensions/stats/templates/graphs.html @@ -4,6 +4,6 @@ {% endif %} {% for elems in graphs %}

{{ elems.label }}

-

{% trans 'No statistics available' %}

{% endfor %} diff --git a/extensions/stats/views.py b/extensions/stats/views.py index f1f912350..77c95215c 100644 --- a/extensions/stats/views.py +++ b/extensions/stats/views.py @@ -25,22 +25,14 @@ periods = [{"name" : "day", "label" : _("Day")}, @login_required @user_passes_test(lambda u: u.is_superuser) def adminindex(request): - period = request.GET.has_key("period") and request.GET["period"] or "day" - domain = request.GET.has_key("domain") and request.GET["domain"] or "global" - if domain != "global": - domain = Domain.objects.get(pk=domain) - domain = domain.name domains = Domain.objects.all() - G = Grapher() - for name, t in tpl.iteritems(): - G.make_defaults(domain, t) - return _render(request, 'stats/adminindex.html', { "admin" : True, + "domain" : "global", "domains" : domains, "graphs" : graph_list, "periods" : periods, - "period" : period}) + "period" : "day"}) @login_required @good_domain