示例#1
0
    def has_permission(self, request: Request, view) -> bool:
        from rest_framework.viewsets import ViewSetMixin

        if bypass_permissions(request):
            return True

        scopes_required = get_required_scopes(view)
        component = self.get_component(view)

        if not self.permission_fields:
            return request.jwt_auth.has_auth(scopes_required, component)

        main_resource = self.get_main_resource()

        if view.action == "create":
            if view.__class__ is main_resource:
                main_object_data = request.data

            else:
                main_object_url = request.data[view.permission_main_object]
                main_object_path = urlparse(main_object_url).path
                main_object = get_resource_for_path(main_object_path)
                main_object_data = self.format_data(main_object, request)

            fields = self.get_fields(main_object_data)
            return request.jwt_auth.has_auth(scopes_required, component,
                                             **fields)

        # detect if this is an unsupported method - if it's a viewset and the
        # action was not mapped, it's not supported and DRF will catch it
        if view.action is None and isinstance(view, ViewSetMixin):
            return True

        # by default - check if the action is allowed at all
        return request.jwt_auth.has_auth(scopes_required, component)
示例#2
0
    def has_permission(self, request: Request, view) -> bool:
        # permission checks run before the handler is determined. if there is no handler,
        # a "method is not allowed" must be raised, not an HTTP 403 (see #385)
        # this implementation works for both APIView and viewsets
        has_handler = hasattr(view, request.method.lower())
        if not has_handler:
            view.http_method_not_allowed(request)

        # JWTs are only valid for a short amount of time
        self.check_jwt_expiry(request.jwt_auth.payload)

        from rest_framework.viewsets import ViewSetMixin

        if bypass_permissions(request):
            return True

        scopes_required = get_required_scopes(view)
        component = self.get_component(view)

        if not self.permission_fields:
            return request.jwt_auth.has_auth(scopes_required, component)

        main_resource = self.get_main_resource()

        if view.action == "create":
            if view.__class__ is main_resource:
                main_object_data = request.data

            else:
                main_object_url = request.data[view.permission_main_object]
                main_object_path = urlparse(main_object_url).path
                try:
                    main_object = get_resource_for_path(main_object_path)
                except ObjectDoesNotExist:
                    raise ValidationError({
                        view.permission_main_object:
                        ValidationError(
                            _("The object does not exist in the database"),
                            code="object-does-not-exist",
                        ).detail
                    })
                except DjangoValidationError as exc:
                    err_dict = as_serializer_error(
                        ValidationError({view.permission_main_object: exc}))
                    raise ValidationError(err_dict)

                main_object_data = self.format_data(main_object, request)

            fields = self.get_fields(main_object_data)
            return request.jwt_auth.has_auth(scopes_required, component,
                                             **fields)

        # detect if this is an unsupported method - if it's a viewset and the
        # action was not mapped, it's not supported and DRF will catch it
        if view.action is None and isinstance(view, ViewSetMixin):
            return True

        # by default - check if the action is allowed at all
        return request.jwt_auth.has_auth(scopes_required, component)
示例#3
0
    def has_permission(self, request: Request, view) -> bool:
        if bypass_permissions(request):
            return True

        scopes_required = get_required_scopes(view)
        component = self.get_component(view)

        main_object = view._get_zaak()
        main_object_data = self.format_data(main_object, request)

        fields = self.get_fields(main_object_data)
        return request.jwt_auth.has_auth(scopes_required, component, **fields)
示例#4
0
    def has_object_permission(self, request: Request, view, obj) -> bool:
        if bypass_permissions(request):
            return True

        scopes_required = get_required_scopes(view)
        component = self.get_component(view)

        if not self.permission_fields:
            return request.jwt_auth.has_auth(scopes_required, component)

        main_resource = self.get_main_resource()

        if view.__class__ is main_resource:
            main_object = obj
        else:
            main_object = self.get_main_object(obj,
                                               view.permission_main_object)

        main_object_data = self.format_data(main_object, request)
        fields = self.get_fields(main_object_data)
        return request.jwt_auth.has_auth(scopes_required, component, **fields)
示例#5
0
    def get_security(self):
        """Return a list of security requirements for this operation.

        Returning an empty list marks the endpoint as unauthenticated (i.e. removes all accepted
        authentication schemes). Returning ``None`` will inherit the top-level secuirty requirements.

        :return: security requirements
        :rtype: list[dict[str,list[str]]]"""
        permissions = self.view.get_permissions()
        scope_permissions = [
            perm for perm in permissions if isinstance(perm, AuthRequired)
        ]

        if not scope_permissions:
            return super().get_security()

        if len(permissions) != len(scope_permissions):
            logger.warning(
                "Can't represent all permissions in OAS for path %s and method %s",
                self.path,
                self.method,
            )

        required_scopes = []
        for perm in scope_permissions:
            scopes = get_required_scopes(self.view)
            if scopes is None:
                continue
            required_scopes.append(scopes)

        if not required_scopes:
            return None  # use global security

        scopes = [str(scope) for scope in sorted(required_scopes)]

        # operation level security
        return [{settings.SECURITY_DEFINITION_NAME: scopes}]