fix for unique oban worker option
[akkoma] / lib / pleroma / web / api_spec / cast_and_validate.ex
index cd02403c18795f5213ab51b686fe0c5e755ab645..a3da856fface8516304ade068d3b43453a59c765 100644 (file)
@@ -1,15 +1,16 @@
 # Pleroma: A lightweight social networking server
 # Copyright © 2019-2020 Moxley Stratton, Mike Buhot <https://github.com/open-api-spex/open_api_spex>, MPL-2.0
-# Copyright © 2020 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
 # 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
@@ -39,13 +40,13 @@ 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)
 
-    case cast_and_validate(spec, operation, conn, content_type) do
+    case cast_and_validate(spec, operation, conn, content_type, strict?()) do
       {:ok, conn} ->
         conn
 
@@ -98,7 +99,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}
@@ -110,6 +115,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)
@@ -118,4 +131,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