see #951
This commit is contained in:
Antoine Nguyen
2016-10-28 15:48:08 +02:00
parent 9367dcd09f
commit 08943f15ec
7 changed files with 97 additions and 44 deletions
@@ -0,0 +1,67 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.5 on 2016-10-26 08:11
from __future__ import unicode_literals
from django.db import migrations
import jsonfield.fields
def set_parameter(store, parameter):
"""Add parameter to the specified store."""
app, name = parameter.name.split(".")
if app not in store:
store[app] = {}
# decode value
value = parameter.value.decode("unicode_escape")
if value == "yes":
value = True
elif value == "no":
value = False
elif value.isdigit():
value = int(value)
store[app][name.lower()] = value
def move_parameters(apps, schema_editor):
"""Move global and user parameters."""
Parameter = apps.get_model("lib", "Parameter")
LocalConfig = apps.get_model("core", "LocalConfig")
parameters = {}
for parameter in Parameter.objects.all():
set_parameter(parameters, parameter)
LocalConfig.objects.all().update(_parameters=parameters)
User = apps.get_model("core", "User")
for user in User.objects.prefetch_related("userparameter_set"):
for parameter in user.userparameter_set.all():
set_parameter(user._parameters, parameter)
user.save()
def clear_parameters(apps, schema_editor):
"""Reverse operation."""
pass
class Migration(migrations.Migration):
dependencies = [
('core', '0009_auto_20161026_1003'),
('lib', '0005_auto_20160416_1449'),
]
operations = [
migrations.AddField(
model_name='localconfig',
name='_parameters',
field=jsonfield.fields.JSONField(default={}),
preserve_default=False,
),
migrations.AddField(
model_name='user',
name='_parameters',
field=jsonfield.fields.JSONField(default={}),
preserve_default=False,
),
migrations.RunPython(move_parameters, clear_parameters)
]
+7 -1
View File
@@ -84,6 +84,7 @@ class User(PermissionsMixin):
help_text=ugettext_lazy(
"An alternative e-mail address, can be used for recovery needs.")
)
_parameters = jsonfield.JSONField(default={})
objects = UserManager()
@@ -98,6 +99,11 @@ class User(PermissionsMixin):
password_expr = re.compile(r'\{([\w\-]+)\}(.+)')
def __init__(self, *args, **kwargs):
"""Load parameter manager."""
super(User, self).__init__(*args, **kwargs)
self.parameters = parameters.Manager("user", self._parameters)
def delete(self, fromuser, *args, **kwargs):
"""Custom delete method
@@ -509,7 +515,7 @@ class LocalConfig(models.Model):
# API results cache
api_versions = jsonfield.JSONField()
_parameters = jsonfield.JSONField()
_parameters = jsonfield.JSONField(default={})
def __init__(self, *args, **kwargs):
"""Load parameter manager."""
+3 -1
View File
@@ -49,7 +49,7 @@ class Registry(object):
def get_forms(self, level, *args, **kwargs):
"""Return form instances for all app of the given level."""
sorted_apps = []
first_app = "core"
first_app = kwargs.pop("first_app", "core")
if first_app in self._registry[level]:
sorted_apps.append(first_app)
sorted_apps += sorted(
@@ -59,6 +59,8 @@ class Registry(object):
result = []
for app in sorted_apps:
data = self._registry[level][app]
if not data["formclass"].has_access(**kwargs):
continue
result.append({
"label": data["label"],
"form": data["formclass"](*args, **kwargs)
+8 -8
View File
@@ -9,7 +9,6 @@ from django.core.urlresolvers import reverse
from django.test import override_settings, TestCase
from modoboa.lib import exceptions
from modoboa.lib import parameters
from modoboa.lib.tests import ModoTestCase
from modoboa.lib.tests import NO_LDAP
@@ -152,7 +151,6 @@ class LDAPTestCaseMixin(object):
'modoboa.lib.authbackends.SimpleBackend',
))
class LDAPAuthenticationTestCase(LDAPTestCaseMixin, ModoTestCase):
"""Validate LDAP authentication scenarios."""
def setUp(self):
@@ -178,9 +176,10 @@ class LDAPAuthenticationTestCase(LDAPTestCaseMixin, ModoTestCase):
self.check_created_user(username)
self.client.logout()
parameters.save_admin("LDAP_ADMIN_GROUPS", "admins")
parameters.save_admin(
"LDAP_GROUPS_SEARCH_BASE", "ou=groups,dc=example,dc=com")
self.set_global_parameters({
"ldap_admin_groups": "admins",
"ldap_groups_search_base": "ou=groups,dc=example,dc=com"
})
username = "mailadmin@example.com"
self.authenticate(username, "test", False)
self.check_created_user(username, "DomainAdmins")
@@ -198,9 +197,10 @@ class LDAPAuthenticationTestCase(LDAPTestCaseMixin, ModoTestCase):
# 1: must work because usernames of domain admins are not
# always email addresses
parameters.save_admin("LDAP_ADMIN_GROUPS", "admins")
parameters.save_admin(
"LDAP_GROUPS_SEARCH_BASE", "ou=groups,dc=example,dc=com")
self.set_global_parameters({
"ldap_admin_groups": "admins",
"ldap_groups_search_base": "ou=groups,dc=example,dc=com"
})
username = "mailadmin"
self.authenticate(username, "test", False)
self.check_created_user(username, "DomainAdmins", False)
+1 -1
View File
@@ -11,7 +11,7 @@ from django.utils.translation import ugettext as _
from modoboa.core.models import Log
from modoboa.core import parameters as core_parameters
from modoboa.core.utils import check_for_updates
from modoboa.lib import events, parameters
from modoboa.lib import events
from modoboa.lib.listing import get_sort_order, get_listing_page
from modoboa.lib.web_utils import (
_render_to_string, render_to_json_response
+4 -1
View File
@@ -8,6 +8,7 @@ from django.contrib.auth.decorators import login_required, user_passes_test
from rest_framework.authtoken.models import Token
from modoboa.core import parameters as core_parameters
from modoboa.lib import events, parameters
from modoboa.lib.cryptutils import encrypt
from modoboa.lib.web_utils import (
@@ -59,7 +60,9 @@ def profile(request, tplname='core/user_profile.html'):
@login_required
def preferences(request):
if request.method == "POST":
for formdef in parameters.get_user_forms(request.user, request.POST):
forms = core_parameters.registry.get_forms(
"user", request.POST, user=request.user)
for formdef in forms:
form = formdef["form"]
if form.is_valid():
form.save()
+7 -32
View File
@@ -76,6 +76,10 @@ class GenericParametersForm(forms.Form):
p.value = str(value)
p.save()
@staticmethod
def has_access(**kwargs):
return True
def save(self):
raise NotImplementedError
@@ -142,10 +146,6 @@ class UserParametersForm(GenericParametersForm):
for p in UserParameter.objects.filter(user=self.user, name__in=names):
self.fields[p.shortname].initial = self._decode_value(p.value)
@staticmethod
def has_access(user):
return True
def save(self):
from .models import UserParameter
from modoboa.lib.form_utils import SeparatorField
@@ -290,23 +290,6 @@ def get_user(user, name, app=None, raise_error=True):
return p.value.decode("unicode_escape")
def get_sorted_apps(level, first="core"):
"""Retrieve the sorted list of all registerd applications.
:param str level: application level
:param str first: force the first item of the result
:rtype: list
"""
sorted_apps = []
if first in _params[level]:
sorted_apps.append(first)
sorted_apps += sorted(
[app for app in _params[level].keys() if app != first],
key=lambda app: _params[level][app]["label"]
)
return sorted_apps
def get_admin_forms(*args, **kwargs):
"""Get all admin level forms.
@@ -318,17 +301,9 @@ def get_admin_forms(*args, **kwargs):
def get_user_forms(user, *args, **kwargs):
"""Return an instance of each user-level forms."""
kwargs["user"] = user
sorted_apps = get_sorted_apps('U', first="general")
result = []
for app in sorted_apps:
formdef = _params["U"][app]
if not formdef["form"].has_access(user):
continue
result.append({
"label": formdef["label"],
"form": formdef["form"](*args, **kwargs)})
return result
kwargs.update({"user": user, "first_app": "general"})
return core_parameters.registry.get_forms(
"user", *args, **kwargs)
def get_parameter_form(level, name, app=None):