diff --git a/doc/getting_started/upgrade.rst b/doc/getting_started/upgrade.rst index 8e3d34d8c..fde360a62 100644 --- a/doc/getting_started/upgrade.rst +++ b/doc/getting_started/upgrade.rst @@ -48,13 +48,16 @@ Finally, follow the common procedure:: $ python manage.py syncdb --migrate $ python manage.py collectstatic -1.1.2: Audit trail issue -======================== +1.1.2: Audit trail issues +========================= -A new middleware is necessary to retrieve the current user. To - activate it, add - ``'modoboa.lib.middleware.RequestCatcherMiddleware'`` at the end of - the ``MIDDLEWARE_CLASSES`` variable in the :file:`settings.py` file. +Update the :file:`settings.py` file as follows: + +#. Remove the ``'reversion.middleware.RevisionMiddleware'`` + middleware from the ``MIDDLEWARE_CLASSES`` variable + +#. Add the new ``'modoboa.lib.middleware.RequestCatcherMiddleware'`` + middleware at the end of the ``MIDDLEWARE_CLASSES`` variable 1.1.1: Few bugfixes =================== diff --git a/modoboa/core/commands/templates/settings.py.tpl b/modoboa/core/commands/templates/settings.py.tpl index f2fc8fe8f..c0df35122 100644 --- a/modoboa/core/commands/templates/settings.py.tpl +++ b/modoboa/core/commands/templates/settings.py.tpl @@ -113,7 +113,6 @@ MIDDLEWARE_CLASSES = ( 'django.middleware.locale.LocaleMiddleware', # Uncomment the next line for simple clickjacking protection: # 'django.middleware.clickjacking.XFrameOptionsMiddleware', - 'reversion.middleware.RevisionMiddleware', 'modoboa.lib.middleware.AjaxLoginRedirect', 'modoboa.lib.middleware.CommonExceptionCatcher', diff --git a/modoboa/core/models.py b/modoboa/core/models.py index 20b49ea01..56bdcbe35 100644 --- a/modoboa/core/models.py +++ b/modoboa/core/models.py @@ -472,10 +472,20 @@ class Log(models.Model): @receiver(reversion.post_revision_commit) def post_revision_commit(sender, **kwargs): - if kwargs["revision"].user is None: - return + """Custom post-revision hook. + + We want to track all creations and modifications of admin. objects + (alias, mailbox, user, domain, domain alias, etc.) so we use + django-reversion for that. + + """ + from modoboa.lib.signals import get_request + + current_user = get_request().user.username logger = logging.getLogger("modoboa.admin") for version in kwargs["versions"]: + if version.object is None: + continue prev_revisions = reversion.get_for_object(version.object) if prev_revisions.count() == 1: action = _("added") @@ -486,7 +496,7 @@ def post_revision_commit(sender, **kwargs): 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 + "user": current_user } getattr(logger, level)(message) diff --git a/modoboa/extensions/admin/__init__.py b/modoboa/extensions/admin/__init__.py index 38ca5504c..a0f29e83b 100644 --- a/modoboa/extensions/admin/__init__.py +++ b/modoboa/extensions/admin/__init__.py @@ -3,7 +3,7 @@ from django.utils.translation import ugettext as _, ugettext_lazy from django.core.urlresolvers import reverse from modoboa.core.extensions import ModoExtension, exts_pool from modoboa.lib import parameters, events -from modoboa.lib.exceptions import PermDeniedException, BadRequest +from modoboa.lib.exceptions import PermDeniedException, BadRequest, Conflict from modoboa.lib.emailutils import split_mailbox from modoboa.extensions.admin.models import ( Domain, DomainAlias, Mailbox, Alias @@ -164,6 +164,12 @@ def import_account_mailbox(user, account, row): ) if not user.can_access(domain): raise PermDeniedException + try: + mb = Mailbox.objects.get(address=mailbox, domain=domain) + except Mailbox.DoesNotExist: + pass + else: + raise Conflict(_("Mailbox %s already exists" % account.email)) quota = int(row[1].strip()) use_domain_quota = True if not quota else False mb = Mailbox(address=mailbox, domain=domain, diff --git a/modoboa/extensions/admin/views/alias.py b/modoboa/extensions/admin/views/alias.py index c8410615f..dc4e8a04e 100644 --- a/modoboa/extensions/admin/views/alias.py +++ b/modoboa/extensions/admin/views/alias.py @@ -1,3 +1,4 @@ +import reversion from django.db import transaction, IntegrityError from django.utils.translation import ugettext as _, ungettext from django.shortcuts import render @@ -56,6 +57,7 @@ def _new_alias(request, title, action, successmsg, @login_required @permission_required("admin.add_alias") @transaction.commit_on_success +@reversion.create_revision() def newdlist(request): return _new_alias( request, _("New distribution list"), reverse(newdlist), @@ -66,6 +68,7 @@ def newdlist(request): @login_required @permission_required("admin.add_alias") @transaction.commit_on_success +@reversion.create_revision() def newalias(request): return _new_alias( request, _("New alias"), reverse(newalias), @@ -76,6 +79,7 @@ def newalias(request): @login_required @permission_required("admin.add_alias") @transaction.commit_on_success +@reversion.create_revision() def newforward(request): return _new_alias( request, _("New forward"), reverse(newforward), @@ -86,6 +90,7 @@ def newforward(request): @login_required @permission_required("admin.change_alias") @transaction.commit_on_success +@reversion.create_revision() def editalias(request, alid, tplname="admin/aliasform.html"): alias = Alias.objects.get(pk=alid) if not request.user.can_access(alias): diff --git a/modoboa/extensions/admin/views/domain.py b/modoboa/extensions/admin/views/domain.py index 63f928083..cb94bc3a5 100644 --- a/modoboa/extensions/admin/views/domain.py +++ b/modoboa/extensions/admin/views/domain.py @@ -1,3 +1,4 @@ +import reversion from django.http import HttpResponseRedirect from django.utils.translation import ugettext as _, ungettext from django.core.urlresolvers import reverse @@ -16,7 +17,6 @@ from modoboa.lib.exceptions import ( ModoboaException, PermDeniedException, BadRequest ) from modoboa.lib.templatetags.lib_tags import pagination_bar -from modoboa.core.models import log_object_removal from modoboa.extensions.admin.lib import get_sort_order, get_listing_page from modoboa.extensions.admin.models import Domain, Mailbox from modoboa.extensions.admin.forms import ( @@ -89,6 +89,7 @@ def domains_list(request): @login_required @permission_required("admin.add_domain") @transaction.commit_on_success +@reversion.create_revision() def newdomain(request, tplname="common/wizard_forms.html"): events.raiseEvent("CanCreate", request.user, "domains") @@ -140,6 +141,7 @@ def newdomain(request, tplname="common/wizard_forms.html"): @login_required @permission_required("admin.view_domains") @transaction.commit_on_success +@reversion.create_revision() def editdomain(request, dom_id, tplname="admin/editdomainform.html"): domain = Domain.objects.get(pk=dom_id) if not request.user.can_access(domain): diff --git a/modoboa/extensions/admin/views/identity.py b/modoboa/extensions/admin/views/identity.py index 769de9c0f..a5af940ce 100644 --- a/modoboa/extensions/admin/views/identity.py +++ b/modoboa/extensions/admin/views/identity.py @@ -1,3 +1,4 @@ +import reversion from django.shortcuts import render from django.db import transaction from django.utils.translation import ugettext as _, ungettext @@ -114,6 +115,7 @@ def list_quotas(request, tplname="admin/quotas.html"): @login_required @permission_required("core.add_user") @transaction.commit_on_success +@reversion.create_revision() def newaccount(request, tplname='common/wizard_forms.html'): """Create a new account. @@ -166,6 +168,7 @@ def newaccount(request, tplname='common/wizard_forms.html'): @login_required @permission_required("core.change_user") @transaction.commit_on_success +@reversion.create_revision() def editaccount(request, accountid, tplname="common/tabforms.html"): account = User.objects.get(pk=accountid) if not request.user.can_access(account): diff --git a/modoboa/extensions/admin/views/import.py b/modoboa/extensions/admin/views/import.py index be306e048..2251d23c1 100644 --- a/modoboa/extensions/admin/views/import.py +++ b/modoboa/extensions/admin/views/import.py @@ -1,8 +1,9 @@ import csv +import reversion from django.utils.translation import ugettext as _ from django.shortcuts import render from django.core.urlresolvers import reverse -from django.db import transaction, IntegrityError +from django.db import transaction from django.contrib.auth.decorators import ( login_required, permission_required, user_passes_test ) @@ -86,6 +87,7 @@ def import_dlist(user, row, formopts): _import_alias(user, row) +@reversion.create_revision() def importdata(request, formclass=ImportDataForm): """Generic import function diff --git a/modoboa/extensions/admin/views/user.py b/modoboa/extensions/admin/views/user.py index f836968b1..15e0a9b6c 100644 --- a/modoboa/extensions/admin/views/user.py +++ b/modoboa/extensions/admin/views/user.py @@ -1,6 +1,6 @@ +import reversion from django.contrib.auth.decorators import login_required from django.utils.translation import ugettext as _ -from modoboa.lib.exceptions import ModoboaException from modoboa.lib.webutils import ( render_to_json_response, _render_to_string ) @@ -11,6 +11,7 @@ from modoboa.extensions.admin.forms import ForwardForm @login_required @needs_mailbox() +@reversion.create_revision() def forward(request, tplname='admin/forward.html'): mb = request.user.mailbox_set.all()[0] try: diff --git a/modoboa/extensions/postfix_relay_domains/views.py b/modoboa/extensions/postfix_relay_domains/views.py index e6df53621..a1af875f6 100644 --- a/modoboa/extensions/postfix_relay_domains/views.py +++ b/modoboa/extensions/postfix_relay_domains/views.py @@ -1,3 +1,4 @@ +import reversion from django.shortcuts import render from django.db import transaction from django.core.urlresolvers import reverse @@ -16,6 +17,7 @@ from .forms import RelayDomainForm, RelayDomainFormGeneral @login_required @permission_required("postfix_relay_domains.add_relaydomain") @transaction.commit_on_success +@reversion.create_revision() def create(request, tplname="postfix_relay_domains/new_relaydomain_form.html"): events.raiseEvent("CanCreate", request.user, "relay_domains") if request.method == 'POST': @@ -39,6 +41,7 @@ def create(request, tplname="postfix_relay_domains/new_relaydomain_form.html"): @login_required @permission_required("postfix_relay_domains.change_relaydomain") +@reversion.create_revision() def edit(request, rdom_id, tplname='common/tabforms.html'): rdom = RelayDomain.objects.get(pk=rdom_id) if not request.user.can_access(rdom): diff --git a/tests/install_from_scratch.py b/tests/install_from_scratch.py index 17f497ff7..3ced6cbab 100644 --- a/tests/install_from_scratch.py +++ b/tests/install_from_scratch.py @@ -21,7 +21,6 @@ class DeployTest(unittest.TestCase): def tearDown(self): path = os.path.join(self.workdir, self.projname) code, output = exec_cmd("python manage.py test core lib admin limits postfix_relay_domains", cwd=path) - print output self.assertEqual(code, 0) def test_standard(self):