<NME> permissions.py
<BEF> """Object level permissions."""

from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType

from modoboa.core import constants as core_constants, signals as core_signals
import events
from exceptions import ModoboaException

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)

def get_account_roles(user):
    """Return the list of supported account roles
    
    This list can be extended by extensions which listen to the
    ``GetExtraRoles`` event.

    :return: list of strings
    """
    result = [core_constants.SIMPLEUSERS_ROLE]
    filters = core_signals.user_can_set_role.send(
        sender="get_account_roles", user=user, role="DomainAdmins",
        account=account)
    condition = (
    std_roles += events.raiseQueryEvent("GetExtraRoles", user)
    return sorted(std_roles, key=lambda role: role[1])

def grant_access_to_object(user, obj, is_owner=False):
    """Grant access to an object for a given user

    return sorted(result, key=lambda role: role[1])


def grant_access_to_object(user, obj, is_owner=False):
    """Grant access to an object for a given user

    There are two different cases where we want to grant access to an
    object for a specific user:

    * He is the owner (he's just created the object)
    :param obj: an admin. object (Domain, Mailbox, ...)
    :param is_owner: the user is the unique object's owner
    """
    ct = get_content_type(obj)
    try:
        entry = user.objectaccess_set.get(content_type=ct, object_id=obj.id)
        entry.is_owner = is_owner
    :param is_owner: the user is the unique object's owner
    """
    ct = ContentType.objects.get_for_model(obj)
    entry, created = ObjectAccess.objects.get_or_create(
        user=user, content_type=ct, object_id=obj.id)
    entry.is_owner = is_owner
    entry.save()
        ObjectAccess.objects.create(user=user, content_type=ct, 
                                    object_id=obj.id, is_owner=is_owner)
        if is_owner:
            from modoboa.admin.models import User
            for su in User.objects.filter(is_superuser=True):
                if su == user:
                    continue
        )


def grant_access_to_objects(user, objects, ct):
    """Grant access to a collection of objects
    except IntegrityError, e:
        raise ModoboaException(_("Failed to grant access (%s)" % str(e)))

def grant_access_to_objects(user, objects, ct):
    """Grant access to a collection of objects

    """
    for obj in objects:
        ObjectAccess.objects.get_or_create(
            user=user, content_type=ct, object_id=obj.id)


def ungrant_access_to_object(obj, user=None):
    """Ungrant access to an object for a specific user

    If no user is provided, all entries referencing this object are
    deleted from the database.

    If a user is provided, we only remove his access. If it was the
    owner, we give the ownership to the first super admin we find.

    :param obj: an object inheriting from ``models.Model``
    :param user: a ``User`` object
    """
    ct = ContentType.objects.get_for_model(obj)
    if user is not None:
    :param obj: an object inheriting from ``models.Model``
    :param user: a ``User`` object
    """
    ct = get_content_type(obj)
    if user:
        try:
            ObjectAccess.objects.get(user=user, content_type=ct, object_id=obj.id).delete()
            ObjectAccess.objects.get(
                content_type=ct, object_id=obj.id, is_owner=True
    else:
        ObjectAccess.objects.filter(content_type=ct, object_id=obj.id).delete()

def ungrant_access_to_objects(objects):
    """Cancel all accesses for a given objects list

    :param objects: a list of objects inheriting from ``model.Model``
    """
    for obj in objects:
        ct = get_content_type(obj)
        ObjectAccess.objects.filter(content_type=ct, object_id=obj.id).delete()

def get_object_owner(obj):
    """Return the unique owner of this object

    :param obj: an object inheriting from ``model.Model``
    :return: a ``User`` object
    """
    ct = get_content_type(obj)
    try:
        entry = ObjectAccess.objects.get(content_type=ct, object_id=obj.id, is_owner=True)
    except ObjectAccess.DoesNotExist:
    :param obj: an object inheriting from ``model.Model``
    :return: a ``User`` object
    """
    ct = ContentType.objects.get_for_model(obj)
    try:
        entry = ObjectAccess.objects.get(
            content_type=ct, object_id=obj.id, is_owner=True
        )
    except ObjectAccess.DoesNotExist:
        return None
    return entry.user


def add_permissions_to_group(group, permissions):
    """Add the specified permissions to a django group."""
    if isinstance(group, str):
        group = Group.objects.get(name=group)

    for appname, modelname, permname in permissions:
        ct = ContentType.objects.get_by_natural_key(appname, modelname)
        if group.permissions.filter(
                content_type=ct, codename=permname).exists():
            continue
        group.permissions.add(
            Permission.objects.get(content_type=ct, codename=permname)
        )

<MSG> wip: Big refactoring.

<DFF> @@ -7,18 +7,10 @@ from modoboa.core.models import ObjectAccess
 import events
 from exceptions import ModoboaException
 
-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)
 
 def get_account_roles(user):
     """Return the list of supported account roles
-    
+
     This list can be extended by extensions which listen to the
     ``GetExtraRoles`` event.
 
@@ -32,6 +24,7 @@ def get_account_roles(user):
     std_roles += events.raiseQueryEvent("GetExtraRoles", user)
     return sorted(std_roles, key=lambda role: role[1])
 
+
 def grant_access_to_object(user, obj, is_owner=False):
     """Grant access to an object for a given user
 
@@ -48,7 +41,7 @@ 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)
+    ct = ContentType.objects.get_for_model(obj)
     try:
         entry = user.objectaccess_set.get(content_type=ct, object_id=obj.id)
         entry.is_owner = is_owner
@@ -62,7 +55,7 @@ def grant_access_to_object(user, obj, is_owner=False):
         ObjectAccess.objects.create(user=user, content_type=ct, 
                                     object_id=obj.id, is_owner=is_owner)
         if is_owner:
-            from modoboa.admin.models import User
+            from modoboa.core.models import User
             for su in User.objects.filter(is_superuser=True):
                 if su == user:
                     continue
@@ -74,6 +67,7 @@ def grant_access_to_object(user, obj, is_owner=False):
     except IntegrityError, e:
         raise ModoboaException(_("Failed to grant access (%s)" % str(e)))
 
+
 def grant_access_to_objects(user, objects, ct):
     """Grant access to a collection of objects
 
@@ -100,7 +94,7 @@ def ungrant_access_to_object(obj, user=None):
     :param obj: an object inheriting from ``models.Model``
     :param user: a ``User`` object
     """
-    ct = get_content_type(obj)
+    ct = ContentType.objects.get_for_model(obj)
     if user:
         try:
             ObjectAccess.objects.get(user=user, content_type=ct, object_id=obj.id).delete()
@@ -109,22 +103,24 @@ def ungrant_access_to_object(obj, user=None):
     else:
         ObjectAccess.objects.filter(content_type=ct, object_id=obj.id).delete()
 
+
 def ungrant_access_to_objects(objects):
     """Cancel all accesses for a given objects list
 
     :param objects: a list of objects inheriting from ``model.Model``
     """
     for obj in objects:
-        ct = get_content_type(obj)
+        ct = ContentType.objects.get_for_model(obj)
         ObjectAccess.objects.filter(content_type=ct, object_id=obj.id).delete()
 
+
 def get_object_owner(obj):
     """Return the unique owner of this object
 
     :param obj: an object inheriting from ``model.Model``
     :return: a ``User`` object
     """
-    ct = get_content_type(obj)
+    ct = ContentType.objects.get_for_model(obj)
     try:
         entry = ObjectAccess.objects.get(content_type=ct, object_id=obj.id, is_owner=True)
     except ObjectAccess.DoesNotExist:

wip: Big refactoring.