Source

django-swingcms / swingcms / custodian / decorators.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from django.http import HttpResponseRedirect

import settings
from swingexceptions import PermissionDenied, MSG_PROHIBITED_ACTION
from cms.code import get_obj_or_404
from custodian.code import get_user, has_perm


def login_required():
    """
    If user is anonymous redirect to login.
    """
    def decorator(f):
        def wrapper(request, *args, **kwargs):

            user = get_user(request)

            if user.is_anonymous():
                next_path = request.get_full_path()
                return HttpResponseRedirect("%s?next=%s" % (settings.DEFAULT_LOGIN_URL, next_path))

            return f(request, *args, **kwargs)
        return wrapper
    return decorator


def permission_required(action, object_or_model_name=None):
    """
    If decorator take 'obj' jolly string, decorated function should receive obj_model_name
    and obj_id args to substitute it. Else check in global and model permissions.
    """
    def decorator(f):
        def wrapper(request, *args, **kwargs):
            user = get_user(request)

            # if wildcard 'obj' check permission on obj passed to decorated function
            if object_or_model_name == 'obj':
                obj = get_obj_or_404(kwargs['obj_model_name'], kwargs['obj_id'])
                can = has_perm(user, action, obj=obj)

            # else evaluate global or model permission
            else:
                can = has_perm(user, action, object_or_model_name=object_or_model_name)

            if not can:
                if user.is_anonymous():
                    next_path = request.get_full_path()
                    return HttpResponseRedirect("%s?next=%s" % (settings.DEFAULT_LOGIN_URL, next_path))
                else:
                    raise PermissionDenied(display=True)

            return f(request, *args, **kwargs)
        return wrapper
    return decorator