diff --git a/admin/lib.py b/admin/lib.py
new file mode 100644
index 000000000..40b896dd2
--- /dev/null
+++ b/admin/lib.py
@@ -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
diff --git a/admin/views.py b/admin/views.py
index ab30b955c..aff0c36dc 100644
--- a/admin/views.py
+++ b/admin/views.py
@@ -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"):
diff --git a/templates/userprefs/setforward.html b/templates/userprefs/setforward.html
new file mode 100644
index 000000000..67659ca3c
--- /dev/null
+++ b/templates/userprefs/setforward.html
@@ -0,0 +1,18 @@
+{% extends "layout_simple.html" %}
+{% block html_head %}
+
+{% endblock %}
+{% block content %}
+{% load i18n %}
+
{% trans "Define your forward" %}
+
+{% if error %}{{ error }}
{% endif %}
+{% url userprefs.views.setforward as action_url %}
+
+{% endblock %}
diff --git a/userprefs/forms.py b/userprefs/forms.py
index 2adf07b0c..cd954f746 100644
--- a/userprefs/forms.py
+++ b/userprefs/forms.py
@@ -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."))
+
diff --git a/userprefs/templatetags/uprefs_extras.py b/userprefs/templatetags/uprefs_extras.py
index 8e0268d52..9a844f754 100644
--- a/userprefs/templatetags/uprefs_extras.py
+++ b/userprefs/templatetags/uprefs_extras.py
@@ -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")
diff --git a/userprefs/urls.py b/userprefs/urls.py
index 06bde3ff4..a14919f38 100644
--- a/userprefs/urls.py
+++ b/userprefs/urls.py
@@ -5,4 +5,5 @@ urlpatterns = patterns('modoboa.userprefs.views',
(r'^preferences/$', 'preferences'),
(r'^preferences/save/$', 'savepreferences'),
(r'^changepassword/$', 'changepassword'),
+ (r'^setforward/$', 'setforward'),
)
diff --git a/userprefs/views.py b/userprefs/views.py
index 9a77897f0..37f986bb2 100644
--- a/userprefs/views.py
+++ b/userprefs/views.py
@@ -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())