From af95f2b465028b409daf582e601de3123aefd4cd Mon Sep 17 00:00:00 2001 From: Antoine Nguyen Date: Wed, 6 Feb 2013 16:47:12 +0100 Subject: [PATCH] Added support for modification callbacks. fix #264 --- modoboa/admin/__init__.py | 78 ++++++++++++++++++++++++++++----------- modoboa/admin/models.py | 45 +++++++++++++--------- modoboa/lib/parameters.py | 17 +++++++++ 3 files changed, 100 insertions(+), 40 deletions(-) diff --git a/modoboa/admin/__init__.py b/modoboa/admin/__init__.py index 37e376411..6b5cd585a 100644 --- a/modoboa/admin/__init__.py +++ b/modoboa/admin/__init__.py @@ -1,28 +1,60 @@ -# -*- coding: utf-8 -*- +# coding: utf-8 from modoboa.lib import parameters, events from django.utils.translation import ugettext as _, ugettext_lazy from django.db.utils import DatabaseError -from models import Extension +from models import Extension, Mailbox -parameters.register_admin("AUTHENTICATION_TYPE", type="list", deflt="local", - values=[('local', ugettext_lazy("Local")), - ('ldap', "LDAP")], - help=ugettext_lazy("The backend used for authentication")) -parameters.register_admin("CREATE_DIRECTORIES", type="list_yesno", deflt="yes", - help=ugettext_lazy("Modoboa will handle mailbox creation on filesystem")) -parameters.register_admin("STORAGE_PATH", type="string", deflt="/var/vmail", - help=ugettext_lazy("Path to the root directory where messages are stored")) -parameters.register_admin("VIRTUAL_UID", type="string", deflt="vmail", - help=ugettext_lazy("UID of the virtual user which owns domains/mailboxes/messages on the filesystem")) -parameters.register_admin("VIRTUAL_GID", type="string", deflt="vmail", - help=ugettext_lazy("GID of the virtual user which owns domains/mailboxes/messages on the filesystem")) -parameters.register_admin("MAILBOX_TYPE", type="list", deflt="maildir", - values=[("maildir", "maildir"), ("mbox", "mbox")], - help=ugettext_lazy("Mailboxes storage format")) -parameters.register_admin("MAILDIR_ROOT", type="string", deflt=".maildir", - visible_if="MAILBOX_TYPE=maildir", - help=ugettext_lazy("Sub-directory (inside the mailbox) where messages are stored when using the maildir format")) +def update_uid(value): + """VIRTUAL_UID modification callback + + Update all mailboxes with the new UID value + + :param value: the new UID + """ + Mailbox.objects.all().update(uid=Mailbox.resolve_uid(value)) + +def update_gid(value): + """VIRTUAL_GID modification callback + + Update all mailboxes with the new GID value + + :param value: the new GID + """ + Mailbox.objects.all().update(gid=Mailbox.resolve_gid(value)) + +parameters.register_admin( + "AUTHENTICATION_TYPE", type="list", deflt="local", + values=[('local', ugettext_lazy("Local")), + ('ldap', "LDAP")], + help=ugettext_lazy("The backend used for authentication") +) +parameters.register_admin( + "CREATE_DIRECTORIES", type="list_yesno", deflt="yes", + help=ugettext_lazy("Modoboa will handle mailbox creation on filesystem") + ) +parameters.register_admin( + "STORAGE_PATH", type="string", deflt="/var/vmail", + help=ugettext_lazy("Path to the root directory where messages are stored") +) +parameters.register_admin( + "VIRTUAL_UID", type="string", deflt="vmail", modify_cb=update_uid, + help=ugettext_lazy("UID of the virtual user which owns domains/mailboxes/messages on the filesystem") + ) +parameters.register_admin( + "VIRTUAL_GID", type="string", deflt="vmail", modify_cb=update_gid, + help=ugettext_lazy("GID of the virtual user which owns domains/mailboxes/messages on the filesystem") + ) +parameters.register_admin( + "MAILBOX_TYPE", type="list", deflt="maildir", + values=[("maildir", "maildir"), ("mbox", "mbox")], + help=ugettext_lazy("Mailboxes storage format") +) +parameters.register_admin( + "MAILDIR_ROOT", type="string", deflt=".maildir", + visible_if="MAILBOX_TYPE=maildir", + help=ugettext_lazy("Sub-directory (inside the mailbox) where messages are stored when using the maildir format") + ) parameters.register_admin( "AUTO_ACCOUNT_REMOVAL", type="list_yesno", deflt="no", help=ugettext_lazy("When a mailbox is removed, also remove the associated account") @@ -36,8 +68,10 @@ parameters.register_admin( ("plain", "plain")], help=ugettext_lazy("Scheme used to crypt mailbox passwords") ) -parameters.register_admin("ITEMS_PER_PAGE", type="int", deflt=30, - help=ugettext_lazy("Number of displayed items per page")) +parameters.register_admin( + "ITEMS_PER_PAGE", type="int", deflt=30, + help=ugettext_lazy("Number of displayed items per page") + ) def enabled_applications(): """Return the list of currently enabled extensions diff --git a/modoboa/admin/models.py b/modoboa/admin/models.py index a5bfdf0bd..857fd6606 100644 --- a/modoboa/admin/models.py +++ b/modoboa/admin/models.py @@ -755,25 +755,34 @@ class Mailbox(DatesAware): self.domain.name, self.address)) return True + @staticmethod + def resolve_uid(value): + if value.isdigit(): + return value + try: + uid = pwd.getpwnam(value).pw_uid + except KeyError: + raise AdminError(_("%s is not a valid uid/username" % value)) + return uid + + @staticmethod + def resolve_gid(value): + if value.isdigit(): + return value + try: + gid = pwd.getpwnam(value).pw_gid + except KeyError: + raise AdminError(_("%s is not a valid gid/groupname" % value)) + return gid + def set_ownership(self): - # If we ever had numerical uid, don't resolve it - v_uid = parameters.get_admin("VIRTUAL_UID"); - if v_uid.isdigit(): - self.uid = v_uid - else: - try: - self.uid = pwd.getpwnam(v_uid).pw_uid - except KeyError: - raise AdminError(_("%s is not a valid uid/username" % v_uid)) - # Just the same for gid - v_gid = parameters.get_admin("VIRTUAL_GID") - if v_gid.isdigit(): - self.gid = v_gid - else: - try: - self.gid = pwd.getpwnam(v_gid).pw_gid - except KeyError: - raise AdminError(_("%s is not a valid gid/groupname" % v_gid)) + """Set uid and gid for this mailbox + + Values come from global parameters. They are resolved + (converted to integers) if needed. + """ + self.uid = self.resolve_uid(parameters.get_admin("VIRTUAL_UID")) + self.gid = self.resolve_gid(parameters.get_admin("VIRTUAL_GID")) def set_quota(self, value, override_domain=False): if value is None or (int(value) > self.domain.quota and not override_domain): diff --git a/modoboa/lib/parameters.py b/modoboa/lib/parameters.py index 2dc3680a9..b9b0da0fc 100644 --- a/modoboa/lib/parameters.py +++ b/modoboa/lib/parameters.py @@ -165,6 +165,17 @@ def register_user(name, **kwargs): app = __guess_extension() return __register(app, 'U', name, **kwargs) +def get_param_def(app, level, name): + """Return the definition of a given parameter + + :param app: the application's name + :param level: the required level (A or U) + :param name: the parameter's name + :return: a dictionnary + """ + __is_defined(app, level, name) + return _params[app][level][name] + def save_admin(name, value, app=None): from models import Parameter @@ -178,6 +189,9 @@ def save_admin(name, value, app=None): p = Parameter() p.name = fullname if p.value != value: + pdef = get_param_def(app, 'A', name) + if "modify_cb" in pdef: + pdef["modify_cb"](value) p.value = value.encode("unicode_escape").strip() p.save() return True @@ -196,6 +210,9 @@ def save_user(user, name, value, app=None): p.user = user p.name = fullname if p.value != value: + pdef = get_param_def(app, 'U', name) + if "modify_cb" in pdef: + pdef["modify_cb"](value) p.value = value.encode("unicode_escape").strip() p.save() return True