wip: Resellers and limits

Take care with proxy models and content types :p

(https://code.djangoproject.com/ticket/11154)

see #105
This commit is contained in:
Antoine Nguyen
2012-01-30 17:54:09 +01:00
parent 0114fbff35
commit 5cfe9a3efd
4 changed files with 36 additions and 18 deletions
+5 -4
View File
@@ -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:
+28 -4
View File
@@ -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):
-1
View File
@@ -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
+3 -9
View File
@@ -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()