Ignore unexpected query params
This commit is contained in:
parent
378ab2db97
commit
d08c63500b
120
lib/pleroma/web/api_spec/cast_and_validate.ex
Normal file
120
lib/pleroma/web/api_spec/cast_and_validate.ex
Normal file
|
@ -0,0 +1,120 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 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`.
|
||||
"""
|
||||
|
||||
@behaviour Plug
|
||||
|
||||
alias Plug.Conn
|
||||
|
||||
@impl Plug
|
||||
def init(opts) do
|
||||
opts
|
||||
|> Map.new()
|
||||
|> Map.put_new(:render_error, Pleroma.Web.ApiSpec.RenderError)
|
||||
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]
|
||||
|
||||
content_type =
|
||||
case Conn.get_req_header(conn, "content-type") do
|
||||
[header_value | _] ->
|
||||
header_value
|
||||
|> String.split(";")
|
||||
|> List.first()
|
||||
|
||||
_ ->
|
||||
nil
|
||||
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
|
||||
{:ok, conn} ->
|
||||
conn
|
||||
|
||||
{:error, reason} ->
|
||||
opts = render_error.init(reason)
|
||||
|
||||
conn
|
||||
|> render_error.call(opts)
|
||||
|> Plug.Conn.halt()
|
||||
end
|
||||
end
|
||||
|
||||
def call(
|
||||
%{
|
||||
private: %{
|
||||
phoenix_controller: controller,
|
||||
phoenix_action: action,
|
||||
open_api_spex: private_data
|
||||
}
|
||||
} = conn,
|
||||
opts
|
||||
) do
|
||||
operation =
|
||||
case private_data.operation_lookup[{controller, action}] do
|
||||
nil ->
|
||||
operation_id = controller.open_api_operation(action).operationId
|
||||
operation = private_data.operation_lookup[operation_id]
|
||||
|
||||
operation_lookup =
|
||||
private_data.operation_lookup
|
||||
|> Map.put({controller, action}, operation)
|
||||
|
||||
OpenApiSpex.Plug.Cache.adapter().put(
|
||||
private_data.spec_module,
|
||||
{private_data.spec, operation_lookup}
|
||||
)
|
||||
|
||||
operation
|
||||
|
||||
operation ->
|
||||
operation
|
||||
end
|
||||
|
||||
if operation.operationId do
|
||||
call(conn, Map.put(opts, :operation_id, operation.operationId))
|
||||
else
|
||||
raise "operationId was not found in action API spec"
|
||||
end
|
||||
end
|
||||
|
||||
def call(conn, opts), do: OpenApiSpex.Plug.CastAndValidate.call(conn, opts)
|
||||
|
||||
defp cast_and_validate(spec, operation, conn, content_type) do
|
||||
case OpenApiSpex.cast_and_validate(spec, operation, conn, content_type) do
|
||||
{:ok, conn} ->
|
||||
{:ok, conn}
|
||||
|
||||
# Remove unexpected query params and cast/validate again
|
||||
{:error, errors} ->
|
||||
query_params =
|
||||
Enum.reduce(errors, conn.query_params, fn
|
||||
%{reason: :unexpected_field, name: name, path: [name]}, params ->
|
||||
Map.delete(params, name)
|
||||
|
||||
_, params ->
|
||||
params
|
||||
end)
|
||||
|
||||
conn = %Conn{conn | query_params: query_params}
|
||||
OpenApiSpex.cast_and_validate(spec, operation, conn, content_type)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -27,7 +27,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
|
|||
alias Pleroma.Web.OAuth.Token
|
||||
alias Pleroma.Web.TwitterAPI.TwitterAPI
|
||||
|
||||
plug(OpenApiSpex.Plug.CastAndValidate, render_error: Pleroma.Web.ApiSpec.RenderError)
|
||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
||||
|
||||
plug(:skip_plug, [OAuthScopesPlug, EnsurePublicOrAuthenticatedPlug] when action == :create)
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ defmodule Pleroma.Web.MastodonAPI.AppController do
|
|||
|
||||
plug(OAuthScopesPlug, %{scopes: ["read"]} when action == :verify_credentials)
|
||||
|
||||
plug(OpenApiSpex.Plug.CastAndValidate)
|
||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
||||
|
||||
@local_mastodon_name "Mastodon-Local"
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
defmodule Pleroma.Web.MastodonAPI.CustomEmojiController do
|
||||
use Pleroma.Web, :controller
|
||||
|
||||
plug(OpenApiSpex.Plug.CastAndValidate)
|
||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
||||
|
||||
plug(
|
||||
:skip_plug,
|
||||
|
|
|
@ -8,7 +8,7 @@ defmodule Pleroma.Web.MastodonAPI.DomainBlockController do
|
|||
alias Pleroma.Plugs.OAuthScopesPlug
|
||||
alias Pleroma.User
|
||||
|
||||
plug(OpenApiSpex.Plug.CastAndValidate)
|
||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
||||
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.DomainBlockOperation
|
||||
|
||||
plug(
|
||||
|
|
|
@ -13,7 +13,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationController do
|
|||
|
||||
@oauth_read_actions [:show, :index]
|
||||
|
||||
plug(OpenApiSpex.Plug.CastAndValidate, render_error: Pleroma.Web.ApiSpec.RenderError)
|
||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
||||
|
||||
plug(
|
||||
OAuthScopesPlug,
|
||||
|
|
|
@ -9,7 +9,7 @@ defmodule Pleroma.Web.MastodonAPI.ReportController do
|
|||
|
||||
action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
|
||||
|
||||
plug(OpenApiSpex.Plug.CastAndValidate, render_error: Pleroma.Web.ApiSpec.RenderError)
|
||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
||||
plug(OAuthScopesPlug, %{scopes: ["write:reports"]} when action == :create)
|
||||
|
||||
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.ReportOperation
|
||||
|
|
Loading…
Reference in a new issue