Harden webhook API input
This commit is contained in:
parent
27090ad7e6
commit
ab634a4aa3
3 changed files with 64 additions and 8 deletions
|
|
@ -40,14 +40,14 @@ defmodule Pleroma.Web.AdminAPI.WebhookController do
|
||||||
end
|
end
|
||||||
|
|
||||||
def create(%{body_params: params} = conn, _) do
|
def create(%{body_params: params} = conn, _) do
|
||||||
with {:ok, webhook} <- Webhook.create(params) do
|
with {:ok, webhook} <- Webhook.create(webhook_params(params)) do
|
||||||
render(conn, "show.json", webhook: webhook)
|
render(conn, "show.json", webhook: webhook)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def update(%{body_params: params} = conn, %{id: id}) do
|
def update(%{body_params: params} = conn, %{id: id}) do
|
||||||
with %Webhook{internal: false} = webhook <- Webhook.get(id),
|
with %Webhook{internal: false} = webhook <- Webhook.get(id),
|
||||||
{:ok, webhook} <- Webhook.update(webhook, params) do
|
{:ok, webhook} <- Webhook.update(webhook, webhook_params(params)) do
|
||||||
render(conn, "show.json", webhook: webhook)
|
render(conn, "show.json", webhook: webhook)
|
||||||
else
|
else
|
||||||
%Webhook{internal: true} -> {:error, :forbidden}
|
%Webhook{internal: true} -> {:error, :forbidden}
|
||||||
|
|
@ -94,4 +94,8 @@ defmodule Pleroma.Web.AdminAPI.WebhookController do
|
||||||
nil -> {:error, :not_found}
|
nil -> {:error, :not_found}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp webhook_params(params) do
|
||||||
|
Map.drop(params, [:internal, "internal"])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -58,9 +58,10 @@ defmodule Pleroma.Web.ApiSpec.Admin.WebhookOperation do
|
||||||
required: [:url, :events],
|
required: [:url, :events],
|
||||||
properties: %{
|
properties: %{
|
||||||
url: %Schema{type: :string, format: :uri},
|
url: %Schema{type: :string, format: :uri},
|
||||||
events: event_type(),
|
events: event_type(min_items: 1),
|
||||||
enabled: %Schema{type: :boolean}
|
enabled: %Schema{type: :boolean}
|
||||||
}
|
},
|
||||||
|
additionalProperties: false
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
responses: %{
|
responses: %{
|
||||||
|
|
@ -84,9 +85,10 @@ defmodule Pleroma.Web.ApiSpec.Admin.WebhookOperation do
|
||||||
type: :object,
|
type: :object,
|
||||||
properties: %{
|
properties: %{
|
||||||
url: %Schema{type: :string, format: :uri},
|
url: %Schema{type: :string, format: :uri},
|
||||||
events: event_type(),
|
events: event_type(min_items: 1),
|
||||||
enabled: %Schema{type: :boolean}
|
enabled: %Schema{type: :boolean}
|
||||||
}
|
},
|
||||||
|
additionalProperties: false
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
responses: %{
|
responses: %{
|
||||||
|
|
@ -180,8 +182,8 @@ defmodule Pleroma.Web.ApiSpec.Admin.WebhookOperation do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp event_type do
|
defp event_type(opts \\ []) do
|
||||||
%Schema{
|
schema = %Schema{
|
||||||
type: :array,
|
type: :array,
|
||||||
items: %Schema{
|
items: %Schema{
|
||||||
title: "Event",
|
title: "Event",
|
||||||
|
|
@ -190,6 +192,11 @@ defmodule Pleroma.Web.ApiSpec.Admin.WebhookOperation do
|
||||||
enum: ["account.created", "report.created"]
|
enum: ["account.created", "report.created"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Keyword.fetch(opts, :min_items) do
|
||||||
|
{:ok, min_items} -> %{schema | minItems: min_items}
|
||||||
|
:error -> schema
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp id_param do
|
defp id_param do
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,27 @@ defmodule Pleroma.Web.AdminAPI.WebhookControllerTest do
|
||||||
|
|
||||||
assert %{url: "http://example.com/webhook", events: [:"account.created"]} = Webhook.get(id)
|
assert %{url: "http://example.com/webhook", events: [:"account.created"]} = Webhook.get(id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "rejects empty events", %{conn: conn} do
|
||||||
|
conn
|
||||||
|
|> put_req_header("content-type", "application/json")
|
||||||
|
|> post("/api/pleroma/admin/webhooks", %{
|
||||||
|
url: "http://example.com/webhook",
|
||||||
|
events: []
|
||||||
|
})
|
||||||
|
|> json_response(:bad_request)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "rejects internal flag", %{conn: conn} do
|
||||||
|
conn
|
||||||
|
|> put_req_header("content-type", "application/json")
|
||||||
|
|> post("/api/pleroma/admin/webhooks", %{
|
||||||
|
url: "http://example.com/webhook",
|
||||||
|
events: ["account.created"],
|
||||||
|
internal: true
|
||||||
|
})
|
||||||
|
|> json_response(:bad_request)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "PATCH /api/pleroma/admin/webhooks" do
|
describe "PATCH /api/pleroma/admin/webhooks" do
|
||||||
|
|
@ -78,6 +99,30 @@ defmodule Pleroma.Web.AdminAPI.WebhookControllerTest do
|
||||||
assert %{events: [:"report.created", :"account.created"]} = Webhook.get(id)
|
assert %{events: [:"report.created", :"account.created"]} = Webhook.get(id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "rejects empty events", %{conn: conn} do
|
||||||
|
{:ok, %{id: id}} =
|
||||||
|
Webhook.create(%{url: "https://example.com/webhook1", events: [:"report.created"]})
|
||||||
|
|
||||||
|
conn
|
||||||
|
|> put_req_header("content-type", "application/json")
|
||||||
|
|> patch("/api/pleroma/admin/webhooks/#{id}", %{events: []})
|
||||||
|
|> json_response(:bad_request)
|
||||||
|
|
||||||
|
assert %{events: [:"report.created"]} = Webhook.get(id)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "rejects internal flag", %{conn: conn} do
|
||||||
|
{:ok, %{id: id}} =
|
||||||
|
Webhook.create(%{url: "https://example.com/webhook1", events: [:"report.created"]})
|
||||||
|
|
||||||
|
conn
|
||||||
|
|> put_req_header("content-type", "application/json")
|
||||||
|
|> patch("/api/pleroma/admin/webhooks/#{id}", %{internal: true})
|
||||||
|
|> json_response(:bad_request)
|
||||||
|
|
||||||
|
assert %{internal: false} = Webhook.get(id)
|
||||||
|
end
|
||||||
|
|
||||||
test "can't edit an internal webhook", %{conn: conn} do
|
test "can't edit an internal webhook", %{conn: conn} do
|
||||||
{:ok, %{id: id}} =
|
{:ok, %{id: id}} =
|
||||||
Webhook.create(%{url: "https://example.com/webhook1", events: [], internal: true})
|
Webhook.create(%{url: "https://example.com/webhook1", events: [], internal: true})
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue