More documentation.

Creation/Removal of domains and mailboxes specific directories on filesystem.
This commit is contained in:
Antoine Nguyen
2009-03-25 18:56:02 +01:00
parent 4d5c243548
commit d234b308b7
6 changed files with 157 additions and 28 deletions
+44 -3
View File
@@ -13,7 +13,10 @@ How to install
Download Mailng's tarball and extract it::
tar xzf mailng-<version>.tar.gz
Enter the mailng repository, 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.
Initialise the database by running the following command::
python manage.py syncdb
@@ -23,7 +26,45 @@ Create the super admin account (just follow the procedure).
Testing installation
--------------------
As a typical Django application, Mailng can be tested using a simple web server. Just run this command to start it::
As a typical Django application, Mailng can be tested using a simple web
server. Just run this command to start it::
python manage.py runserver
You will be able to play with mailng by looking at http://<youraddress>:8000/mailng/admin/
You will be able to play with mailng by looking at
http://<youraddress>:8000/mailng/admin/.
Tips to link Mailng with postfix
--------------------------------
First, define following maps on your server::
# /etc/postfix/sql-domains.cf
user = <user>
password = <password>
dbname = <database>
query = SELECT name FROM domains WHERE name='%s' AND enabled='1'
# /etc/postfix/sql-mailboxes.cf
user = <user>
password = <password>
dbname = <database>
query = SELECT path FROM mailboxes WHERE address = '%s' AND enabled = '1'
Then, use the following configuration in your /etc/postfix/main.cf file
(this is one possible configuration)::
# Stuff before
mailbox_transport = virtual
home_mailbox = Maildir/
maildrop_destination_recipient_limit = 1
virtual_minimum_uid = 500
virtual_gid_maps = static:500
virtual_uid_maps = static:500
virtual_mailbox_base = /var/vmail
relay_domains = mysql:/etc/postfix/sql-domains.cf
virtual_mailbox_domains = mysql:/etc/postfix/sql-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/sql-mailboxes.cf
virtual_alias_domains =
# Stuff after
+8 -3
View File
@@ -1,7 +1,12 @@
Mailng is a light web messaging solution. It provides different tools that facilitates virtual domains hosting. It is designed to be integrated with email servers like postfix (http://www.postfix.org/) and/or dovecot (http://www.dovecot.org/).
Mailng is a light web messaging solution. It provides different tools that
facilitate virtual domains hosting. It is designed to be integrated with email
servers like postfix (http://www.postfix.org/) and/or dovecot
(http://www.dovecot.org/).
For now, only the administration component is available. Additional tools will come in a near future.
For now, only the administration component is available. Additional tools will
come in a near future.
Django is needed to use Mailng (http://www.djangoproject.com/)
Mootools version 1.2 (http://www.mootools.net/) and SqueezeBox version 1.1 (http://digitarald.de/project/squeezebox/) are provided with Mailng.
Mootools version 1.2 (http://www.mootools.net/) and SqueezeBox version 1.1
(http://digitarald.de/project/squeezebox/) are provided with Mailng.
+31 -22
View File
@@ -8,6 +8,7 @@ from django.core.urlresolvers import reverse
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from mailng import admin
from mailng.lib.fsops import *
from mailng.admin.models import Domain, Mailbox, Alias
from forms import MailboxForm, DomainForm, AliasForm
@@ -40,9 +41,12 @@ def newdomain(request):
if Domain.objects.filter(name=request.POST["name"]):
error = "Domain with this name already defined"
else:
form.save()
ctx = _ctx_ok(reverse(admin.views.domains))
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
if create_domain(request.POST["name"]):
form.save()
ctx = _ctx_ok(reverse(admin.views.domains))
return HttpResponse(simplejson.dumps(ctx),
mimetype="application/json")
error = "Failed to initialise domain, check permissions"
ctx = _ctx_ko("admin/newdomain.html", {
"form" : form, "error" : error
})
@@ -52,6 +56,7 @@ def newdomain(request):
return render_to_response('admin/newdomain.html', {
"form" : form
})
@login_required
def editdomain(request, dom_id):
domain = Domain.objects.get(pk=dom_id)
@@ -74,6 +79,7 @@ def editdomain(request, dom_id):
@login_required
def deldomain(request, dom_id):
domain = Domain.objects.get(pk=dom_id)
destroy_domain(domain.name)
domain.delete()
return HttpResponseRedirect('/mailng/admin/')
@@ -96,25 +102,27 @@ def newmailbox(request, dom_id=None):
domain=dom_id):
error = "Mailbox with this address already exists"
else:
mb = form.save(commit=False)
user = User()
user.username = user.email = "%s@%s" % (mb.address, domain.name)
user.set_password(request.POST["password1"])
user.is_active = request.POST.has_key("enabled") \
and True or False
fname, lname = mb.name.split()
user.first_name = fname
user.last_name = lname
user.save()
mb.user = user
mb.uid = mb.gid = 500
mb.domain = domain
mb.save()
ctx = _ctx_ok(reverse(admin.views.mailboxes, args=[domain.id]))
return HttpResponse(simplejson.dumps(ctx),
mimetype="application/json")
if create_mailbox(domain.name, request.POST["address"]):
mb = form.save(commit=False)
user = User()
user.username = user.email = "%s@%s" % (mb.address, domain.name)
user.set_password(request.POST["password1"])
user.is_active = request.POST.has_key("enabled") \
and True or False
fname, lname = mb.name.split()
user.first_name = fname
user.last_name = lname
user.save()
mb.user = user
mb.uid = mb.gid = 500
mb.domain = domain
mb.save()
ctx = _ctx_ok(reverse(admin.views.mailboxes, args=[domain.id]))
return HttpResponse(simplejson.dumps(ctx),
mimetype="application/json")
error = "Failed to initialise mailbox, check permissions"
ctx = _ctx_ko("admin/newmailbox.html", {
"form" : form, "domain" : domain, "error" : error
})
@@ -156,6 +164,7 @@ def editmailbox(request, dom_id, mbox_id=None):
@login_required
def delmailbox(request, dom_id, mbox_id=None):
mb = Mailbox.objects.get(pk=mbox_id)
destroy_mailbox(mb.domain.name, mb.address)
mb.delete()
return HttpResponseRedirect(reverse(admin.views.mailboxes,
args=[dom_id]))
View File
+69
View File
@@ -0,0 +1,69 @@
# -*- coding: utf-8 -*-
import popen2
import os
import time
from django.conf import settings
def exec_pipe(cmd):
"""Exécute une commande et récupère la sortie générée
Le module popen2 est utilisé pour l'exécution de la commande. Un
objet Popen4 est créé car il regroupe la sortie standard et la sortie
d'erreur dans le même fd.
De plus, popen2 est le seul à pouvoir capturer retourner le code de
sortie de la commande.
cmd -- commande à exécuter
Retourne un couple (code de sortie, texte de sortie)
"""
child = popen2.Popen4(cmd)
child.tochild.close()
while True:
ret = child.poll()
if ret != -1:
break
time.sleep(0.001)
output = child.fromchild.read()
if not ret:
code = 0
else:
if os.WIFEXITED(ret):
code = os.WEXITSTATUS(ret), output
else:
code = -1
return code, output
def create_domain(name):
code, output = exec_pipe("sudo -u %s mkdir %s/%s" \
% (settings.VIRTUAL_UID, settings.STORAGE_PATH,
name))
if code:
os.system("echo '%s' >> /tmp/vmail.log" % output)
return False
return True
def destroy_domain(name):
code, output = exec_pipe("sudo -u %s rm -r %s/%s" \
% (settings.VIRTUAL_UID, settings.STORAGE_PATH,
name))
if code:
return False
return True
def create_mailbox(domain, name):
code, output = exec_pipe("sudo -u %s mkdir -p %s/%s/%s/.maildir" \
% (settings.VIRTUAL_UID, settings.STORAGE_PATH,
domain, name))
if code:
return False
return True
def destroy_mailbox(domain, name):
code, output = exec_pipe("sudo -u %s rm -r %s/%s/%s" \
% (settings.VIRTUAL_UID, settings.STORAGE_PATH,
domain, name))
if code:
return False
return True
+5
View File
@@ -80,3 +80,8 @@ INSTALLED_APPS = (
'django.contrib.sites',
'mailng.admin'
)
# Mailng specific options
STORAGE_PATH = "/var/vmail"
VIRTUAL_UID = "vmail"
VIRTUAL_GID = "vmail"