Added per-user forward definition (with a custom interface available inside the "Options" menu). It will not be available for admins.

see #143
This commit is contained in:
Antoine Nguyen
2011-06-06 15:44:30 +02:00
parent a2ec92daa7
commit add222840c
7 changed files with 134 additions and 27 deletions
+45
View File
@@ -0,0 +1,45 @@
# coding: utf-8
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib.auth.models import User, Group
from models import *
def is_domain_admin(user):
"""Tell if a user is administrator for a domain of not
Whatever the domain, we just want to know if the given user is
declared as a domain administrator.
:param user: a User object
:return: True if the user is a domain administrator, False otherwise.
"""
grp = Group.objects.get(name="DomainAdmins")
return grp in user.groups.all()
def good_domain(f):
"""Custom permission decorator
Check if a domain administrator is accessing the good domain.
:param f: the original called function
"""
def dec(request, **kwargs):
if request.user.is_superuser:
return f(request, **kwargs)
mb = Mailbox.objects.get(user=request.user.id)
access = True
if request.GET.has_key("domid"):
dom_id = int(request.GET["domid"])
if dom_id != mb.domain.id:
access = False
else:
q = request.GET.copy()
q["domid"] = mb.domain.id
request.GET = q
if access:
return f(request, **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
+1 -23
View File
@@ -11,6 +11,7 @@ from django.contrib.auth.models import User, Group
from django.contrib import messages
from django.db import transaction, IntegrityError
from lib import *
from modoboa import admin, userprefs
from models import *
from admin.permissions import *
@@ -20,29 +21,6 @@ from modoboa.lib import _render, ajax_response, ajax_simple_response, \
from modoboa.lib.models import Parameter
import copy
def good_domain(f):
def dec(request, **kwargs):
if request.user.is_superuser:
return f(request, **kwargs)
mb = Mailbox.objects.get(user=request.user.id)
access = True
if request.GET.has_key("domid"):
dom_id = int(request.GET["domid"])
if dom_id != mb.domain.id:
access = False
else:
q = request.GET.copy()
q["domid"] = mb.domain.id
request.GET = q
if access:
return f(request, **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
def render_domains_page(request, page, **kwargs):
template = "admin/%s.html" % page
if request.GET.has_key("domid"):
+18
View File
@@ -0,0 +1,18 @@
{% extends "layout_simple.html" %}
{% block html_head %}
<script src="{{ MEDIA_URL }}js/form.js" type="text/javascript"></script>
{% endblock %}
{% block content %}
{% load i18n %}
<div class="title"><h1>{% trans "Define your forward" %}</h1></div>
{% if error %}<div class="error">{{ error }}</div>{% endif %}
{% url userprefs.views.setforward as action_url %}
<form action="{{ action_url }}" method="post" name="setfwform" id="setfwform">
{% include "common/genericform.html" %}
<div class="lastrow" align="center">
<input type="submit" class="button" name="submit" value="{% trans 'Update' %}" />
</div>
</form>
{% endblock %}
+22 -1
View File
@@ -1,8 +1,12 @@
from django import forms
from modoboa.admin.models import Mailbox
from modoboa.admin.models import Domain
from modoboa.lib import _check_password
from django.contrib.auth.models import check_password
from django.utils.translation import ugettext as _
from modoboa.lib import split_mailbox
class BadDestination(Exception):
pass
class ChangePasswordForm(forms.Form):
oldpassword = forms.CharField(label=_("Old password"),
@@ -30,3 +34,20 @@ class ChangePasswordForm(forms.Form):
if self.cleaned_data["newpassword"] != self.cleaned_data["confirmation"]:
raise forms.ValidationError(_("Passwords mismatch"))
return self.cleaned_data["confirmation"]
class ForwardForm(forms.Form):
dest = forms.CharField(label=_("Destination(s)"), widget=forms.Textarea)
def parse_dest(self):
self.dests = []
for d in self.cleaned_data["dest"].strip().split(","):
local_part, domname = split_mailbox(d)
if not local_part or not domname or not len(domname):
raise BadDestination("Invalid mailbox syntax for %s" % d)
try:
mb = Domain.objects.get(name=domname)
except Mailbox.DoesNotExist:
self.dests += [d]
else:
raise BadDestination(_("You can't define a forward to a local destination. Please ask your administrator to create an alias instead."))
+11
View File
@@ -4,6 +4,7 @@ from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse
from modoboa import userprefs
from modoboa.lib import events, static_url
from modoboa.admin.lib import is_domain_admin
register = template.Library()
@@ -29,6 +30,16 @@ def options_menu(user):
]
},
]
if not user.is_superuser and not is_domain_admin(user):
entries[0]["menu"] += [{
"name" : "setforwards",
"url" : reverse(userprefs.views.setforward),
"img" : static_url("pics/alias.png"),
"label" : _("Forward"),
"class" : "boxed",
"rel" : "{handler:'iframe',size:{x:360,y:320}}"
}]
entries[0]["menu"] += events.raiseQueryEvent("UserMenuDisplay",
target="options_menu")
+1
View File
@@ -5,4 +5,5 @@ urlpatterns = patterns('modoboa.userprefs.views',
(r'^preferences/$', 'preferences'),
(r'^preferences/save/$', 'savepreferences'),
(r'^changepassword/$', 'changepassword'),
(r'^setforward/$', 'setforward'),
)
+36 -3
View File
@@ -2,12 +2,13 @@ import copy
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.contrib.auth.decorators \
import login_required
import login_required, user_passes_test
from django.utils.translation import ugettext as _
from modoboa.lib import _render, ajax_response, parameters
from modoboa.lib import crypt_password
from forms import ChangePasswordForm
from modoboa.admin.models import Mailbox
from forms import *
from modoboa.admin.models import Mailbox, Alias
from modoboa.admin.lib import is_domain_admin
@login_required
def index(request):
@@ -36,6 +37,38 @@ def changepassword(request, tplname="userprefs/chpassword.html"):
"form" : form
})
@login_required
@user_passes_test(lambda u: not u.is_superuser and not is_domain_admin(u))
def setforward(request, tplname="userprefs/setforward.html"):
mb = Mailbox.objects.get(user=request.user.id)
try:
al = Alias.objects.get(address=mb.address,
domain__name=mb.domain.name)
except Alias.DoesNotExist:
al = None
if request.method == "POST":
form = ForwardForm(request.POST)
error = None
if form.is_valid():
try:
if al is None:
al = Alias()
al.address = mb.address
al.domain = mb.domain
al.enabled = mb.user.is_active
form.parse_dest()
al.save([], form.dests)
return ajax_response(request, respmsg=_("Forward updated"))
except BadDestination, e:
error = str(e)
return ajax_response(request, status="ko", template=tplname, form=form, error=error)
form = ForwardForm()
if al is not None:
form.fields["dest"].initial = al.extmboxes
return _render(request, tplname, {
"form" : form
})
@login_required
def preferences(request):
apps = sorted(parameters._params.keys())