federation_status: New endpoint showing unreachable instances
authorHaelwenn (lanodan) Monnier <contact@hacktivis.me>
Thu, 15 Oct 2020 22:32:20 +0000 (00:32 +0200)
committerHaelwenn (lanodan) Monnier <contact@hacktivis.me>
Thu, 15 Oct 2020 23:14:04 +0000 (01:14 +0200)
lib/pleroma/instances.ex
lib/pleroma/instances/instance.ex
lib/pleroma/web/pleroma_api/controllers/instances_controller.ex [new file with mode: 0644]
lib/pleroma/web/router.ex
test/pleroma/web/pleroma_api/controllers/instances_controller_test.exs [new file with mode: 0644]

index 557e8decfdd3c41e3d52e73edaa4469c4c603839..7315bd7cbeb170f5afc081a073cabb32d9b93c52 100644 (file)
@@ -11,6 +11,7 @@ defmodule Pleroma.Instances do
   defdelegate reachable?(url_or_host), to: @adapter
   defdelegate set_reachable(url_or_host), to: @adapter
   defdelegate set_unreachable(url_or_host, unreachable_since \\ nil), to: @adapter
+  defdelegate get_consistently_unreachable(), to: @adapter
 
   def set_consistently_unreachable(url_or_host),
     do: set_unreachable(url_or_host, reachability_datetime_threshold())
index f0f6014690a090b1d97e04f7a47aa4a3b2fe641d..df471a39d9a501a15050b94bd891e015add8ccce 100644 (file)
@@ -119,6 +119,17 @@ defmodule Pleroma.Instances.Instance do
 
   def set_unreachable(_, _), do: {:error, nil}
 
+  def get_consistently_unreachable do
+    reachability_datetime_threshold = Instances.reachability_datetime_threshold()
+
+    from(i in Instance,
+      where: ^reachability_datetime_threshold > i.unreachable_since,
+      order_by: i.unreachable_since,
+      select: {i.host, i.unreachable_since}
+    )
+    |> Repo.all()
+  end
+
   defp parse_datetime(datetime) when is_binary(datetime) do
     NaiveDateTime.from_iso8601(datetime)
   end
diff --git a/lib/pleroma/web/pleroma_api/controllers/instances_controller.ex b/lib/pleroma/web/pleroma_api/controllers/instances_controller.ex
new file mode 100644 (file)
index 0000000..bd95cb5
--- /dev/null
@@ -0,0 +1,19 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.PleromaAPI.InstancesController do
+  use Pleroma.Web, :controller
+
+  alias Pleroma.Instances
+
+  # defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaInstancesController
+
+  def show(conn, _params) do
+    unreachable =
+      Instances.get_consistently_unreachable()
+      |> Enum.reduce(%{}, fn {host, date}, acc -> Map.put(acc, host, to_string(date)) end)
+
+    json(conn, %{"unreachable" => unreachable})
+  end
+end
index d2d93998965e8592cd72429abacd96b46a7e88d0..5f9a749e4f2db5ae28d55363ed9605b2aa34a8f3 100644 (file)
@@ -373,6 +373,7 @@ defmodule Pleroma.Web.Router do
   scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do
     pipe_through(:api)
     get("/accounts/:id/scrobbles", ScrobbleController, :index)
+    get("/federation_status", InstancesController, :show)
   end
 
   scope "/api/v1", Pleroma.Web.MastodonAPI do
diff --git a/test/pleroma/web/pleroma_api/controllers/instances_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/instances_controller_test.exs
new file mode 100644 (file)
index 0000000..9ce901c
--- /dev/null
@@ -0,0 +1,40 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.PleromaApi.InstancesControllerTest do
+  use Pleroma.Web.ConnCase
+
+  alias Pleroma.Instances
+
+  setup_all do: clear_config([:instance, :federation_reachability_timeout_days], 1)
+
+  setup do
+    constant = "http://consistently-unreachable.name/"
+    eventual = "http://eventually-unreachable.com/path"
+
+    {:ok, %Pleroma.Instances.Instance{unreachable_since: constant_unreachable}} =
+      Instances.set_consistently_unreachable(constant)
+
+    _eventual_unrechable = Instances.set_unreachable(eventual)
+
+    %{constant_unreachable: constant_unreachable, constant: constant}
+  end
+
+  test "GET /api/v1/pleroma/federation_status", %{
+    conn: conn,
+    constant_unreachable: constant_unreachable,
+    constant: constant
+  } do
+    constant_host = URI.parse(constant).host
+
+    assert conn
+           |> put_req_header("content-type", "application/json")
+           |> get("/api/v1/pleroma/federation_status")
+           |> json_response(200) == %{
+             "unreachable" => %{constant_host => to_string(constant_unreachable)}
+           }
+
+    # |> json_response_and_validate_schema(200)
+  end
+end