mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-17 05:41:25 +02:00
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:
@@ -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
@@ -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"):
|
||||
|
||||
@@ -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
@@ -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."))
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -5,4 +5,5 @@ urlpatterns = patterns('modoboa.userprefs.views',
|
||||
(r'^preferences/$', 'preferences'),
|
||||
(r'^preferences/save/$', 'savepreferences'),
|
||||
(r'^changepassword/$', 'changepassword'),
|
||||
(r'^setforward/$', 'setforward'),
|
||||
)
|
||||
|
||||
+36
-3
@@ -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())
|
||||
|
||||
Reference in New Issue
Block a user