mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-18 05:51:26 +02:00
* Added support for migrations * Big refactoring of the admin code done: Support for SHA256 algorithm to store passwords (fix #195) done: admin models refactoring (fix #196)
133 lines
4.5 KiB
Python
133 lines
4.5 KiB
Python
# coding: utf-8
|
|
from functools import wraps
|
|
from django.contrib.contenttypes.models import ContentType
|
|
from django.utils.translation import ugettext as _
|
|
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
|
from models import *
|
|
from modoboa.lib.webutils import _render_error, _render
|
|
from modoboa.admin.tables import *
|
|
from exceptions import *
|
|
|
|
def render_listing(request, objtype, tplname="admin/listing.html",
|
|
**kwargs):
|
|
"""Common function to render a listing
|
|
|
|
All listing pages available into the admin application use the
|
|
same layout, rendered by this function.
|
|
|
|
:param request: a ``Request`` object
|
|
:param objtype: the object type's name (lowercase)
|
|
:param tplname: the template used to render the HTML
|
|
"""
|
|
tblclass = "%sTable" % objtype.capitalize()
|
|
if not globals().has_key(tblclass):
|
|
raise AdminError(_("Unknown object type"))
|
|
tblclass = globals()[tblclass]
|
|
|
|
if request.GET.has_key("domid"):
|
|
kwargs["domid"] = request.GET["domid"]
|
|
else:
|
|
kwargs["domid"] = ""
|
|
kwargs["selection"] = objtype
|
|
paginator = Paginator(kwargs["objects"],
|
|
int(parameters.get_admin("ITEMS_PER_PAGE")))
|
|
try:
|
|
page = request.GET.get("page", "1")
|
|
except ValueError:
|
|
page = 1
|
|
try:
|
|
kwargs["objects"] = paginator.page(page)
|
|
except (EmptyPage, PageNotAnInteger):
|
|
kwargs["objects"] = paginator.page(paginator.num_pages)
|
|
kwargs["last_page"] = paginator.num_pages
|
|
kwargs["total"] = paginator.count
|
|
kwargs["table"] = tblclass(request, kwargs["objects"].object_list)
|
|
|
|
return _render(request, tplname, kwargs)
|
|
|
|
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)
|
|
* He is going to administrate the object (but he is not the owner)
|
|
|
|
:param user: a ``User`` object
|
|
:param obj: an admin. object (Domain, Mailbox, ...)
|
|
:param is_owner: the user is the unique object's owner
|
|
"""
|
|
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()
|
|
except ObjectAccess.DoesNotExist:
|
|
pass
|
|
else:
|
|
return
|
|
|
|
try:
|
|
objaccess = ObjectAccess(user=user, content_object=obj, is_owner=is_owner)
|
|
objaccess.save()
|
|
except IntegrityError, e:
|
|
raise AdminError(_("Failed to grant access (%s)" % str(e)))
|
|
|
|
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.
|
|
|
|
:param obj: an object inheriting from ``models.Model``
|
|
:param user: a ``User`` object
|
|
"""
|
|
ct = ContentType.objects.get_for_model(obj)
|
|
if user:
|
|
try:
|
|
ObjectAccess.objects.get(user=user, content_type=ct, object_id=obj.id).delete()
|
|
except ObjectAccess.DoesNotExist:
|
|
pass
|
|
else:
|
|
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 = 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 check_domain_access(f):
|
|
"""Decorator to check if the current user can access a domain
|
|
|
|
This decorator only applies to url that contain a 'domid' or
|
|
'mbid' parameter. (for a direct access)
|
|
|
|
Raise a ``PermDeniedError`` if the current user can't view the
|
|
requested object.
|
|
"""
|
|
@wraps(f)
|
|
def dec(request, **kwargs):
|
|
if not request.user.is_superuser:
|
|
domain = None
|
|
domid = request.GET.get("domid", None)
|
|
if domid:
|
|
domain = Domain.objects.get(pk=domid)
|
|
else:
|
|
mbid = request.GET.get("mbid", None)
|
|
if mbid:
|
|
domain = Mailbox.objects.get(pk=mbid).domain
|
|
if domain and not request.user.can_access(domain):
|
|
raise PermDeniedError(_("You can't access this domain"))
|
|
|
|
return f(request, **kwargs)
|
|
return dec
|