diff --git a/demo/__init__.py b/demo/__init__.py index c6fcc4bad..20ad29592 100755 --- a/demo/__init__.py +++ b/demo/__init__.py @@ -35,6 +35,10 @@ def announcement(**kwargs): return [txt] return "" +def password_change(user): + return [user.id == 1] + if 'modoboa.demo' in settings.INSTALLED_APPS: events.register("UserMenuDisplay", menu) events.register("GetAnnouncement", announcement) + events.register("PasswordChange", password_change) diff --git a/doc/plugin_api.rst b/doc/plugin_api.rst index ba48a4036..13c1e61ea 100644 --- a/doc/plugin_api.rst +++ b/doc/plugin_api.rst @@ -256,6 +256,17 @@ callbacks and indicates the place where the announcement will appear: Callbacks listening to this event must return a list of string. +PasswordChange +-------------- + +Raised just before a *password change* action. The associated ``User`` +object is provided inside the ``user`` keyword argument. + +Callbacks listening to this event must return a list containing either +``True`` or ``False``. If at least one ``True`` is returned, the +*password change* will be cancelled (ie. changing the password for +this user is disabled). + Parameters ========== diff --git a/lib/events.py b/lib/events.py index 631486e26..434dd358a 100644 --- a/lib/events.py +++ b/lib/events.py @@ -12,6 +12,8 @@ events = ["CreateDomain", "DeleteMailbox", "ModifyMailbox", + "PasswordChange", + "UserMenuDisplay", "AdminMenuDisplay", diff --git a/templates/common/error_simple.html b/templates/common/error_simple.html new file mode 100644 index 000000000..ddebe672e --- /dev/null +++ b/templates/common/error_simple.html @@ -0,0 +1,4 @@ +{% extends "layout_simple.html" %} +{% block content %} +

{{ error }}

+{% endblock %} diff --git a/userprefs/views.py b/userprefs/views.py index cab96d0c5..cfe3a55cc 100644 --- a/userprefs/views.py +++ b/userprefs/views.py @@ -3,9 +3,10 @@ from django.core.urlresolvers import reverse from django.http import HttpResponseRedirect from django.contrib.auth.decorators \ import login_required, user_passes_test +from django.conf import settings from django.utils.translation import ugettext as _ -from modoboa.lib import parameters -from modoboa.lib.webutils import _render, ajax_response +from modoboa.lib import parameters, events +from modoboa.lib.webutils import _render, _render_error, ajax_response from forms import * from modoboa.admin.models import Mailbox, Alias from modoboa.admin.lib import is_domain_admin @@ -21,6 +22,11 @@ def changepassword(request, tplname="userprefs/chpassword.html"): target = request.user else: target = Mailbox.objects.get(user=request.user.id) + res = events.raiseQueryEvent("PasswordChange", user=request.user) + if True in res: + ctx = dict(error=_("Password change is disabled for this user")) + return _render_error(request, errortpl="error_simple", user_context=ctx) + error = None if request.method == "POST": form = ChangePasswordForm(target, request.POST) @@ -32,7 +38,8 @@ def changepassword(request, tplname="userprefs/chpassword.html"): request.session["password"] = encrypt(request.POST["confirmation"]) target.save() return ajax_response(request, respmsg=_("Password changed")) - return ajax_response(request, status="ko", template=tplname, form=form, error=error) + return ajax_response(request, status="ko", template=tplname, + form=form, error=error) form = ChangePasswordForm(target) return _render(request, 'userprefs/chpassword.html', {