diff --git a/changelog.d/instance-domain-blocks.add b/changelog.d/instance-domain-blocks.add new file mode 100644 index 000000000..85f01c5c2 --- /dev/null +++ b/changelog.d/instance-domain-blocks.add @@ -0,0 +1 @@ +Add v1/instance/domain_blocks endpoint diff --git a/lib/pleroma/web/api_spec/operations/instance_operation.ex b/lib/pleroma/web/api_spec/operations/instance_operation.ex index 911ffb994..d8b2901d3 100644 --- a/lib/pleroma/web/api_spec/operations/instance_operation.ex +++ b/lib/pleroma/web/api_spec/operations/instance_operation.ex @@ -57,6 +57,22 @@ defmodule Pleroma.Web.ApiSpec.InstanceOperation do } end + def domain_blocks_operation do + %Operation{ + tags: ["Instance misc"], + summary: "Retrieve instance domain blocks", + operationId: "InstanceController.domain_blocks", + responses: %{ + 200 => + Operation.response( + "Array of domain blocks", + "application/json", + array_of_domain_blocks() + ) + } + } + end + def translation_languages_operation do %Operation{ tags: ["Instance misc"], @@ -420,4 +436,19 @@ defmodule Pleroma.Web.ApiSpec.InstanceOperation do } } end + + defp array_of_domain_blocks do + %Schema{ + type: :array, + items: %Schema{ + type: :object, + properties: %{ + domain: %Schema{type: :string}, + digest: %Schema{type: :string}, + severity: %Schema{type: :string}, + comment: %Schema{type: :string} + } + } + } + end end diff --git a/lib/pleroma/web/mastodon_api/controllers/instance_controller.ex b/lib/pleroma/web/mastodon_api/controllers/instance_controller.ex index 0f74c1dff..cf5bbf16e 100644 --- a/lib/pleroma/web/mastodon_api/controllers/instance_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/instance_controller.ex @@ -7,7 +7,7 @@ defmodule Pleroma.Web.MastodonAPI.InstanceController do plug(Pleroma.Web.ApiSpec.CastAndValidate) - plug(:skip_auth when action in [:show, :show2, :peers]) + plug(:skip_auth) defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.InstanceOperation @@ -31,6 +31,11 @@ defmodule Pleroma.Web.MastodonAPI.InstanceController do render(conn, "rules.json") end + @doc "GET /api/v1/instance/domain_blocks" + def domain_blocks(conn, _params) do + render(conn, "domain_blocks.json") + end + @doc "GET /api/v1/instance/translation_languages" def translation_languages(conn, _params) do render(conn, "translation_languages.json") diff --git a/lib/pleroma/web/mastodon_api/views/instance_view.ex b/lib/pleroma/web/mastodon_api/views/instance_view.ex index b21383659..75a391bd0 100644 --- a/lib/pleroma/web/mastodon_api/views/instance_view.ex +++ b/lib/pleroma/web/mastodon_api/views/instance_view.ex @@ -5,11 +5,18 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do use Pleroma.Web, :view + import Pleroma.Web.Utils.Guards, only: [not_empty_string: 1] + alias Pleroma.Config alias Pleroma.Web.ActivityPub.MRF @mastodon_api_level "2.7.2" + @block_severities %{ + federated_timeline_removal: "silence", + reject: "suspend" + } + def render("show.json", _) do instance = Config.get(:instance) @@ -90,6 +97,48 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do } end + def render("domain_blocks.json", _) do + if Config.get([:mrf, :transparency]) do + exclusions = Config.get([:mrf, :transparency_exclusions]) |> MRF.instance_list_from_tuples() + + domain_blocks = + Config.get(:mrf_simple) + |> Enum.map(fn {rule, instances} -> + instances + |> Enum.map(fn + {host, reason} when not_empty_string(host) and not_empty_string(reason) -> + {host, reason} + + {host, _reason} when not_empty_string(host) -> + {host, ""} + + host when not_empty_string(host) -> + {host, ""} + + _ -> + nil + end) + |> Enum.reject(&is_nil/1) + |> Enum.reject(fn {host, _} -> + host in exclusions or not Map.has_key?(@block_severities, rule) + end) + |> Enum.map(fn {host, reason} -> + %{ + domain: host, + digest: :crypto.hash(:sha256, host) |> Base.encode16(case: :lower), + severity: Map.get(@block_severities, rule), + comment: reason + } + end) + end) + |> List.flatten() + + domain_blocks + else + [] + end + end + def render("translation_languages.json", _) do with true <- Pleroma.Language.Translation.configured?(), {:ok, languages} <- Pleroma.Language.Translation.languages_matrix() do diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 5e1ef7480..85b6b986d 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -798,6 +798,7 @@ defmodule Pleroma.Web.Router do get("/instance", InstanceController, :show) get("/instance/peers", InstanceController, :peers) get("/instance/rules", InstanceController, :rules) + get("/instance/domain_blocks", InstanceController, :domain_blocks) get("/instance/translation_languages", InstanceController, :translation_languages) get("/statuses", StatusController, :index) diff --git a/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs index 10c0b6ea7..e0c9091e0 100644 --- a/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs @@ -153,6 +153,33 @@ defmodule Pleroma.Web.MastodonAPI.InstanceControllerTest do ] = result["rules"] end + describe "instance domain blocks" do + setup do + clear_config([:mrf_simple, :reject], [{"fediverse.pl", "uses pl-fe"}]) + end + + test "get instance domain blocks", %{conn: conn} do + conn = get(conn, "/api/v1/instance/domain_blocks") + + assert [ + %{ + "comment" => "uses pl-fe", + "digest" => "55e3f44aefe7eb022d3b1daaf7396cabf7f181bf6093c8ea841e30c9fc7d8226", + "domain" => "fediverse.pl", + "severity" => "suspend" + } + ] == json_response_and_validate_schema(conn, 200) + end + + test "returns empty array if mrf transparency is disabled", %{conn: conn} do + clear_config([:mrf, :transparency], false) + + conn = get(conn, "/api/v1/instance/domain_blocks") + + assert [] == json_response_and_validate_schema(conn, 200) + end + end + test "translation languages matrix", %{conn: conn} do clear_config([Pleroma.Language.Translation, :provider], TranslationMock)