mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-17 05:41:25 +02:00
More documentation.
Creation/Removal of domains and mailboxes specific directories on filesystem.
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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]))
|
||||
|
||||
@@ -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
|
||||
@@ -80,3 +80,8 @@ INSTALLED_APPS = (
|
||||
'django.contrib.sites',
|
||||
'mailng.admin'
|
||||
)
|
||||
|
||||
# Mailng specific options
|
||||
STORAGE_PATH = "/var/vmail"
|
||||
VIRTUAL_UID = "vmail"
|
||||
VIRTUAL_GID = "vmail"
|
||||
|
||||
Reference in New Issue
Block a user