make 2fa UI less awful
[akkoma] / lib / pleroma / web / api_spec / cast_and_validate.ex
index fbfc27d6f7655cd3efe38556c9e3c706421a6081..d23a7dcb6c4fd8b57fdd5cfc6f1d1c88e89290dd 100644 (file)
@@ -1,6 +1,6 @@
 # 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
@@ -15,6 +15,7 @@ defmodule Pleroma.Web.ApiSpec.CastAndValidate do
 
   @behaviour Plug
 
+  alias OpenApiSpex.Plug.PutApiSpec
   alias Plug.Conn
 
   @impl Plug
@@ -25,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
@@ -43,8 +42,7 @@ defmodule Pleroma.Web.ApiSpec.CastAndValidate do
           "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, strict?()) do
       {:ok, conn} ->
@@ -64,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
 
@@ -115,6 +110,10 @@ 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))