diff --git a/admin/lib.py b/admin/lib.py index 3d02ad8cc..1ad7d6bda 100644 --- a/admin/lib.py +++ b/admin/lib.py @@ -58,8 +58,8 @@ def grant_access_to_object(user, obj, is_owner=False): :param obj: an admin. object (Domain, Mailbox, ...) :param is_owner: the user is the unique object's owner """ + ct = get_content_type(obj) try: - ct = ContentType.objects.get_for_model(obj) entry = user.objectaccess_set.get(content_type=ct, object_id=obj.id) entry.is_owner = is_owner entry.save() @@ -69,7 +69,8 @@ def grant_access_to_object(user, obj, is_owner=False): return try: - objaccess = ObjectAccess(user=user, content_object=obj, is_owner=is_owner) + objaccess = ObjectAccess(user=user, content_type=ct, + object_id=obj.id, is_owner=is_owner) objaccess.save() except IntegrityError, e: raise AdminError(_("Failed to grant access (%s)" % str(e))) @@ -83,7 +84,7 @@ def ungrant_access_to_object(obj, user=None): :param obj: an object inheriting from ``models.Model`` :param user: a ``User`` object """ - ct = ContentType.objects.get_for_model(obj) + ct = get_content_type(obj) if user: try: ObjectAccess.objects.get(user=user, content_type=ct, object_id=obj.id).delete() @@ -98,7 +99,7 @@ def get_object_owner(obj): :param obj: an object inheriting from ``model.Model`` :return: a ``User`` object """ - ct = ContentType.objects.get_for_model(obj) + ct = get_content_type(obj) try: entry = ObjectAccess.objects.get(content_type=ct, object_id=obj.id, is_owner=True) except ObjectAccess.DoesNotExist: diff --git a/admin/models.py b/admin/models.py index b8feddede..d88fe5a81 100644 --- a/admin/models.py +++ b/admin/models.py @@ -24,6 +24,15 @@ try: except ImportError: ldap_available = False +def get_content_type(obj): + """Simple function that use the right method to retrieve a content type + + :param obj: a django model + :return: a ``ContentType`` object + """ + return obj.get_content_type() if hasattr(obj, "get_content_type") \ + else ContentType.objects.get_for_model(obj) + class User(DUser): """Proxy for the ``User`` model. @@ -41,6 +50,21 @@ class User(DUser): def __unicode__(self): return u"%s %s" % (self.first_name, self.last_name) + @staticmethod + def get_content_type(): + """An uggly hack to retrieve the appropriate content_type! + + The explanation is available here: + https://code.djangoproject.com/ticket/11154 + + Quickly, the content_types framework does not retrieve the + appropriate content type for proxy models, it retrieves the + one of the first parent that is not a proxy. + """ + if not hasattr(User, "ct"): + User.ct = ContentType.objects.get(app_label="admin", model="user") + return User.ct + def _crypt_password(self, raw_value): scheme = parameters.get_admin("PASSWORD_SCHEME") if scheme == "crypt": @@ -125,7 +149,7 @@ class User(DUser): return Domain.objects.all() result = Domain.objects.filter(owners__user=self).distinct() - userct = ContentType.objects.get_for_model(User) + userct = self.get_content_type() for entry in self.objectaccess_set.filter(content_type=userct): if not entry.content_object.belongs_to_group('DomainAdmins'): continue @@ -186,7 +210,7 @@ class User(DUser): :param obj: an object inheriting from ``models.Model`` :return: a boolean """ - ct = ContentType.objects.get_for_model(obj) + ct = get_content_type(obj) try: ooentry = self.objectaccess_set.get(content_type=ct, object_id=obj.id) except ObjectAccess.DoesNotExist: @@ -206,7 +230,7 @@ class User(DUser): if self.is_superuser: return True - ct = ContentType.objects.get_for_model(obj) + ct = get_content_type(obj) try: ooentry = self.objectaccess_set.get(content_type=ct, object_id=obj.id) except ObjectAccess.DoesNotExist: @@ -216,7 +240,7 @@ class User(DUser): if ct.model == "user": return False - ct = ContentType.objects.get_for_model(User) + ct = self.get_content_type() qs = self.objectaccess_set.filter(content_type=ct) for ooentry in qs.all(): if ooentry.content_object.is_owner(obj): diff --git a/extensions/limits/models.py b/extensions/limits/models.py index ed2386905..9c26ac570 100644 --- a/extensions/limits/models.py +++ b/extensions/limits/models.py @@ -1,7 +1,6 @@ # coding: utf-8 from django.db import models -from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes import generic from django.utils.translation import ugettext as _, ugettext_noop from modoboa.admin.models import User diff --git a/extensions/limits/permissions.py b/extensions/limits/permissions.py index a16b3939c..fd4bf1f91 100644 --- a/extensions/limits/permissions.py +++ b/extensions/limits/permissions.py @@ -1,10 +1,9 @@ # coding: utf-8 from django.utils.translation import ugettext as _, ugettext_noop -from django.contrib.auth.models import User from modoboa.admin.permissions import Permissions -from modoboa.admin.lib import grant_access_to_object -from modoboa.admin.models import ObjectAccess +from modoboa.admin.lib import grant_access_to_object, ungrant_access_to_object +from modoboa.admin.models import User, ObjectAccess from modoboa.lib import events from modoboa.lib.webutils import _render, _render_to_string from tables import * @@ -30,15 +29,10 @@ class ResellersPerms(Permissions): return False, dict(status="ko", content=content) def delete(self, selection): - ct = ContentType.objects.get_for_model(User) for u in User.objects.filter(id__in=selection): - try: - ObjectOwner.objects.get(content_type=ct, object_id=u.id).delete() - except ObjectOwner.DoesNotExist: - pass + ungrant_access_to_object(u) u.delete() - def get(self, request): resellers = User.objects.filter(groups__name="Resellers") return ResellersTable(request, resellers).render()