wip: relay domains support

* Unit tests added (limits application)
* Added support for limits
* Big changes were required
* Using standard HTTP codes to identify errors (json)
* Custom exceptions have been reworked (not finished yet)

see #491
This commit is contained in:
Antoine Nguyen
2013-10-28 18:36:42 +01:00
parent d7a2e5c30b
commit f91ef1adf2
62 changed files with 1484 additions and 950 deletions
+4 -1
View File
@@ -15,6 +15,7 @@ base_events = [
"RoleChanged",
"GetExtraRoles",
"PasswordChange",
"UserCanSetRole",
"UserMenuDisplay",
"AdminMenuDisplay",
@@ -32,7 +33,9 @@ base_events = [
"ExtraAdminContent",
"ExtraUprefsRoutes",
"ExtraUprefsJS"
"ExtraUprefsJS",
"GetExtraParameters"
]
-14
View File
@@ -1,14 +0,0 @@
"""
:mod:`exceptions` --- Custom exceptions of the admin. application
-----------------------------------------------------------------
"""
from modoboa.lib.exceptions import ModoboaException
class AdminError(ModoboaException):
"""
Just a Custom exception to identify errors coming from the admin
application.
"""
pass
+7
View File
@@ -49,6 +49,13 @@ class ExtensionsPool(object):
self.extensions[name]["instance"] = self.extensions[name]["cls"]()
return self.extensions[name]["instance"]
def is_extension_enabled(self, name):
from modoboa.core.models import Extension
if not name in self.extensions:
return False
return Extension.objects.get(name=name).enabled
def get_extension_infos(self, name):
instance = self.get_extension(name)
if instance is None:
+13 -10
View File
@@ -17,10 +17,11 @@ from django.contrib.auth.models import (
UserManager, Group, AbstractBaseUser, PermissionsMixin
)
from modoboa.lib import events, md5crypt, parameters
from modoboa.lib.exceptions import PermDeniedException
from modoboa.lib.exceptions import (
PermDeniedException, InternalError, BadRequest
)
from modoboa.lib.sysutils import exec_cmd
from modoboa.core.extensions import exts_pool
from modoboa.core.exceptions import AdminError
try:
from modoboa.lib.ldaputils import *
@@ -72,7 +73,9 @@ class User(AbstractBaseUser, PermissionsMixin):
get_object_owner, grant_access_to_object, ungrant_access_to_object
if fromuser == self:
raise AdminError(_("You can't delete your own account"))
raise PermDeniedException(
_("You can't delete your own account")
)
if not fromuser.can_access(self):
raise PermDeniedException
@@ -133,15 +136,15 @@ class User(AbstractBaseUser, PermissionsMixin):
self.password = self._crypt_password(raw_value)
else:
if not ldap_available:
raise AdminError(
raise InternalError(
_("Failed to update password: LDAP module not installed")
)
ab = LDAPAuthBackend()
try:
ab.update_user_password(self.username, curvalue, raw_value)
except LDAPException, e:
raise AdminError(_("Failed to update password: %s" % str(e)))
except LDAPException as e:
raise InternalError(_("Failed to update password: %s" % str(e)))
events.raiseEvent(
"PasswordUpdated", self, raw_value, self.pk is None
)
@@ -197,7 +200,7 @@ class User(AbstractBaseUser, PermissionsMixin):
try:
return self.groups.all()[0].name
except IndexError:
return "SimpleUsers"
return "---"
@property
def enabled(self):
@@ -318,7 +321,7 @@ class User(AbstractBaseUser, PermissionsMixin):
:param crypt_password:
"""
if len(row) < 7:
raise AdminError(_("Invalid line"))
raise BadRequest(_("Invalid line"))
role = row[6].strip()
if not user.is_superuser and not role in ["SimpleUsers", "DomainAdmins"]:
raise PermDeniedException(
@@ -327,11 +330,11 @@ class User(AbstractBaseUser, PermissionsMixin):
self.username = row[1].strip()
if role == "SimpleUsers":
if (len(row) < 8 or not row[7].strip()):
raise AdminError(
raise BadRequest(
_("The simple user '%s' must have a valid email address" % self.username)
)
if self.username != row[7].strip():
raise AdminError(
raise BadRequest(
_("username and email fields must not differ for '%s'" % self.username)
)
+10 -17
View File
@@ -6,7 +6,7 @@ from django.contrib.auth.decorators import (
)
from modoboa.lib import parameters
from modoboa.lib.webutils import (
ajax_simple_response, _render_to_string
_render_to_string, render_to_json_response
)
from modoboa.lib.listing import get_sort_order, get_listing_page
from modoboa.core.models import Extension, Log
@@ -24,7 +24,7 @@ def viewsettings(request, tplname='core/settings_header.html'):
@login_required
@user_passes_test(lambda u: u.is_superuser)
def viewparameters(request, tplname='core/parameters.html'):
return ajax_simple_response({
return render_to_json_response({
"status": "ok",
"left_selection": "parameters",
"content": _render_to_string(request, tplname, {
@@ -42,12 +42,10 @@ def saveparameters(request):
form.save()
form.to_django_settings()
continue
return ajax_simple_response({
"status": "ko", "prefix": form.app, "errors": form.errors
})
return ajax_simple_response(dict(
status="ok", respmsg=_("Parameters saved")
))
return render_to_json_response(
{'form_errors': form.errors, 'prefix': form.app}, status=400
)
return render_to_json_response(_("Parameters saved"))
@login_required
@@ -68,8 +66,7 @@ def viewextensions(request, tplname='core/extensions.html'):
ext["selection"] = False
tbl = ExtensionsTable(request, exts)
return ajax_simple_response({
"status": "ok",
return render_to_json_response({
"content": _render_to_string(request, tplname, {"extensions": tbl})
})
@@ -91,16 +88,13 @@ def saveextensions(request):
if not ext in found:
ext.off()
return ajax_simple_response(dict(
status="ok", respmsg=_("Modifications applied.")
))
return render_to_json_response(_("Modifications applied."))
@login_required
@user_passes_test(lambda u: u.is_superuser)
def information(request, tplname="core/information.html"):
return ajax_simple_response({
"status": "ok",
return render_to_json_response({
"content": render_to_string(tplname, {})
})
@@ -118,8 +112,7 @@ def logs(request, tplname="core/logs.html"):
Log.objects.all().order_by("%s%s" % (sort_dir, sort_order)),
request.GET.get("page", 1)
)
return ajax_simple_response({
"status": "ok",
return render_to_json_response({
"content": render_to_string(tplname, {
"logs": page.object_list,
}),
+9 -18
View File
@@ -3,7 +3,7 @@ from django.utils.translation import ugettext as _
from django.contrib.auth.decorators import login_required
from modoboa.lib import events, parameters
from modoboa.lib.webutils import (
ajax_simple_response, _render_to_string
_render_to_string, render_to_json_response
)
from modoboa.lib.cryptutils import encrypt
from modoboa.core.forms import ProfileForm
@@ -32,17 +32,11 @@ def profile(request, tplname='core/user_profile.html'):
form.save()
if update_password and form.cleaned_data["confirmation"] != "":
request.session["password"] = encrypt(form.cleaned_data["confirmation"])
return ajax_simple_response(dict(
status="ok", respmsg=_("Profile updated")
))
return ajax_simple_response({
"status": "ko",
"errors": form.errors
})
return render_to_json_response(_("Profile updated"))
return render_to_json_response({'form_errors': form.errors}, status=400)
form = ProfileForm(update_password, instance=request.user)
return ajax_simple_response({
"status": "ok",
return render_to_json_response({
"content": _render_to_string(request, tplname, {
"form": form
})
@@ -57,16 +51,13 @@ def preferences(request):
if form.is_valid():
form.save()
continue
return ajax_simple_response({
"status": "ko", "prefix": form.app, "errors": form.errors
})
return render_to_json_response({
"prefix": form.app, "form_errors": form.errors
}, status=400)
return ajax_simple_response({
"status": "ok", "respmsg": _("Preferences saved")
})
return render_to_json_response(_("Preferences saved"))
return ajax_simple_response({
"status": "ok",
return render_to_json_response({
"content": _render_to_string(request, "core/user_preferences.html", {
"forms": parameters.get_user_forms(request.user)
})