コード例 #1
0
        def _wrapped_view(*args, **kwargs):
            # View functions take request as the first argument,
            # but view methods take (self, request) as the first two arguments.
            # This correctly identifies the request in either case,
            # and provides a meaningful error message if no request is found.
            for arg in args[:2]:
                if isinstance(arg, HttpRequest):
                    request = arg
                    break
            else:
                raise TypeError("%s() missing 1 required positional argument: "
                                "'request'" % view_func.__name__)
            # if more than one parameter is passed to the decorator we try to
            # fetch object for which check would be made
            obj = None
            if lookup_variables:
                model, lookups = lookup_variables[0], lookup_variables[1:]
                # Parse model
                if isinstance(model, str):
                    splitted = model.split('.')
                    if len(splitted) != 2:
                        raise GuardianError(
                            "If model should be looked up from "
                            "string it needs format: 'app_label.ModelClass'")
                    model = apps.get_model(*splitted)
                elif issubclass(model.__class__, (Model, ModelBase, QuerySet)):
                    pass
                else:
                    raise GuardianError(
                        "First lookup argument must always be "
                        "a model, string pointing at app/model or queryset. "
                        "Given: %s (type: %s)" % (model, type(model)))
                # Parse lookups
                if len(lookups) % 2 != 0:
                    raise GuardianError(
                        "Lookup variables must be provided "
                        "as pairs of lookup_string and view_arg")
                lookup_dict = {}
                for lookup, view_arg in zip(lookups[::2], lookups[1::2]):
                    if view_arg not in kwargs:
                        raise GuardianError("Argument %s was not passed "
                                            "into view function" % view_arg)
                    lookup_dict[lookup] = kwargs[view_arg]
                obj = get_object_or_404(model, **lookup_dict)

            response = get_40x_or_None(request,
                                       perms=[perm],
                                       obj=obj,
                                       login_url=login_url,
                                       redirect_field_name=redirect_field_name,
                                       return_403=return_403,
                                       return_404=return_404,
                                       accept_global_perms=accept_global_perms)
            if response:
                return response
            return view_func(*args, **kwargs)
コード例 #2
0
        def _wrapped_view(request, *args, **kwargs):
            # if more than one parameter is passed to the decorator we try to
            # fetch object for which check would be made
            obj = None
            if lookup_variables:
                model, lookups = lookup_variables[0], lookup_variables[1:]
                # Parse model
                if isinstance(model, basestring):
                    splitted = model.split('.')
                    if len(splitted) != 2:
                        raise GuardianError(
                            "If model should be looked up from "
                            "string it needs format: 'app_label.ModelClass'")
                    model = get_model(*splitted)
                elif type(model) in (Model, ModelBase, QuerySet):
                    pass
                else:
                    raise GuardianError(
                        "First lookup argument must always be "
                        "a model, string pointing at app/model or queryset. "
                        "Given: %s (type: %s)" % (model, type(model)))
                # Parse lookups
                if len(lookups) % 2 != 0:
                    raise GuardianError(
                        "Lookup variables must be provided "
                        "as pairs of lookup_string and view_arg")
                lookup_dict = {}
                for lookup, view_arg in zip(lookups[::2], lookups[1::2]):
                    if view_arg not in kwargs:
                        raise GuardianError("Argument %s was not passed "
                                            "into view function" % view_arg)
                    lookup_dict[lookup] = kwargs[view_arg]
                obj = get_object_or_404(model, **lookup_dict)

            # Handles both original and with object provided permission check
            # as ``obj`` defaults to None
            if not request.user.has_perm(perm, obj):
                if return_403:
                    if guardian_settings.RENDER_403:
                        try:
                            response = render_to_response(
                                guardian_settings.TEMPLATE_403, {},
                                RequestContext(request))
                            response.status_code = 403
                            return response
                        except TemplateDoesNotExist, e:
                            if settings.DEBUG:
                                raise e
                    elif guardian_settings.RAISE_403:
                        raise PermissionDenied
                    return HttpResponseForbidden()
                else:
                    path = urlquote(request.get_full_path())
                    tup = login_url, redirect_field_name, path
                    return HttpResponseRedirect("%s?%s=%s" % tup)
コード例 #3
0
ファイル: decorators.py プロジェクト: wlorenzetti/g3w-admin
        def _wrapped_view(request, *args, **kwargs):
            # if more than one parameter is passed to the decorator we try to
            # fetch object for which check would be made
            obj = None
            if lookup_variables:
                project_type, project_key = lookup_variables[
                    0], lookup_variables[1]
                project_key_value = kwargs[project_key]
                project_type_value = kwargs[project_type]
                # Parse model
                if project_type_value in settings.G3WADMIN_PROJECT_APPS:
                    model = apps.get_model(project_type_value, 'Project')
                else:
                    raise GuardianError("{} no in G3W_PROJECT_APPS: ".format(
                        project_type_value, settings.G3WADMIN_PROJECT_APPS))

                if project_key_value.isdigit():
                    lookup_dict = {'pk': int(project_key_value)}
                else:
                    lookup_dict = {'slug': project_key_value}
                obj = get_object_or_404(model, **lookup_dict)

            # ad app to perm
            perms = [project_type_value + "." + perm]

            response = get_40x_or_None(request,
                                       perms=perms,
                                       obj=obj,
                                       login_url=login_url,
                                       redirect_field_name=redirect_field_name,
                                       return_403=return_403,
                                       accept_global_perms=accept_global_perms)
            if response:
                return response
            return view_func(request, *args, **kwargs)
コード例 #4
0
        def _wrapped_view(request, *args, **kwargs):
            # if more than one parameter is passed to the decorator we try to
            # fetch object for which check would be made
            obj = None
            if lookup_variables:
                model, lookups = lookup_variables[0], lookup_variables[1:]
                # Parse model
                if isinstance(model, str):
                    splitted = model.split('.')
                    if len(splitted) != 2:
                        raise GuardianError(
                            "If model should be looked up from "
                            "string it needs format: 'app_label.ModelClass'")
                    model = apps.get_model(*splitted)
                elif issubclass(model.__class__, (Model, ModelBase, QuerySet)):
                    pass
                else:
                    raise GuardianError(
                        "First lookup argument must always be "
                        "a model, string pointing at app/model or queryset. "
                        "Given: %s (type: %s)" % (model, type(model)))
                # Parse lookups
                if len(lookups) % 2 != 0:
                    raise GuardianError(
                        "Lookup variables must be provided "
                        "as pairs of lookup_string and view_arg")
                lookup_dict = {}
                for lookup, view_arg in zip(lookups[::2], lookups[1::2]):
                    if view_arg not in kwargs:
                        raise GuardianError("Argument %s was not passed "
                                            "into view function" % view_arg)
                    lookup_dict[lookup] = kwargs[view_arg]
                obj = get_object_or_404(model, **lookup_dict)

            response = get_40x_or_None(request,
                                       perms=[perm],
                                       obj=obj,
                                       login_url=login_url,
                                       redirect_field_name=redirect_field_name,
                                       return_403=return_403,
                                       return_404=return_404,
                                       accept_global_perms=accept_global_perms)
            if response:
                return response
            return view_func(request, *args, **kwargs)
コード例 #5
0
ファイル: decorators.py プロジェクト: spudunk/g3w-admin
def permission_required_by_user_backend(user, perm, user_tuple, **kwargs):
    """
    Check if perm to check is in user perms fo ouser
    """
    model, lookups = user_tuple[0], user_tuple[1:]
    lookup_dict = {}
    for lookup, view_arg in zip(lookups[::2], lookups[1::2]):
        if view_arg not in kwargs:
            raise GuardianError("Argument %s was not passed "
                                "into view function" % view_arg)
        lookup_dict[lookup] = kwargs[view_arg]

    ouser = get_object_or_404(model, **lookup_dict)
    perms = get_perms_by_user_backend(user, ouser)
    return perm in perms
コード例 #6
0
ファイル: decorators.py プロジェクト: nstoykov/g3w-admin
def permission_required_for_anonymous_user(perm, user_tuple, **kwargs):
    """
    Check if anonymous user has perms on object
    """
    model, lookups = user_tuple[0], user_tuple[1:]
    lookup_dict = {}
    for lookup, view_arg in zip(lookups[::2], lookups[1::2]):
        if view_arg not in kwargs:
            raise GuardianError("Argument %s was not passed "
                                "into view function" % view_arg)
        lookup_dict[lookup] = kwargs[view_arg]

    perms = get_perms(get_anonymous_user(),
                      get_object_or_404(model, **lookup_dict))
    return perm in perms
コード例 #7
0
 def test_error_classes(self):
     self.assertTrue(isinstance(GuardianError(), Exception))
     guardian_errors = [NotUserNorGroup]
     for err in guardian_errors:
         self._test_error_class(err())
コード例 #8
0
def permission_required(perm, lookup_variables=None, **kwargs):
    """
    Decorator for views that checks whether a user has a particular permission
    enabled.
    Optionally, instances for which check should be made may be passed as an
    second argument or as a tuple parameters same as those passed to
    ``get_object_or_404`` but must be provided as pairs of strings. This way
    decorator can fetch i.e. ``User`` instance based on performed request and
    check permissions on it (without this, one would need to fetch user instance
    at view's logic and check permission inside a view).
    :param login_url: if denied, user would be redirected to location set by
      this parameter. Defaults to ``django.conf.settings.LOGIN_URL``.
    :param redirect_field_name: name of the parameter passed if redirected.
      Defaults to ``django.contrib.auth.REDIRECT_FIELD_NAME``.
    :param return_403: if set to ``True`` then instead of redirecting to the
      login page, response with status code 403 is returned (
      ``django.http.HttpResponseForbidden`` instance or rendered template -
      see :setting:`GUARDIAN_RENDER_403`). Defaults to ``False``.
    :param return_404: if set to ``True`` then instead of redirecting to the
      login page, response with status code 404 is returned (
      ``django.http.HttpResponseNotFound`` instance or rendered template -
      see :setting:`GUARDIAN_RENDER_404`). Defaults to ``False``.
    :param accept_global_perms: if set to ``True``, then *object level
      permission* would be required **only if user does NOT have global
      permission** for target *model*. If turned on, makes this decorator
      like an extension over standard
      ``django.contrib.admin.decorators.permission_required`` as it would
      check for global permissions first. Defaults to ``False``.
    Examples::
        @permission_required('auth.change_user', return_403=True)
        def my_view(request):
            return HttpResponse('Hello')
        @permission_required('auth.change_user', (User, 'username', 'username'))
        def my_view(request, username):
            '''
            auth.change_user permission would be checked based on given
            'username'. If view's parameter would be named ``name``, we would
            rather use following decorator::
                @permission_required('auth.change_user', (User, 'username', 'name'))
            '''
            user = get_object_or_404(User, username=username)
            return user.get_absolute_url()
        @permission_required('auth.change_user',
            (User, 'username', 'username', 'groups__name', 'group_name'))
        def my_view(request, username, group_name):
            '''
            Similar to the above example, here however we also make sure that
            one of user's group is named same as request's ``group_name`` param.
            '''
            user = get_object_or_404(User, username=username,
                group__name=group_name)
            return user.get_absolute_url()
    """
    login_url = kwargs.pop('login_url', settings.LOGIN_URL)
    redirect_field_name = kwargs.pop('redirect_field_name',
                                     REDIRECT_FIELD_NAME)
    return_403 = kwargs.pop('return_403', False)
    return_404 = kwargs.pop('return_404', False)
    accept_global_perms = kwargs.pop('accept_global_perms', False)

    # Check if perm is given as string in order not to decorate
    # view function itself which makes debugging harder
    if not isinstance(perm, str):
        raise GuardianError(
            "First argument must be in format: "
            "'app_label.codename or a callable which return similar string'")

    def decorator(view_func):
        def _wrapped_view(*args, **kwargs):
            # View functions take request as the first argument,
            # but view methods take (self, request) as the first two arguments.
            # This correctly identifies the request in either case,
            # and provides a meaningful error message if no request is found.
            for arg in args[:2]:
                if isinstance(arg, HttpRequest):
                    request = arg
                    break
            else:
                raise TypeError("%s() missing 1 required positional argument: "
                                "'request'" % view_func.__name__)
            # if more than one parameter is passed to the decorator we try to
            # fetch object for which check would be made
            obj = None
            if lookup_variables:
                model, lookups = lookup_variables[0], lookup_variables[1:]
                # Parse model
                if isinstance(model, str):
                    splitted = model.split('.')
                    if len(splitted) != 2:
                        raise GuardianError(
                            "If model should be looked up from "
                            "string it needs format: 'app_label.ModelClass'")
                    model = apps.get_model(*splitted)
                elif issubclass(model.__class__, (Model, ModelBase, QuerySet)):
                    pass
                else:
                    raise GuardianError(
                        "First lookup argument must always be "
                        "a model, string pointing at app/model or queryset. "
                        "Given: %s (type: %s)" % (model, type(model)))
                # Parse lookups
                if len(lookups) % 2 != 0:
                    raise GuardianError(
                        "Lookup variables must be provided "
                        "as pairs of lookup_string and view_arg")
                lookup_dict = {}
                for lookup, view_arg in zip(lookups[::2], lookups[1::2]):
                    if view_arg not in kwargs:
                        raise GuardianError("Argument %s was not passed "
                                            "into view function" % view_arg)
                    lookup_dict[lookup] = kwargs[view_arg]
                obj = get_object_or_404(model, **lookup_dict)

            response = get_40x_or_None(request,
                                       perms=[perm],
                                       obj=obj,
                                       login_url=login_url,
                                       redirect_field_name=redirect_field_name,
                                       return_403=return_403,
                                       return_404=return_404,
                                       accept_global_perms=accept_global_perms)
            if response:
                return response
            return view_func(*args, **kwargs)

        return wraps(view_func)(_wrapped_view)

    return decorator
コード例 #9
0
def permission_required(perm, lookup_variables=None, **kwargs):
    """
    Decorator for views that checks whether a user has a particular permission
    enabled.

    Optionally, instances for which check should be made may be passed as an
    second argument or as a tuple parameters same as those passed to
    ``get_object_or_404`` but must be provided as pairs of strings.

    :param login_url: if denied, user would be redirected to location set by
      this parameter. Defaults to ``django.conf.settings.LOGIN_URL``.
    :param redirect_field_name: name of the parameter passed if redirected.
      Defaults to ``django.contrib.auth.REDIRECT_FIELD_NAME``.
    :param return_403: if set to ``True`` then instead of redirecting to the
      login page, response with status code 403 is returned (
      ``django.http.HttpResponseForbidden`` instance). Defaults to ``False``.

    Examples::

        @permission_required('auth.change_user', return_403=True)
        def my_view(request):
            return HttpResponse('Hello')

        @permission_required('auth.change_user', (User, 'username', 'username'))
        def my_view(request, username):
            user = get_object_or_404(User, username=username)
            return user.get_absolute_url()

        @permission_required('auth.change_user',
            (User, 'username', 'username', 'groups__name', 'group_name'))
        def my_view(request, username, group_name):
            user = get_object_or_404(User, username=username,
                group__name=group_name)
            return user.get_absolute_url()

    """
    login_url = kwargs.pop('login_url', settings.LOGIN_URL)
    redirect_field_name = kwargs.pop('redirect_field_name',
                                     REDIRECT_FIELD_NAME)
    return_403 = kwargs.pop('return_403', False)

    # Check if perm is given as string in order not to decorate
    # view function itself which makes debugging harder
    if not isinstance(perm, basestring):
        raise GuardianError(
            "First argument must be in format: "
            "'app_label.codename or a callable which return similar string'")

    def decorator(view_func):
        def _wrapped_view(request, *args, **kwargs):
            # if more than one parameter is passed to the decorator we try to
            # fetch object for which check would be made
            obj = None
            if lookup_variables:
                model, lookups = lookup_variables[0], lookup_variables[1:]
                # Parse model
                if isinstance(model, basestring):
                    splitted = model.split('.')
                    if len(splitted) != 2:
                        raise GuardianError(
                            "If model should be looked up from "
                            "string it needs format: 'app_label.ModelClass'")
                    model = get_model(*splitted)
                elif type(model) in (Model, ModelBase, QuerySet):
                    pass
                else:
                    raise GuardianError(
                        "First lookup argument must always be "
                        "a model, string pointing at app/model or queryset. "
                        "Given: %s (type: %s)" % (model, type(model)))
                # Parse lookups
                if len(lookups) % 2 != 0:
                    raise GuardianError(
                        "Lookup variables must be provided "
                        "as pairs of lookup_string and view_arg")
                lookup_dict = {}
                for lookup, view_arg in zip(lookups[::2], lookups[1::2]):
                    if view_arg not in kwargs:
                        raise GuardianError("Argument %s was not passed "
                                            "into view function" % view_arg)
                    lookup_dict[lookup] = kwargs[view_arg]
                obj = get_object_or_404(model, **lookup_dict)

            # Handles both original and with object provided permission check
            # as ``obj`` defaults to None
            if not request.user.has_perm(perm, obj):
                if return_403:
                    return HttpResponseForbidden()
                else:
                    path = urlquote(request.get_full_path())
                    tup = login_url, redirect_field_name, path
                    return HttpResponseRedirect("%s?%s=%s" % tup)
            return view_func(request, *args, **kwargs)

        return wraps(view_func)(_wrapped_view)

    return decorator
コード例 #10
0
        def wrapped(*args, **kwargs):
            # if more than one parameter is passed to the decorator we try to
            # fetch object for which check would be made
            obj = None
            request = None
            if 'request' in kwargs:
                request = kwargs['request']
            elif 'bundle' in kwargs:
                request = kwargs['bundle'].request
            else:
                for arg in args:
                    if isinstance(arg, HttpRequest):
                        request = arg
                        break
                    elif isinstance(arg, Bundle) and isinstance(
                            arg.request, HttpRequest):
                        request = arg.request
                        break

            if lookup_variables:
                model, lookups = lookup_variables[0], lookup_variables[1:]
                # Parse model
                if isinstance(model, basestring):
                    splitted = model.split('.')
                    if len(splitted) != 2:
                        raise GuardianError(
                            "If model should be looked up from "
                            "string it needs format: 'app_label.ModelClass'")
                    model = get_model(*splitted)
                elif issubclass(model.__class__, (Model, ModelBase, QuerySet)):
                    pass
                else:
                    raise GuardianError(
                        "First lookup argument must always be "
                        "a model, string pointing at app/model or queryset. "
                        "Given: %s (type: %s)" % (model, type(model)))
                # Parse lookups
                if len(lookups) % 2 != 0:
                    raise GuardianError(
                        "Lookup variables must be provided "
                        "as pairs of lookup_string and view_arg")
                lookup_dict = {}
                for lookup, view_arg in zip(lookups[::2], lookups[1::2]):
                    if view_arg not in kwargs:
                        raise GuardianError("Argument %s was not passed "
                                            "into view function" % view_arg)
                    lookup_dict[lookup] = kwargs[view_arg]

                if not check_static:
                    try:
                        obj = get_object_or_404(model, **lookup_dict)
                    except Http404:
                        raise ImmediateHttpResponse(
                            response=http.HttpNotFound())

            has_perms = False
            if request:
                if check_static:
                    has_perms = model.static_has_perms(perm, request.user)
                else:
                    has_perms = obj.has_perms(perm, request.user)

            if not has_perms:
                raise ImmediateHttpResponse(response=http.HttpForbidden())

            return view_func(*args, **kwargs)
コード例 #11
0
def permission_required(perm, lookup_variables=None, **kwargs):
    """
    Decorator for views that checks whether a user has a particular permission
    enabled.

    Optionally, instances for which check should be made may be passed as an
    second argument or as a tuple parameters.

    :param check_static: if set to ``Model``, the permissions will be
    checked in calling to Model.static_has_perms() instead of calling to
    has_perms(). Defaults to ``None``.

    Examples::

    @permission_required('join', (Agora, 'id', 'id'))
    def join(self, request):
    agora = get_object_or_404(Agora, id=id)
    agora.members.append(request.user)
    return self.success()

    @permission_required('create', check_static=Agora)
    def obj_create(self, bundle, request=None, **kwargs):
    user = get_object_or_404(User, username=username)
    return user.get_absolute_url()

    """
    check_static = kwargs.pop('check_static', None)

    if check_static:
        lookup_variables = [check_static]

    # Check if perm is given as string in order not to decorate
    # view function itself which makes debugging harder
    if not isinstance(perm, basestring):
        raise GuardianError(
            "First argument must be in format: "
            "'app_label.codename or a callable which return similar string'")

    def decorator(view_func):
        def wrapped(*args, **kwargs):
            # if more than one parameter is passed to the decorator we try to
            # fetch object for which check would be made
            obj = None
            request = None
            if 'request' in kwargs:
                request = kwargs['request']
            elif 'bundle' in kwargs:
                request = kwargs['bundle'].request
            else:
                for arg in args:
                    if isinstance(arg, HttpRequest):
                        request = arg
                        break
                    elif isinstance(arg, Bundle) and isinstance(
                            arg.request, HttpRequest):
                        request = arg.request
                        break

            if lookup_variables:
                model, lookups = lookup_variables[0], lookup_variables[1:]
                # Parse model
                if isinstance(model, basestring):
                    splitted = model.split('.')
                    if len(splitted) != 2:
                        raise GuardianError(
                            "If model should be looked up from "
                            "string it needs format: 'app_label.ModelClass'")
                    model = get_model(*splitted)
                elif issubclass(model.__class__, (Model, ModelBase, QuerySet)):
                    pass
                else:
                    raise GuardianError(
                        "First lookup argument must always be "
                        "a model, string pointing at app/model or queryset. "
                        "Given: %s (type: %s)" % (model, type(model)))
                # Parse lookups
                if len(lookups) % 2 != 0:
                    raise GuardianError(
                        "Lookup variables must be provided "
                        "as pairs of lookup_string and view_arg")
                lookup_dict = {}
                for lookup, view_arg in zip(lookups[::2], lookups[1::2]):
                    if view_arg not in kwargs:
                        raise GuardianError("Argument %s was not passed "
                                            "into view function" % view_arg)
                    lookup_dict[lookup] = kwargs[view_arg]

                if not check_static:
                    try:
                        obj = get_object_or_404(model, **lookup_dict)
                    except Http404:
                        raise ImmediateHttpResponse(
                            response=http.HttpNotFound())

            has_perms = False
            if request:
                if check_static:
                    has_perms = model.static_has_perms(perm, request.user)
                else:
                    has_perms = obj.has_perms(perm, request.user)

            if not has_perms:
                raise ImmediateHttpResponse(response=http.HttpForbidden())

            return view_func(*args, **kwargs)

        return wraps(view_func)(wrapped)

    return decorator
コード例 #12
0
ファイル: decorators.py プロジェクト: wlorenzetti/g3w-admin
def project_type_permission_required(perm, lookup_variables=None, **kwargs):
    """
    Decorator for views that checks whether a user has a particular permission
    enabled.

    Optionally, instances for which check should be made may be passed as an
    second argument or as a tuple parameters same as those passed to
    ``get_object_or_404`` but must be provided as pairs of strings. This way
    decorator can fetch i.e. ``User`` instance based on performed request and
    check permissions on it (without this, one would need to fetch user instance
    at view's logic and check permission inside a view).

    :param login_url: if denied, user would be redirected to location set by
      this parameter. Defaults to ``django.conf.settings.LOGIN_URL``.
    :param redirect_field_name: name of the parameter passed if redirected.
      Defaults to ``django.contrib.auth.REDIRECT_FIELD_NAME``.
    :param return_403: if set to ``True`` then instead of redirecting to the
      login page, response with status code 403 is returned (
      ``django.http.HttpResponseForbidden`` instance or rendered template -
      see :setting:`GUARDIAN_RENDER_403`). Defaults to ``False``.
    :param accept_global_perms: if set to ``True``, then *object level
      permission* would be required **only if user does NOT have global
      permission** for target *model*. If turned on, makes this decorator
      like an extension over standard
      ``django.contrib.admin.decorators.permission_required`` as it would
      check for global permissions first. Defaults to ``False``.

    Examples::
        @permission_required('qdjango.edit_notes', ('qdjango', '2'))
        def my_view(request, username):
            ...
    """
    login_url = kwargs.pop('login_url', settings.LOGIN_URL)
    redirect_field_name = kwargs.pop('redirect_field_name',
                                     REDIRECT_FIELD_NAME)
    return_403 = kwargs.pop('return_403', False)
    accept_global_perms = kwargs.pop('accept_global_perms', False)

    # Check if perm is given as string in order not to decorate
    # view function itself which makes debugging harder
    if not isinstance(perm, basestring):
        raise GuardianError(
            "First argument must be in format: "
            "'app_label.codename or a callable which return similar string'")

    def decorator(view_func):
        def _wrapped_view(request, *args, **kwargs):
            # if more than one parameter is passed to the decorator we try to
            # fetch object for which check would be made
            obj = None
            if lookup_variables:
                project_type, project_key = lookup_variables[
                    0], lookup_variables[1]
                project_key_value = kwargs[project_key]
                project_type_value = kwargs[project_type]
                # Parse model
                if project_type_value in settings.G3WADMIN_PROJECT_APPS:
                    model = apps.get_model(project_type_value, 'Project')
                else:
                    raise GuardianError("{} no in G3W_PROJECT_APPS: ".format(
                        project_type_value, settings.G3WADMIN_PROJECT_APPS))

                if project_key_value.isdigit():
                    lookup_dict = {'pk': int(project_key_value)}
                else:
                    lookup_dict = {'slug': project_key_value}
                obj = get_object_or_404(model, **lookup_dict)

            # ad app to perm
            perms = [project_type_value + "." + perm]

            response = get_40x_or_None(request,
                                       perms=perms,
                                       obj=obj,
                                       login_url=login_url,
                                       redirect_field_name=redirect_field_name,
                                       return_403=return_403,
                                       accept_global_perms=accept_global_perms)
            if response:
                return response
            return view_func(request, *args, **kwargs)

        return wraps(view_func)(_wrapped_view)

    return decorator
コード例 #13
0
ファイル: decorators.py プロジェクト: dohoang1102/LibShare
def permission_required(perm, lookup_variables=None, **kwargs):
    """
    Decorator for views that checks whether a user has a particular permission
    enabled.

    Optionally, instances for which check should be made may be passed as an
    second argument or as a tuple parameters same as those passed to
    ``get_object_or_404`` but must be provided as pairs of strings.

    :param login_url: if denied, user would be redirected to location set by
      this parameter. Defaults to ``django.conf.settings.LOGIN_URL``.
    :param redirect_field_name: name of the parameter passed if redirected.
      Defaults to ``django.contrib.auth.REDIRECT_FIELD_NAME``.
    :param return_403: if set to ``True`` then instead of redirecting to the
      login page, response with status code 403 is returned (
      ``django.http.HttpResponseForbidden`` instance or rendered template -
      see :setting:`GUARDIAN_RENDER_403`). Defaults to ``False``.
    :param accept_global_perms: if set to ``True``, then *object level
      permission* would be required **only if user does NOT have global
      permission** for target *model*. If turned on, makes this decorator
      like an extension over standard
      ``django.contrib.admin.decorators.permission_required`` as it would
      check for global permissions first. Defaults to ``False``.

    Examples::

        @permission_required('auth.change_user', return_403=True)
        def my_view(request):
            return HttpResponse('Hello')

        @permission_required('auth.change_user', (User, 'username', 'username'))
        def my_view(request, username):
            user = get_object_or_404(User, username=username)
            return user.get_absolute_url()

        @permission_required('auth.change_user',
            (User, 'username', 'username', 'groups__name', 'group_name'))
        def my_view(request, username, group_name):
            user = get_object_or_404(User, username=username,
                group__name=group_name)
            return user.get_absolute_url()

    """
    login_url = kwargs.pop('login_url', settings.LOGIN_URL)
    redirect_field_name = kwargs.pop('redirect_field_name',
                                     REDIRECT_FIELD_NAME)
    return_403 = kwargs.pop('return_403', False)
    accept_global_perms = kwargs.pop('accept_global_perms', False)

    # Check if perm is given as string in order not to decorate
    # view function itself which makes debugging harder
    if not isinstance(perm, basestring):
        raise GuardianError(
            "First argument must be in format: "
            "'app_label.codename or a callable which return similar string'")

    def decorator(view_func):
        def _wrapped_view(request, *args, **kwargs):
            # if more than one parameter is passed to the decorator we try to
            # fetch object for which check would be made
            obj = None
            if lookup_variables:
                model, lookups = lookup_variables[0], lookup_variables[1:]
                # Parse model
                if isinstance(model, basestring):
                    splitted = model.split('.')
                    if len(splitted) != 2:
                        raise GuardianError(
                            "If model should be looked up from "
                            "string it needs format: 'app_label.ModelClass'")
                    model = get_model(*splitted)
                elif type(model) in (Model, ModelBase, QuerySet):
                    pass
                else:
                    raise GuardianError(
                        "First lookup argument must always be "
                        "a model, string pointing at app/model or queryset. "
                        "Given: %s (type: %s)" % (model, type(model)))
                # Parse lookups
                if len(lookups) % 2 != 0:
                    raise GuardianError(
                        "Lookup variables must be provided "
                        "as pairs of lookup_string and view_arg")
                lookup_dict = {}
                for lookup, view_arg in zip(lookups[::2], lookups[1::2]):
                    if view_arg not in kwargs:
                        raise GuardianError("Argument %s was not passed "
                                            "into view function" % view_arg)
                    lookup_dict[lookup] = kwargs[view_arg]
                obj = get_object_or_404(model, **lookup_dict)

            response = get_403_or_None(request,
                                       perms=[perm],
                                       obj=obj,
                                       login_url=login_url,
                                       redirect_field_name=redirect_field_name,
                                       return_403=return_403,
                                       accept_global_perms=accept_global_perms)
            if response:
                return response
            return view_func(request, *args, **kwargs)

        return wraps(view_func)(_wrapped_view)

    return decorator