X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;ds=inline;f=lib%2Fpleroma%2Fweb%2Fapi_spec%2Fcast_and_validate.ex;h=d23a7dcb6c4fd8b57fdd5cfc6f1d1c88e89290dd;hb=a079ec3a3cdfd42d2cbd51c7698c2c87828e5778;hp=f36cf7a5525f35289a2fe25915bcd35167b4b81f;hpb=d08c63500b5deca268ebc24833be4cb3279bdaaa;p=akkoma diff --git a/lib/pleroma/web/api_spec/cast_and_validate.ex b/lib/pleroma/web/api_spec/cast_and_validate.ex index f36cf7a55..d23a7dcb6 100644 --- a/lib/pleroma/web/api_spec/cast_and_validate.ex +++ b/lib/pleroma/web/api_spec/cast_and_validate.ex @@ -1,18 +1,21 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2020 Pleroma Authors +# Copyright © 2019-2020 Moxley Stratton, Mike Buhot , MPL-2.0 +# Copyright © 2017-2021 Pleroma Authors # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.ApiSpec.CastAndValidate do @moduledoc """ This plug is based on [`OpenApiSpex.Plug.CastAndValidate`] (https://github.com/open-api-spex/open_api_spex/blob/master/lib/open_api_spex/plug/cast_and_validate.ex). - The main difference is ignoring unexpected query params - instead of throwing an error. Also, the default rendering - error module is `Pleroma.Web.ApiSpec.RenderError`. + The main difference is ignoring unexpected query params instead of throwing + an error and a config option (`[Pleroma.Web.ApiSpec.CastAndValidate, :strict]`) + to disable this behavior. Also, the default rendering error module + is `Pleroma.Web.ApiSpec.RenderError`. """ @behaviour Plug + alias OpenApiSpex.Plug.PutApiSpec alias Plug.Conn @impl Plug @@ -23,12 +26,10 @@ defmodule Pleroma.Web.ApiSpec.CastAndValidate do end @impl Plug - def call(%{private: %{open_api_spex: private_data}} = conn, %{ - operation_id: operation_id, - render_error: render_error - }) do - spec = private_data.spec - operation = private_data.operation_lookup[operation_id] + + def call(conn, %{operation_id: operation_id, render_error: render_error}) do + {spec, operation_lookup} = PutApiSpec.get_spec_and_operation_lookup(conn) + operation = operation_lookup[operation_id] content_type = case Conn.get_req_header(conn, "content-type") do @@ -38,13 +39,12 @@ defmodule Pleroma.Web.ApiSpec.CastAndValidate do |> List.first() _ -> - nil + "application/json" end - private_data = Map.put(private_data, :operation_id, operation_id) - conn = Conn.put_private(conn, :open_api_spex, private_data) + conn = Conn.put_private(conn, :operation_id, operation_id) - case cast_and_validate(spec, operation, conn, content_type) do + case cast_and_validate(spec, operation, conn, content_type, strict?()) do {:ok, conn} -> conn @@ -62,25 +62,22 @@ defmodule Pleroma.Web.ApiSpec.CastAndValidate do private: %{ phoenix_controller: controller, phoenix_action: action, - open_api_spex: private_data + open_api_spex: %{spec_module: spec_module} } } = conn, opts ) do + {spec, operation_lookup} = PutApiSpec.get_spec_and_operation_lookup(conn) + operation = - case private_data.operation_lookup[{controller, action}] do + case operation_lookup[{controller, action}] do nil -> operation_id = controller.open_api_operation(action).operationId - operation = private_data.operation_lookup[operation_id] + operation = operation_lookup[operation_id] - operation_lookup = - private_data.operation_lookup - |> Map.put({controller, action}, operation) + operation_lookup = Map.put(operation_lookup, {controller, action}, operation) - OpenApiSpex.Plug.Cache.adapter().put( - private_data.spec_module, - {private_data.spec, operation_lookup} - ) + OpenApiSpex.Plug.Cache.adapter().put(spec_module, {spec, operation_lookup}) operation @@ -97,7 +94,11 @@ defmodule Pleroma.Web.ApiSpec.CastAndValidate do def call(conn, opts), do: OpenApiSpex.Plug.CastAndValidate.call(conn, opts) - defp cast_and_validate(spec, operation, conn, content_type) do + defp cast_and_validate(spec, operation, conn, content_type, true = _strict) do + OpenApiSpex.cast_and_validate(spec, operation, conn, content_type) + end + + defp cast_and_validate(spec, operation, conn, content_type, false = _strict) do case OpenApiSpex.cast_and_validate(spec, operation, conn, content_type) do {:ok, conn} -> {:ok, conn} @@ -109,6 +110,14 @@ defmodule Pleroma.Web.ApiSpec.CastAndValidate do %{reason: :unexpected_field, name: name, path: [name]}, params -> Map.delete(params, name) + # Filter out empty params + %{reason: :invalid_type, path: [name_atom], value: ""}, params -> + Map.delete(params, to_string(name_atom)) + + %{reason: :invalid_enum, name: nil, path: path, value: value}, params -> + path = path |> Enum.reverse() |> tl() |> Enum.reverse() |> list_items_to_string() + update_in(params, path, &List.delete(&1, value)) + _, params -> params end) @@ -117,4 +126,13 @@ defmodule Pleroma.Web.ApiSpec.CastAndValidate do OpenApiSpex.cast_and_validate(spec, operation, conn, content_type) end end + + defp list_items_to_string(list) do + Enum.map(list, fn + i when is_atom(i) -> to_string(i) + i -> i + end) + end + + defp strict?, do: Pleroma.Config.get([__MODULE__, :strict], false) end