Files
modoboa/admin/views.py
T

448 lines
18 KiB
Python

# -*- coding: utf-8 -*-
from django.shortcuts import get_object_or_404, render_to_response
from django.template.loader import render_to_string
from django.template import RequestContext
from django.http import HttpResponse, HttpResponseRedirect
from django.utils import simplejson
from django.utils.translation import ugettext as _
from django.utils.http import urlquote
from django.core import serializers
from django.core.urlresolvers import reverse
from django.contrib.auth.decorators \
import login_required, permission_required, user_passes_test
from django.contrib.auth.models import User, Group
from django.contrib import messages
from modoboa import admin, userprefs
from modoboa.admin.models import Domain, Mailbox, Alias
from forms import MailboxForm, DomainForm, AliasForm, PermissionForm
from modoboa.lib.authbackends import crypt_password
from modoboa.lib import _render, _ctx_ok, _ctx_ko, getctx
from modoboa.lib import events, parameters
from modoboa.lib.models import Parameter
import string
import copy
import pwd
def is_superuser(user):
if not user.is_superuser:
user.message_set.create(message=_("Permission denied."))
return False
return True
def good_domain(f):
def dec(request, dom_id, **kwargs):
if request.user.is_superuser:
return f(request, dom_id, **kwargs)
mb = Mailbox.objects.get(user=request.user.id)
if isinstance(dom_id, str) or isinstance(dom_id, unicode):
dom_id = string.atoi(dom_id)
if dom_id == mb.domain.id:
return f(request, dom_id, **kwargs)
from django.conf import settings
path = urlquote(request.get_full_path())
login_url = settings.LOGIN_URL
return HttpResponseRedirect("%s?next=%s" % (login_url, path))
return dec
@login_required
def domains(request):
if not request.user.has_perm("admin.view_domains"):
print "redirect"
if request.user.has_perm("admin.view_mailboxes"):
mb = Mailbox.objects.get(user=request.user.id)
return mailboxes(request, dom_id=mb.domain.id)
return HttpResponseRedirect(reverse(userprefs.views.preferences))
domains = Domain.objects.all()
counters = {}
for dom in domains:
dom.mboxcounter = len(dom.mailbox_set.all())
return _render(request, 'admin/domains.html', {
"domains" : domains, "counters" : counters
})
@login_required
@permission_required("admin.add_domain")
def newdomain(request):
if request.method == "POST":
form = DomainForm(request.POST)
error = None
if form.is_valid():
if Domain.objects.filter(name=request.POST["name"]):
error = _("Domain with this name already defined")
else:
domain = form.save(commit=False)
if domain.create_dir():
form.save()
events.raiseEvent("CreateDomain", dom=domain)
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
})
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
form = DomainForm()
return render_to_response('admin/newdomain.html', {
"form" : form
})
@login_required
@permission_required("admin.change_domain")
def editdomain(request, dom_id):
domain = Domain.objects.get(pk=dom_id)
if request.method == "POST":
form = DomainForm(request.POST, instance=domain)
error = None
if form.is_valid():
if domain.name != request.POST["name"]:
if Domain.objects.filter(name=request.POST["name"]):
error = _("Domain with this name already defined")
else:
if not domain.rename_dir(request.POST["name"]):
error = _("Failed to rename domain, check permissions")
if not error:
form.save()
ctx = _ctx_ok(reverse(admin.views.domains))
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
ctx = _ctx_ko("admin/editdomain.html", {
"domain" : domain, "form" : form, "error" : error
})
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
form = DomainForm(instance=domain)
return render_to_response('admin/editdomain.html', {
"domain" : domain, "form" : form
})
@login_required
@permission_required("admin.delete_domain")
def deldomain(request, dom_id):
domain = Domain.objects.get(pk=dom_id)
events.raiseEvent("DeleteDomain", dom=domain)
domain.delete_dir()
domain.delete()
return HttpResponseRedirect('/modoboa/admin/')
@login_required
@good_domain
@permission_required("admin.view_mailboxes")
def mailboxes(request, dom_id=None):
domain = Domain.objects.get(pk=dom_id)
mailboxes = Mailbox.objects.filter(domain=dom_id)
return _render(request, 'admin/mailboxes.html', {
"mailboxes" : mailboxes, "domain" : domain
})
@login_required
@good_domain
@permission_required("admin.view_mailboxes")
def mailboxes_raw(request, dom_id=None):
mailboxes = Mailbox.objects.filter(domain=dom_id)
return _render(request, 'admin/mailboxes_raw.html', {
"mailboxes" : mailboxes
})
@login_required
@good_domain
@permission_required("admin.add_mailbox")
def newmailbox(request, dom_id=None):
domain = Domain.objects.get(pk=dom_id)
if request.method == "POST":
form = MailboxForm(request.POST)
error = None
if form.is_valid():
if Mailbox.objects.filter(address=request.POST["address"],
domain=dom_id):
error = _("Mailbox with this address already exists")
else:
mb = form.save(commit=False)
if mb.create_dir(domain):
from django.conf import settings
user = User()
user.username = user.email = "%s@%s" % (mb.address, domain.name)
user.set_unusable_password()
user.is_active = request.POST.has_key("enabled") \
and True or False
try:
fname, lname = mb.name.split()
except ValueError:
fname = mb.name
lname = ""
user.first_name = fname
user.last_name = lname
user.save()
mb.user = user
mb.password = crypt_password(request.POST["password1"])
mb.uid = pwd.getpwnam(parameters.get_admin("admin", "VIRTUAL_UID")).pw_uid
mb.gid = pwd.getpwnam(parameters.get_admin("admin", "VIRTUAL_GID")).pw_gid
mb.domain = domain
mb.quota = request.POST["quota"]
if not mb.quota:
mb.quota = domain.quota
mb.full_address = "%s@%s" % (mb.address, domain.name)
mb.save()
events.raiseEvent("CreateMailbox", mbox=mb)
messages.info(request, _("Mailbox created."),
fail_silently=True)
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
})
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
form = MailboxForm()
return render_to_response('admin/newmailbox.html', {
"domain" : domain, "form" : form
})
@login_required
@good_domain
@permission_required("admin.change_mailbox")
def editmailbox(request, dom_id, mbox_id=None):
mb = Mailbox.objects.get(pk=mbox_id)
if request.method == "POST":
oldmb = copy.deepcopy(mb)
form = MailboxForm(request.POST, instance=mb)
error = None
if form.is_valid():
if mb.address != request.POST["address"]:
if Mailbox.objects.filter(address=request.POST["address"],
domain=dom_id):
error = _("Mailbox with this address already exists")
else:
if not mb.rename_dir(mb.domain.name, request.POST["address"]):
error = _("Failed to rename mailbox, check permissions")
if not error:
mb = form.save(commit=False)
mb.user.is_active = request.POST.has_key("enabled") \
and request.POST["enabled"] or False
mb.user.save()
if request.POST["password1"] != u"é":
mb.password = crypt_password(request.POST["password1"])
mb.quota = request.POST["quota"]
if not mb.quota:
mb.quota = mb.domain.quota
mb.full_address = "%s@%s" % (mb.address, mb.domain.name)
mb.save()
events.raiseEvent("ModifyMailbox", mbox=mb, oldmbox=oldmb)
ctx = _ctx_ok(reverse(admin.views.mailboxes, args=[dom_id]))
return HttpResponse(simplejson.dumps(ctx),
mimetype="application/json")
ctx = _ctx_ko("admin/editmailbox.html", {
"mbox" : mb, "form" : form, "error" : error
})
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
form = MailboxForm(instance=mb)
form.fields['quota'].initial = mb.quota
form.fields['enabled'].initial = mb.user.is_active
form.fields['password1'].initial = "é"
form.fields['password2'].initial = "é"
return _render(request, 'admin/editmailbox.html', {
"form" : form, "mbox" : mb
})
@login_required
@good_domain
@permission_required("admin.delete_mailbox")
def delmailbox(request, dom_id, mbox_id=None):
mb = Mailbox.objects.get(pk=mbox_id)
events.raiseEvent("DeleteMailbox", mbox=mb)
if not request.GET.has_key("keepdir") or request.GET["keepdir"] != "true":
mb.delete_dir()
mb.user.delete()
mb.delete()
ctx = _ctx_ok("");
return HttpResponse(simplejson.dumps(ctx),
mimetype="application/json")
# return HttpResponseRedirect(reverse(admin.views.mailboxes,
# args=[dom_id]))
@login_required
@good_domain
@permission_required("admin.view_aliases")
def aliases(request, dom_id=None, mbox_id=None):
domain = Domain.objects.get(pk=dom_id)
if not mbox_id:
aliases = Alias.objects.filter(mboxes__domain__id=dom_id).distinct()
else:
aliases = Alias.objects.filter(mboxes__id=mbox_id)
return _render(request, 'admin/aliases.html', {
"aliases" : aliases, "domain" : domain
})
@login_required
@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, domain=domain)
error = None
if form.is_valid():
if Alias.objects.filter(address=request.POST["address"]):
error = _("Alias with this name already exists")
else:
alias = form.save(commit=False)
alias.full_address = "%s@%s" % (alias.address, domain.name)
alias.save()
form.save_m2m()
ctx = _ctx_ok(reverse(admin.views.aliases, args=[dom_id]))
return HttpResponse(simplejson.dumps(ctx),
mimetype="application/json")
ctx = _ctx_ko("admin/newalias.html", {
"domain" : dom_id, "form" : form, "error" : error
})
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
form = AliasForm(domain=domain)
return render_to_response('admin/newalias.html', {
"domain" : dom_id, "form" : form, "noerrors" : True
})
@login_required
@good_domain
@permission_required("admin.change_alias")
def editalias(request, dom_id, alias_id):
alias = Alias.objects.get(pk=alias_id)
if request.method == "POST":
form = AliasForm(request.POST, instance=alias)
error = None
if form.is_valid():
if alias.address != request.POST["address"] \
and 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()
form.save_m2m()
ctx = _ctx_ok(reverse(admin.views.aliases, args=[dom_id]))
return HttpResponse(simplejson.dumps(ctx),
mimetype="application/json")
ctx = _ctx_ko("admin/editalias.html", {
"alias" : alias, "form" : form, "error" : error
})
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
form = AliasForm(instance=alias)
return _render(request, 'admin/editalias.html', {
"form" : form, "alias" : alias, "domain" : dom_id
})
@login_required
@good_domain
@permission_required("admin.delete_alias")
def delalias(request, dom_id, alias_id):
alias = Alias.objects.get(pk=alias_id)
alias.delete()
return HttpResponseRedirect(reverse(admin.views.aliases,
args=[dom_id]))
@login_required
@user_passes_test(lambda u: u.is_superuser)
def settings(request):
admins = User.objects.filter(is_superuser=True)
domadmins = Mailbox.objects.filter(user__groups__name="DomainAdmins")
return _render(request, 'admin/permissions.html', {
"admins" : admins, "domadmins" : domadmins
})
@login_required
@user_passes_test(lambda u: u.is_superuser)
def addpermission(request):
if request.method == "POST":
form = PermissionForm(request.POST)
if request.POST.has_key('user'):
mboxid = request.POST['user']
form.fields["user"].choices = \
[(mboxid, Mailbox.objects.get(pk=mboxid)),]
if form.is_valid():
mb = Mailbox.objects.get(pk=request.POST["user"])
if request.POST["role"] == "SuperAdmins":
mb.user.is_superuser = True
mb.user.groups.clear()
else:
mb.user.is_superuser = False
mb.user.groups.add(Group.objects.get(name=request.POST["role"]))
mb.user.save()
ctx = _ctx_ok(reverse(admin.views.settings))
return HttpResponse(simplejson.dumps(ctx),
mimetype="application/json")
ctx = _ctx_ko("admin/addpermission.html", {
"form" : form
})
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
form = PermissionForm()
return _render(request, 'admin/addpermission.html', {
"form" : form
})
@login_required
@user_passes_test(lambda u: u.is_superuser)
def deletepermission(request, mbox_id, group):
if group == "SuperAdmins":
user = User.objects.get(pk=mbox_id)
if user.username == "admin":
messages.error(request, _("admin is intouchable!!"), fail_silently=True)
else:
user.is_superuser = False
user.save()
else:
mbox = Mailbox.objects.get(pk=mbox_id)
grp = Group.objects.get(name=group)
mbox.user.groups.remove(grp)
mbox.user.save()
return HttpResponseRedirect(reverse(admin.views.settings))
@login_required
@user_passes_test(lambda u: u.is_superuser)
def viewparameters(request):
apps = sorted(parameters._params.keys())
gparams = []
for app in apps:
tmp = {"name" : app, "params" : []}
for p in sorted(parameters._params[app]['A']):
param_def = parameters._params[app]['A'][p]
newdef = {"name" : p,
"value" : parameters.get_admin(app, p),
"help" : param_def["help"],
"default" : param_def["default"],
"type" : param_def["type"]}
if "values" in param_def.keys():
newdef["values"] = param_def["values"]
tmp["params"] += [newdef]
gparams += [tmp]
return _render(request, 'admin/parameters.html', {
"gparams" : gparams
})
@login_required
@user_passes_test(lambda u: u.is_superuser)
def saveparameters(request):
for pname, v in request.POST.iteritems():
if pname == "update":
continue
app, name = pname.split('.')
parameters.save_admin(app, name, v)
ctx = getctx("ok")
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")