Compatibility with reversion >= 1.8.

fixes #497
This commit is contained in:
Antoine Nguyen
2013-11-12 21:48:48 +01:00
parent 1c6d993550
commit 4e72d70917
16 changed files with 114 additions and 63 deletions
@@ -106,6 +106,7 @@ TEMPLATE_LOADERS = (
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.transaction.TransactionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
@@ -154,8 +155,8 @@ MODOBOA_APPS = (
'modoboa.lib',
# Modoboa extensions here.
'modoboa.extensions.admin',
'modoboa.extensions.limits',
'modoboa.extensions.postfix_relay_domains',
'modoboa.extensions.limits',
'modoboa.extensions.postfix_autoreply',
'modoboa.extensions.webmail',
'modoboa.extensions.stats',
+5 -3
View File
@@ -76,11 +76,13 @@ class ExtensionsPool(object):
"""
from modoboa.core.models import Extension
result = []
for ext in settings.MODOBOA_APPS:
__import__(ext)
result = []
for extname in self.extensions.keys():
extname = ext.split('.')[-1]
extinstance = self.get_extension(extname)
if extinstance is None:
continue
try:
baseurl = extinstance.url \
if extinstance.url is not None else extname
@@ -106,7 +108,7 @@ class ExtensionsPool(object):
for extname, extdef in self.extensions.iteritems():
if not extdef["show"]:
continue
infos = extdef["instance"].infos()
infos = self.get_extension_infos(extname)
infos["id"] = extname
result += [infos]
return sorted(result, key=lambda i: i["name"])
+29 -7
View File
@@ -4,9 +4,11 @@ import re
import hashlib
import crypt
import base64
import logging
from random import Random
import reversion
from django.db import models
from django.db.models.signals import post_delete
from django.dispatch import receiver
from django.utils import timezone
from django.utils.translation import ugettext as _, ugettext_lazy
@@ -463,24 +465,44 @@ class Log(models.Model):
@receiver(reversion.post_revision_commit)
def post_revision_commit(sender, **kwargs):
import logging
if kwargs["revision"].user is None:
return
logger = logging.getLogger("modoboa.admin")
for version in kwargs["versions"]:
if version.type == reversion.models.VERSION_ADD:
prev_revisions = reversion.get_for_object(version.object)
if prev_revisions.count() == 1:
action = _("added")
level = "info"
elif version.type == reversion.models.VERSION_CHANGE:
else:
action = _("modified")
level = "warning"
else:
action = _("deleted")
level = "critical"
message = _("%(object)s '%(name)s' %(action)s by user %(user)s") % {
"object": unicode(version.content_type).capitalize(),
"name": version.object_repr, "action": action,
"user": kwargs["revision"].user.username
}
getattr(logger, level)(message)
@receiver(post_delete)
def post_delete_hook(sender, instance, **kwargs):
"""Custom post-delete hook.
We want to know who was responsible for an object deletion.
"""
from reversion.models import Version
if not reversion.is_registered(sender):
return
del_list = reversion.get_deleted(sender)
try:
version = del_list.get(object_id=instance.id)
except Version.DoesNotExist:
return
logger = logging.getLogger("modoboa.admin")
msg = _("%(object)s '%(name)s' %(action)s by user %(user)s") % {
"object": unicode(version.content_type).capitalize(),
"name": version.object_repr, "action": _("deleted"),
"user": version.revision.user.username
}
logger.critical(msg)
+1 -1
View File
@@ -45,7 +45,7 @@ def settings_menu(selection, user):
"label": _("Information")},
{"name": "logs",
"class": "ajaxlink",
"url": "logs/",
"url": "logs/&sort_order=-date_created",
"label": _("Logs")},
{"name": "parameters",
"class": "ajaxlink",
+4 -3
View File
@@ -107,7 +107,7 @@ class DomainFormGeneral(forms.ModelForm, DynamicForm):
username = q['username'].replace('@%s' % self.oldname, '@%s' % domain.name)
Quota.objects.filter(username=q['username']).update(username=username)
def save(self, user, commit=True):
def save(self, user, commit=True, domalias_post_create=False):
"""Custom save method
Updating a domain may have consequences on other objects
@@ -148,7 +148,7 @@ class DomainFormGeneral(forms.ModelForm, DynamicForm):
else:
continue
al = DomainAlias(name=alias, target=d, enabled=d.enabled)
al.save(creator=user)
al.save(creator=user) if domalias_post_create else al.save()
if old_mail_homes is not None:
self.update_mailbox_quotas(d)
@@ -253,5 +253,6 @@ class DomainForm(TabForms):
As forms interact with each other, it is easier to make custom
code to save them.
"""
for f in self.forms:
self.forms[0]['instance'].save(user, domalias_post_create=True)
for f in self.forms[1:]:
f["instance"].save(user)
@@ -148,4 +148,13 @@ class Domain(AdminObject):
for dalias in self.domainalias_set.all():
dalias.to_csv(csvwriter)
def post_create(self, creator):
"""Post creation actions.
:param ``User`` creator: user whos created this domain
"""
super(Domain, self).post_create(creator)
for domalias in self.domainalias_set.all():
domalias.post_create(creator)
reversion.register(Domain)
@@ -392,7 +392,7 @@ Identities.prototype = {
$("#wizard").cwizard({
formid: "newaccount_form",
transition_callbacks: {
2: this.mailform_prefill
1: this.mailform_prefill
},
success_callback: $.proxy(this.reload_listing, this)
});
+11 -10
View File
@@ -115,6 +115,14 @@ def list_quotas(request, tplname="admin/quotas.html"):
@permission_required("core.add_user")
@transaction.commit_on_success
def newaccount(request, tplname='common/wizard_forms.html'):
"""Create a new account.
.. note:: An issue still remains int this code: if all validation
steps are successful but an error occurs after we call 'save',
the account will be created. It happens transaction management
doesn't work very well with nested functions. Need to wait for
django 1.6 and atomicity.
"""
cwizard = CreationWizard()
cwizard.add_step(AccountFormGeneral, _("General"),
[dict(classes="btn-inverse next", label=_("Next"))],
@@ -135,16 +143,9 @@ def newaccount(request, tplname='common/wizard_forms.html'):
if retcode == 2:
genform = cwizard.steps[0]["form"]
account = genform.save()
try:
account.post_create(request.user)
mailform = cwizard.steps[1]["form"]
mailform.save(request.user, account)
except ModoboaException:
# A bit uggly: transaction management doesn't work very
# well with nested functions. Need to wait for django 1.6
# and atomicity.
account.delete(request.user, False)
raise
account.post_create(request.user)
mailform = cwizard.steps[1]["form"]
mailform.save(request.user, account)
return render_to_json_response(_("Account created"))
return render_to_json_response({
'stepid': data, 'form_errors': cwizard.errors
@@ -1,8 +1,8 @@
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext as _
from django.template import Template, Context
from modoboa.lib import events, parameters
from modoboa.extensions.admin.models import DomainAlias
from modoboa.extensions.amavis.lib import (
create_user_and_policy, update_user_and_policy, delete_user_and_policy,
create_user_and_use_policy, delete_user
@@ -36,13 +36,16 @@ def on_domain_deleted(domain):
@events.observe("DomainAliasCreated")
def on_relay_domain_alias_created(user, domainalias):
def on_domain_alias_created(user, domainalias):
create_user_and_use_policy(domainalias.name, domainalias.target.name)
@events.observe("DomainAliasDeleted")
def on_relay_domain_alias_deleted(domainalias):
delete_user(domainalias.name)
def on_domain_alias_deleted(domainaliases):
if isinstance(domainaliases, DomainAlias):
domainaliases = [domainaliases]
for domainalias in domainaliases:
delete_user(domainalias.name)
@events.observe("GetStaticContent")
@@ -82,7 +82,7 @@ class RelayDomainFormGeneral(forms.ModelForm, DynamicForm):
return cleaned_data
def save(self, user, commit=True):
def save(self, user, commit=True, rdomalias_post_create=False):
"""Custom save method.
As relay domain aliases are defined using the same form as
@@ -119,7 +119,8 @@ class RelayDomainFormGeneral(forms.ModelForm, DynamicForm):
al = RelayDomainAlias(
name=alias, target=rd, enabled=rd.enabled
)
al.save(creator=user)
al.save(creator=user) \
if rdomalias_post_create else al.save()
return rd
@@ -151,5 +152,6 @@ class RelayDomainForm(TabForms):
As forms interact with each other, it is easier to make custom
code to save them.
"""
for f in self.forms:
self.forms[0]['instance'].save(user, rdomalias_post_create=True)
for f in self.forms[1:]:
f["instance"].save(user)
@@ -106,32 +106,6 @@ def extra_limit_templates():
]
@events.observe('GetExtraParameters')
def extra_parameters(app, level):
from django import forms
if app != 'limits' or level != 'A':
return {}
return {
'deflt_relay_domains_limit': forms.IntegerField(
label=ugettext_lazy("Relay domains"),
initial=0,
help_text=ugettext_lazy(
"Maximum number of allowed relay domains for a new administrator"
),
widget=forms.widgets.TextInput(attrs={"class": "span1"})
),
'deflt_relay_domain_aliases_limit': forms.IntegerField(
label=ugettext_lazy("Relay domain aliases"),
initial=0,
help_text=ugettext_lazy(
"Maximum number of allowed relay domain aliases for a new administrator"
),
widget=forms.widgets.TextInput(attrs={"class": "span1"})
)
}
@events.observe('ExtraDomainImportHelp')
def extra_domain_import_help():
return [ugettext_lazy("""
@@ -1,9 +1,36 @@
from django.utils.translation import ugettext_lazy
from modoboa.lib import events
from modoboa.lib.permissions import get_object_owner
from modoboa.extensions.limits.lib import inc_limit_usage, dec_limit_usage
from .models import RelayDomainAlias
@events.observe('GetExtraParameters')
def extra_parameters(app, level):
from django import forms
if app != 'limits' or level != 'A':
return {}
return {
'deflt_relay_domains_limit': forms.IntegerField(
label=ugettext_lazy("Relay domains"),
initial=0,
help_text=ugettext_lazy(
"Maximum number of allowed relay domains for a new administrator"
),
widget=forms.widgets.TextInput(attrs={"class": "span1"})
),
'deflt_relay_domain_aliases_limit': forms.IntegerField(
label=ugettext_lazy("Relay domain aliases"),
initial=0,
help_text=ugettext_lazy(
"Maximum number of allowed relay domain aliases for a new administrator"
),
widget=forms.widgets.TextInput(attrs={"class": "span1"})
)
}
@events.observe('RelayDomainCreated')
def inc_relaydomains_count(user, rdomain):
inc_limit_usage(user, 'relay_domains_limit')
@@ -139,6 +139,15 @@ class RelayDomain(AdminObject):
self.verify_recipients = (row[5].strip() == 'True')
self.save(creator=user)
def post_create(self, creator):
"""Post creation actions.
:param ``User`` creator: user whos created this relay domain
"""
super(RelayDomain, self).post_create(creator)
for rdomalias in self.relaydomainalias_set.all():
rdomalias.post_create(creator)
reversion.register(RelayDomain)
@@ -23,9 +23,7 @@ def create(request, tplname="postfix_relay_domains/new_relaydomain_form.html"):
if form.is_valid():
rdom = form.save(request.user)
rdom.post_create(request.user)
return render_to_json_response(
{"respmsg": _("Relay domain created")}
)
return render_to_json_response(_("Relay domain created"))
return render_to_json_response(
{'form_errors': form.errors}, status=400
)
+2
View File
@@ -17,6 +17,8 @@ _params = {'A': {}, 'U': {}}
class NotDefined(ModoboaException):
http_code = 404
def __init__(self, app, name):
self.app = app
self.name = name
+1 -1
View File
@@ -1,5 +1,5 @@
django
django-reversion==1.7.1
django-reversion>=1.8.0
dj-database-url
south
lxml