Beispiel #1
0
    def get_default_responses(self):
        """Get the default responses determined for this view from the request serializer and request method.

        :type: dict[str, openapi.Schema]
        """
        ret = super().get_default_responses()

        # Figure out object (or model) name.
        if self.model:
            if hasattr(self.model._meta, 'verbose_name'):
                object_name = self.model._meta.verbose_name
            else:
                object_name = self.model.__name__
        else:
            object_name = 'Object'

        # Add additional response HTTP status codes.
        if self.view.permission_classes:
            if permissions.AllowAny not in self.view.permission_classes:
                ret[status.HTTP_403_FORBIDDEN] = 'Forbidden'
                if self.view.authentication_classes:
                    ret[status.HTTP_401_UNAUTHORIZED] = 'Unauthorized'

        if not is_list_view(
                self.path, self.method,
                self.view) and self.method.lower() in ('get', 'put', 'patch'):
            ret[status.HTTP_404_NOT_FOUND] = '{} not found'.format(object_name)

        return ret
Beispiel #2
0
    def get_response_serializers(self):
        responses = super().get_response_serializers()
        definitions = self.components.with_scope(openapi.SCHEMA_DEFINITIONS)
        definitions.setdefault(GENERIC_ERROR, self.get_generic_error_schema)
        definitions.setdefault(VALIDATION_ERROR, self.get_validation_error_schema)

        if self.get_request_serializer():
            responses.setdefault(exceptions.ValidationError.status_code, openapi.Response(
                description=force_real_str(exceptions.ValidationError.default_detail),
                schema=openapi.SchemaRef(definitions, VALIDATION_ERROR)
            ))

        security = self.get_security()
        if (not security or len(security) > 0) and AllowAny not in self.view.permission_classes:
            responses.setdefault(status.HTTP_401_UNAUTHORIZED, openapi.Response(
                description="Authentication credentials were not provided.",
                schema=openapi.SchemaRef(definitions, GENERIC_ERROR)
            ))
            responses.setdefault(exceptions.PermissionDenied.status_code, openapi.Response(
                description="Permission denied.",
                schema=openapi.SchemaRef(definitions, GENERIC_ERROR)
            ))

        if not is_list_view(self.path, self.method, self.view) or '{' in self.path:
            responses.setdefault(exceptions.NotFound.status_code, openapi.Response(
                description="Not found.",
                schema=openapi.SchemaRef(definitions, GENERIC_ERROR)
            ))

        return responses
Beispiel #3
0
    def get_default_responses(self):
        """Get the default responses determined for this view from the request serializer and request method.

        :type: dict[str, openapi.Schema]
        """
        method = self.method.lower()

        default_status = guess_response_status(method)
        default_schema = ''
        if method in ('get', 'post', 'put', 'patch'):
            default_schema = self.get_default_response_serializer()

        default_schema = default_schema or ''
        if default_schema and not isinstance(default_schema, openapi.Schema):
            default_schema = self.serializer_to_schema(default_schema) or ''

        if default_schema:
            if (is_list_view(self.path, self.method, self.view) and self.method.lower() == 'get') \
                    or is_bulk_view(self.path, self.method, self.view):
                default_schema = openapi.Schema(type=openapi.TYPE_ARRAY,
                                                items=default_schema)
            if self.should_page():
                default_schema = self.get_paginated_response(
                    default_schema) or default_schema

        return OrderedDict({str(default_status): default_schema})
Beispiel #4
0
    def get_default_responses(self):
        """Get the default responses determined for this view from the request serializer and
        request method.

        :type: dict[str, openapi.Schema]
        """
        method = self.method.lower()

        default_status = guess_response_status(method)
        default_schema = ''
        if method in ('get', 'post', 'put', 'patch'):
            default_schema = self.get_default_response_serializer()

        default_schema = default_schema or ''

        if default_schema and not isinstance(default_schema, openapi.Schema):
            default_schema = self.serializer_to_schema(default_schema) or ''

        if default_schema:
            if is_list_view(self.path, self.method, self.view) and self.method.lower() == 'get':
                default_schema = openapi.Schema(type=openapi.TYPE_ARRAY, items=default_schema)
            if self.should_page():
                default_schema = self.get_paginated_response(default_schema) or default_schema

        return OrderedDict({str(default_status): default_schema})
Beispiel #5
0
    def get_default_response_data(self, default_serializer):
        default_data_schema = ''
        if default_serializer and not isinstance(default_serializer, openapi.Schema):
            default_data_schema = self.serializer_to_schema(default_serializer) or ''

        if is_list_view(self.path, self.method, self.view) and self.method.lower() == 'get':
            default_data_schema = openapi.Schema(type=openapi.TYPE_ARRAY, items=default_data_schema)

        return default_data_schema
Beispiel #6
0
    def is_list(self):
        """
        Determines if this is a GET list view, and returns a boolean

        :param drf_jsonapi.inspectors.SwaggerAutoSchema self: This object
        :returns: true if this is a list
        :rtype: boolean
        """

        if self.method.lower() != 'get':
            return False

        return is_list_view(self.path, self.method, self.view)
Beispiel #7
0
    def get_response_serializers(self):
        responses = super().get_response_serializers()
        definitions = self.components.with_scope(
            openapi.SCHEMA_DEFINITIONS)  # type: openapi.ReferenceResolver

        definitions.setdefault("GenericError", self.get_generic_error_schema)
        definitions.setdefault("ValidationError",
                               self.get_validation_error_schema)
        definitions.setdefault("APIException", self.get_generic_error_schema)

        if self.get_request_serializer() or self.get_query_serializer():
            responses.setdefault(
                exceptions.ValidationError.status_code,
                openapi.Response(
                    description=force_real_str(
                        exceptions.ValidationError.default_detail),
                    schema=openapi.SchemaRef(definitions, "ValidationError"),
                ),
            )

        security = self.get_security()
        if security is None or len(security) > 0:
            # Note: 401 error codes are coerced  into 403 see
            # rest_framework/views.py:433:handle_exception
            # This is b/c the API uses token auth which doesn't have WWW-Authenticate header
            responses.setdefault(
                status.HTTP_403_FORBIDDEN,
                openapi.Response(
                    description=
                    "Authentication credentials were invalid, absent or insufficient.",
                    schema=openapi.SchemaRef(definitions, "GenericError"),
                ),
            )
        if not is_list_view(self.path, self.method, self.view):
            responses.setdefault(
                exceptions.PermissionDenied.status_code,
                openapi.Response(
                    description="Permission denied.",
                    schema=openapi.SchemaRef(definitions, "APIException"),
                ),
            )
            responses.setdefault(
                exceptions.NotFound.status_code,
                openapi.Response(
                    description=("Object does not exist or caller "
                                 "has insufficient permissions to access it."),
                    schema=openapi.SchemaRef(definitions, "APIException"),
                ),
            )

        return responses
Beispiel #8
0
    def should_filter(self):
        """Determine whether filter backend parameters should be included for this request.

        :rtype: bool
        """
        if not getattr(self.view, 'filter_backends', None):
            return False

        if getattr(self.view, 'action', '') in ('bulk_destroy', ):
            return False

        if self.method.lower() not in ["get", "delete"]:
            return False

        return is_list_view(self.path, self.method, self.view)
Beispiel #9
0
    def get_operation_keys(self, subpath, method, view):
        """Return a list of keys that should be used to group an operation within the specification. ::

          /users/                   ("users", "list"), ("users", "create")
          /users/{pk}/              ("users", "read"), ("users", "update"), ("users", "delete")
          /users/enabled/           ("users", "enabled")  # custom viewset list action
          /users/{pk}/star/         ("users", "star")     # custom viewset detail action
          /users/{pk}/groups/       ("users", "groups", "list"), ("users", "groups", "create")
          /users/{pk}/groups/{pk}/  ("users", "groups", "read"), ("users", "groups", "update")

        :param str subpath: path to the operation with any common prefix/base path removed
        :param str method: HTTP method
        :param view: the view associated with the operation
        :rtype: tuple
        """
        if hasattr(view, 'action'):
            # Viewsets have explicitly named actions.
            action = view.action
        else:
            # Views have no associated action, so we determine one from the method.
            if is_list_view(subpath, method, view):
                action = 'list'
            else:
                action = self._gen.default_mapping[method.lower()]

        named_path_components = [
            component for component in subpath.strip('/').split('/')
            if '{' not in component
        ]

        if is_custom_action(action):
            # Custom action, eg "/users/{pk}/activate/", "/users/active/"
            if len(view.action_map) > 1:
                if not action.startswith(('bulk', 'partial_bulk')):
                    action = self._gen.default_mapping[method.lower()]

                if action in self._gen.coerce_method_names:
                    action = self._gen.coerce_method_names[action]

                return named_path_components + [action]
            else:
                return named_path_components[:-1] + [action]

        if action in self._gen.coerce_method_names:
            action = self._gen.coerce_method_names[action]

        # Default action, eg "/users/", "/users/{pk}/"
        return named_path_components + [action]
Beispiel #10
0
    def is_list(self):
        """
        Determines if this is a GET list view, and returns a boolean

        :param drf_jsonapi.inspectors.SwaggerAutoSchema self: This object
        :returns: true if this is a list
        :rtype: boolean
        """

        if self.relationship:
            handler = self.view.get_relationship_handler(self.relationship)
            return handler.many

        if self.method.lower() != "get":
            return False
        return is_list_view(self.path, self.method, self.view)
    def get_response_serializers(self):
        responses = super().get_response_serializers()
        definitions = self.components.with_scope(
            openapi.SCHEMA_DEFINITIONS)  # type: openapi.ReferenceResolver

        definitions.setdefault('GenericError', self.get_generic_error_schema)
        definitions.setdefault('ValidationError',
                               self.get_validation_error_schema)
        definitions.setdefault('APIException', self.get_generic_error_schema)

        if self.get_request_serializer() or self.get_query_serializer():
            responses.setdefault(
                exceptions.ValidationError.status_code,
                openapi.Response(description=force_real_str(
                    exceptions.ValidationError.default_detail),
                                 schema=openapi.SchemaRef(
                                     definitions, 'ValidationError')))

        authenticators = self.view.get_authenticators()
        if authenticators and len(authenticators) > 0:
            responses.setdefault(
                exceptions.AuthenticationFailed.status_code,
                openapi.Response(
                    description=
                    "Authentication credentials were invalid, absent or insufficient.",
                    schema=openapi.SchemaRef(definitions, 'GenericError')))
        if not is_list_view(self.path, self.method, self.view):
            responses.setdefault(
                exceptions.PermissionDenied.status_code,
                openapi.Response(description="Permission denied.",
                                 schema=openapi.SchemaRef(
                                     definitions, 'APIException')))
            responses.setdefault(
                exceptions.NotFound.status_code,
                openapi.Response(
                    description=
                    "Object does not exist or caller has insufficient permissions to access it.",
                    schema=openapi.SchemaRef(definitions, 'APIException')))

        return responses
Beispiel #12
0
def is_bulk_view(path, method, view):
    if not is_list_view(path, method, view):
        return False

    return hasattr(view, 'action') and view.action.startswith(
        ('bulk', 'partial_bulk'))