Add internal (not managable from API) webhooks
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
parent
ad014adc1c
commit
1b9b03b494
7 changed files with 62 additions and 12 deletions
|
@ -11,6 +11,12 @@ def call(conn, {:error, :not_found}) do
|
|||
|> json(%{error: dgettext("errors", "Not found")})
|
||||
end
|
||||
|
||||
def call(conn, {:error, :forbidden}) do
|
||||
conn
|
||||
|> put_status(:forbidden)
|
||||
|> json(%{error: dgettext("errors", "Forbidden")})
|
||||
end
|
||||
|
||||
def call(conn, {:error, reason}) do
|
||||
conn
|
||||
|> put_status(:bad_request)
|
||||
|
|
|
@ -46,42 +46,49 @@ def create(%{body_params: params} = conn, _) do
|
|||
end
|
||||
|
||||
def update(%{body_params: params} = conn, %{id: id}) do
|
||||
with %Webhook{} = webhook <- Webhook.get(id),
|
||||
with %Webhook{internal: false} = webhook <- Webhook.get(id),
|
||||
webhook <- Webhook.update(webhook, params) do
|
||||
render(conn, "show.json", webhook: webhook)
|
||||
else
|
||||
%Webhook{internal: true} -> {:error, :forbidden}
|
||||
end
|
||||
end
|
||||
|
||||
def delete(conn, %{id: id}) do
|
||||
with %Webhook{} = webhook <- Webhook.get(id),
|
||||
with %Webhook{internal: false} = webhook <- Webhook.get(id),
|
||||
{:ok, webhook} <- Webhook.delete(webhook) do
|
||||
render(conn, "show.json", webhook: webhook)
|
||||
else
|
||||
%Webhook{internal: true} -> {:error, :forbidden}
|
||||
end
|
||||
end
|
||||
|
||||
def enable(conn, %{id: id}) do
|
||||
with %Webhook{} = webhook <- Webhook.get(id),
|
||||
with %Webhook{internal: false} = webhook <- Webhook.get(id),
|
||||
{:ok, webhook} <- Webhook.set_enabled(webhook, true) do
|
||||
render(conn, "show.json", webhook: webhook)
|
||||
else
|
||||
%Webhook{internal: true} -> {:error, :forbidden}
|
||||
nil -> {:error, :not_found}
|
||||
end
|
||||
end
|
||||
|
||||
def disable(conn, %{id: id}) do
|
||||
with %Webhook{} = webhook <- Webhook.get(id),
|
||||
with %Webhook{internal: false} = webhook <- Webhook.get(id),
|
||||
{:ok, webhook} <- Webhook.set_enabled(webhook, false) do
|
||||
render(conn, "show.json", webhook: webhook)
|
||||
else
|
||||
%Webhook{internal: true} -> {:error, :forbidden}
|
||||
nil -> {:error, :not_found}
|
||||
end
|
||||
end
|
||||
|
||||
def rotate_secret(conn, %{id: id}) do
|
||||
with %Webhook{} = webhook <- Webhook.get(id),
|
||||
with %Webhook{internal: false} = webhook <- Webhook.get(id),
|
||||
{:ok, webhook} <- Webhook.rotate_secret(webhook) do
|
||||
render(conn, "show.json", webhook: webhook)
|
||||
else
|
||||
%Webhook{internal: true} -> {:error, :forbidden}
|
||||
nil -> {:error, :not_found}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,6 +18,7 @@ def render("show.json", %{webhook: webhook}) do
|
|||
events: webhook.events,
|
||||
secret: webhook.secret,
|
||||
enabled: webhook.enabled,
|
||||
internal: webhook.internal,
|
||||
created_at: Utils.to_masto_date(webhook.inserted_at),
|
||||
updated_at: Utils.to_masto_date(webhook.updated_at)
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
defmodule Pleroma.Web.ApiSpec.Admin.WebhookOperation do
|
||||
alias OpenApiSpex.Operation
|
||||
alias OpenApiSpex.Schema
|
||||
alias Pleroma.Web.ApiSpec.Schemas.ApiError
|
||||
|
||||
import Pleroma.Web.ApiSpec.Helpers
|
||||
|
||||
|
@ -88,7 +89,8 @@ def update_operation do
|
|||
}
|
||||
),
|
||||
responses: %{
|
||||
200 => Operation.response("Webhook", "application/json", webhook())
|
||||
200 => Operation.response("Webhook", "application/json", webhook()),
|
||||
403 => Operation.response("Forbidden", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
@ -101,7 +103,8 @@ def delete_operation do
|
|||
security: [%{"oAuth" => ["admin:write"]}],
|
||||
parameters: [id_param()],
|
||||
responses: %{
|
||||
200 => Operation.response("Webhook", "application/json", webhook())
|
||||
200 => Operation.response("Webhook", "application/json", webhook()),
|
||||
403 => Operation.response("Forbidden", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
@ -114,7 +117,8 @@ def enable_operation do
|
|||
security: [%{"oAuth" => ["admin:write"]}],
|
||||
parameters: [id_param()],
|
||||
responses: %{
|
||||
200 => Operation.response("Webhook", "application/json", webhook())
|
||||
200 => Operation.response("Webhook", "application/json", webhook()),
|
||||
403 => Operation.response("Forbidden", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
@ -127,7 +131,8 @@ def disable_operation do
|
|||
security: [%{"oAuth" => ["admin:write"]}],
|
||||
parameters: [id_param()],
|
||||
responses: %{
|
||||
200 => Operation.response("Webhook", "application/json", webhook())
|
||||
200 => Operation.response("Webhook", "application/json", webhook()),
|
||||
403 => Operation.response("Forbidden", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
@ -140,7 +145,8 @@ def rotate_secret_operation do
|
|||
security: [%{"oAuth" => ["admin:write"]}],
|
||||
parameters: [id_param()],
|
||||
responses: %{
|
||||
200 => Operation.response("Webhook", "application/json", webhook())
|
||||
200 => Operation.response("Webhook", "application/json", webhook()),
|
||||
403 => Operation.response("Forbidden", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
@ -156,6 +162,7 @@ defp webhook do
|
|||
events: event_type(),
|
||||
secret: %Schema{type: :string},
|
||||
enabled: %Schema{type: :boolean},
|
||||
internal: %Schema{type: :boolean},
|
||||
created_at: %Schema{type: :string, format: :"date-time"},
|
||||
updated_at: %Schema{type: :string, format: :"date-time"}
|
||||
},
|
||||
|
@ -165,6 +172,7 @@ defp webhook do
|
|||
"events" => ["report.created"],
|
||||
"secret" => "D3D8CF4BC11FD9C41FD34DCC38D282E451C8BD34",
|
||||
"enabled" => true,
|
||||
"internal" => false,
|
||||
"created_at" => "2022-06-24T16:19:38.523Z",
|
||||
"updated_at" => "2022-06-24T16:19:38.523Z"
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ defmodule Pleroma.Webhook do
|
|||
field(:events, {:array, Ecto.Enum}, values: @event_types, null: false, default: [])
|
||||
field(:secret, :string, null: false, default: "")
|
||||
field(:enabled, :boolean, null: false, default: true)
|
||||
field(:internal, :boolean, null: false, default: false)
|
||||
|
||||
timestamps()
|
||||
end
|
||||
|
@ -32,7 +33,7 @@ def get_by_type(type) do
|
|||
|
||||
def changeset(%__MODULE__{} = webhook, params) do
|
||||
webhook
|
||||
|> cast(params, [:url, :events, :enabled])
|
||||
|> cast(params, [:url, :events, :enabled, :internal])
|
||||
|> validate_required([:url, :events])
|
||||
|> unique_constraint(:url)
|
||||
|> strip_events()
|
||||
|
@ -41,7 +42,7 @@ def changeset(%__MODULE__{} = webhook, params) do
|
|||
|
||||
def update_changeset(%__MODULE__{} = webhook, params \\ %{}) do
|
||||
webhook
|
||||
|> cast(params, [:url, :events, :enabled])
|
||||
|> cast(params, [:url, :events, :enabled, :internal])
|
||||
|> unique_constraint(:url)
|
||||
|> strip_events()
|
||||
end
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Repo.Migrations.AddInternalToWebhooks do
|
||||
use Ecto.Migration
|
||||
|
||||
def change do
|
||||
alter table(:webhooks) do
|
||||
add(:internal, :boolean, default: false, null: false)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -64,6 +64,20 @@ test "edits a webhook", %{conn: conn} do
|
|||
|
||||
assert %{events: [:"report.created", :"account.created"]} = Webhook.get(id)
|
||||
end
|
||||
|
||||
test "can't edit an internal webhook", %{conn: conn} do
|
||||
%{id: id} =
|
||||
Webhook.create(%{url: "https://example.com/webhook1", events: [], internal: true})
|
||||
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> patch("/api/pleroma/admin/webhooks/#{id}", %{
|
||||
events: ["report.created", "account.created"]
|
||||
})
|
||||
|> json_response_and_validate_schema(:forbidden)
|
||||
|
||||
assert %{events: []} = Webhook.get(id)
|
||||
end
|
||||
end
|
||||
|
||||
describe "DELETE /api/pleroma/admin/webhooks" do
|
||||
|
|
Loading…
Reference in a new issue