1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Pleroma.Web.ApiSpec.CastAndValidate do
7 This plug is based on [`OpenApiSpex.Plug.CastAndValidate`]
8 (https://github.com/open-api-spex/open_api_spex/blob/master/lib/open_api_spex/plug/cast_and_validate.ex).
9 The main difference is ignoring unexpected query params
10 instead of throwing an error. Also, the default rendering
11 error module is `Pleroma.Web.ApiSpec.RenderError`.
22 |> Map.put_new(:render_error, Pleroma.Web.ApiSpec.RenderError)
26 def call(%{private: %{open_api_spex: private_data}} = conn, %{
27 operation_id: operation_id,
28 render_error: render_error
30 spec = private_data.spec
31 operation = private_data.operation_lookup[operation_id]
34 case Conn.get_req_header(conn, "content-type") do
44 private_data = Map.put(private_data, :operation_id, operation_id)
45 conn = Conn.put_private(conn, :open_api_spex, private_data)
47 case cast_and_validate(spec, operation, conn, content_type) do
52 opts = render_error.init(reason)
55 |> render_error.call(opts)
63 phoenix_controller: controller,
64 phoenix_action: action,
65 open_api_spex: private_data
71 case private_data.operation_lookup[{controller, action}] do
73 operation_id = controller.open_api_operation(action).operationId
74 operation = private_data.operation_lookup[operation_id]
77 private_data.operation_lookup
78 |> Map.put({controller, action}, operation)
80 OpenApiSpex.Plug.Cache.adapter().put(
81 private_data.spec_module,
82 {private_data.spec, operation_lookup}
91 if operation.operationId do
92 call(conn, Map.put(opts, :operation_id, operation.operationId))
94 raise "operationId was not found in action API spec"
98 def call(conn, opts), do: OpenApiSpex.Plug.CastAndValidate.call(conn, opts)
100 defp cast_and_validate(spec, operation, conn, content_type) do
101 case OpenApiSpex.cast_and_validate(spec, operation, conn, content_type) do
105 # Remove unexpected query params and cast/validate again
108 Enum.reduce(errors, conn.query_params, fn
109 %{reason: :unexpected_field, name: name, path: [name]}, params ->
110 Map.delete(params, name)
116 conn = %Conn{conn | query_params: query_params}
117 OpenApiSpex.cast_and_validate(spec, operation, conn, content_type)