Add OpenAPI spec for AdminAPI.RelayController
authorEgor Kislitsyn <egor@kislitsyn.com>
Fri, 22 May 2020 13:52:26 +0000 (17:52 +0400)
committerEgor Kislitsyn <egor@kislitsyn.com>
Mon, 25 May 2020 12:51:16 +0000 (16:51 +0400)
lib/pleroma/web/admin_api/controllers/admin_api_controller.ex
lib/pleroma/web/admin_api/controllers/relay_controller.ex [new file with mode: 0644]
lib/pleroma/web/api_spec/operations/admin/relay_operation.ex [new file with mode: 0644]
lib/pleroma/web/router.ex
test/web/admin_api/controllers/admin_api_controller_test.exs
test/web/admin_api/controllers/relay_controller_test.exs [new file with mode: 0644]

index 6b1d64a2eb3152f3ae0f916283f6af2fc7cf2162..b73701f5e86bc79be666e7c32a5857bb70f43851 100644 (file)
@@ -20,7 +20,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
   alias Pleroma.Web.ActivityPub.ActivityPub
   alias Pleroma.Web.ActivityPub.Builder
   alias Pleroma.Web.ActivityPub.Pipeline
-  alias Pleroma.Web.ActivityPub.Relay
   alias Pleroma.Web.ActivityPub.Utils
   alias Pleroma.Web.AdminAPI
   alias Pleroma.Web.AdminAPI.AccountView
@@ -80,7 +79,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
   plug(
     OAuthScopesPlug,
     %{scopes: ["write:follows"], admin: true}
-    when action in [:user_follow, :user_unfollow, :relay_follow, :relay_unfollow]
+    when action in [:user_follow, :user_unfollow]
   )
 
   plug(
@@ -108,7 +107,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
            :config_show,
            :list_log,
            :stats,
-           :relay_list,
            :config_descriptions,
            :need_reboot
          ]
@@ -531,50 +529,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
     render_error(conn, :forbidden, "You can't revoke your own admin status.")
   end
 
-  def relay_list(conn, _params) do
-    with {:ok, list} <- Relay.list() do
-      json(conn, %{relays: list})
-    else
-      _ ->
-        conn
-        |> put_status(500)
-    end
-  end
-
-  def relay_follow(%{assigns: %{user: admin}} = conn, %{"relay_url" => target}) do
-    with {:ok, _message} <- Relay.follow(target) do
-      ModerationLog.insert_log(%{
-        action: "relay_follow",
-        actor: admin,
-        target: target
-      })
-
-      json(conn, target)
-    else
-      _ ->
-        conn
-        |> put_status(500)
-        |> json(target)
-    end
-  end
-
-  def relay_unfollow(%{assigns: %{user: admin}} = conn, %{"relay_url" => target}) do
-    with {:ok, _message} <- Relay.unfollow(target) do
-      ModerationLog.insert_log(%{
-        action: "relay_unfollow",
-        actor: admin,
-        target: target
-      })
-
-      json(conn, target)
-    else
-      _ ->
-        conn
-        |> put_status(500)
-        |> json(target)
-    end
-  end
-
   @doc "Sends registration invite via email"
   def email_invite(%{assigns: %{user: user}} = conn, %{"email" => email} = params) do
     with {_, false} <- {:registrations_open, Config.get([:instance, :registrations_open])},
diff --git a/lib/pleroma/web/admin_api/controllers/relay_controller.ex b/lib/pleroma/web/admin_api/controllers/relay_controller.ex
new file mode 100644 (file)
index 0000000..cf9f3a1
--- /dev/null
@@ -0,0 +1,67 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.AdminAPI.RelayController do
+  use Pleroma.Web, :controller
+
+  alias Pleroma.ModerationLog
+  alias Pleroma.Plugs.OAuthScopesPlug
+  alias Pleroma.Web.ActivityPub.Relay
+
+  require Logger
+
+  plug(Pleroma.Web.ApiSpec.CastAndValidate)
+
+  plug(
+    OAuthScopesPlug,
+    %{scopes: ["write:follows"], admin: true}
+    when action in [:follow, :unfollow]
+  )
+
+  plug(OAuthScopesPlug, %{scopes: ["read"], admin: true} when action == :index)
+
+  action_fallback(Pleroma.Web.AdminAPI.FallbackController)
+
+  defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.Admin.RelayOperation
+
+  def index(conn, _params) do
+    with {:ok, list} <- Relay.list() do
+      json(conn, %{relays: list})
+    end
+  end
+
+  def follow(%{assigns: %{user: admin}, body_params: %{relay_url: target}} = conn, _) do
+    with {:ok, _message} <- Relay.follow(target) do
+      ModerationLog.insert_log(%{
+        action: "relay_follow",
+        actor: admin,
+        target: target
+      })
+
+      json(conn, target)
+    else
+      _ ->
+        conn
+        |> put_status(500)
+        |> json(target)
+    end
+  end
+
+  def unfollow(%{assigns: %{user: admin}, body_params: %{relay_url: target}} = conn, _) do
+    with {:ok, _message} <- Relay.unfollow(target) do
+      ModerationLog.insert_log(%{
+        action: "relay_unfollow",
+        actor: admin,
+        target: target
+      })
+
+      json(conn, target)
+    else
+      _ ->
+        conn
+        |> put_status(500)
+        |> json(target)
+    end
+  end
+end
diff --git a/lib/pleroma/web/api_spec/operations/admin/relay_operation.ex b/lib/pleroma/web/api_spec/operations/admin/relay_operation.ex
new file mode 100644 (file)
index 0000000..7672cb4
--- /dev/null
@@ -0,0 +1,83 @@
+# 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.Admin.RelayOperation do
+  alias OpenApiSpex.Operation
+  alias OpenApiSpex.Schema
+
+  import Pleroma.Web.ApiSpec.Helpers
+
+  def open_api_operation(action) do
+    operation = String.to_existing_atom("#{action}_operation")
+    apply(__MODULE__, operation, [])
+  end
+
+  def index_operation do
+    %Operation{
+      tags: ["Admin", "Relays"],
+      summary: "List Relays",
+      operationId: "AdminAPI.RelayController.index",
+      security: [%{"oAuth" => ["read"]}],
+      responses: %{
+        200 =>
+          Operation.response("Response", "application/json", %Schema{
+            type: :object,
+            properties: %{
+              relays: %Schema{
+                type: :array,
+                items: %Schema{type: :string},
+                example: ["lain.com", "mstdn.io"]
+              }
+            }
+          })
+      }
+    }
+  end
+
+  def follow_operation do
+    %Operation{
+      tags: ["Admin", "Relays"],
+      summary: "Follow a Relay",
+      operationId: "AdminAPI.RelayController.follow",
+      security: [%{"oAuth" => ["write:follows"]}],
+      requestBody:
+        request_body("Parameters", %Schema{
+          type: :object,
+          properties: %{
+            relay_url: %Schema{type: :string, format: :uri}
+          }
+        }),
+      responses: %{
+        200 =>
+          Operation.response("Status", "application/json", %Schema{
+            type: :string,
+            example: "http://mastodon.example.org/users/admin"
+          })
+      }
+    }
+  end
+
+  def unfollow_operation do
+    %Operation{
+      tags: ["Admin", "Relays"],
+      summary: "Unfollow a Relay",
+      operationId: "AdminAPI.RelayController.unfollow",
+      security: [%{"oAuth" => ["write:follows"]}],
+      requestBody:
+        request_body("Parameters", %Schema{
+          type: :object,
+          properties: %{
+            relay_url: %Schema{type: :string, format: :uri}
+          }
+        }),
+      responses: %{
+        200 =>
+          Operation.response("Status", "application/json", %Schema{
+            type: :string,
+            example: "http://mastodon.example.org/users/admin"
+          })
+      }
+    }
+  end
+end
index e493a41534bb0f8b3a0a11e0eb6ec7714e4fd803..269bbabdea680993b76958e3b7fa54fca4beae7d 100644 (file)
@@ -160,9 +160,9 @@ defmodule Pleroma.Web.Router do
       :right_delete_multiple
     )
 
-    get("/relay", AdminAPIController, :relay_list)
-    post("/relay", AdminAPIController, :relay_follow)
-    delete("/relay", AdminAPIController, :relay_unfollow)
+    get("/relay", RelayController, :index)
+    post("/relay", RelayController, :follow)
+    delete("/relay", RelayController, :unfollow)
 
     post("/users/invite_token", AdminAPIController, :create_invite_token)
     get("/users/invites", AdminAPIController, :invites)
index 321840a8c31ff34222ca991ca3459ba6073a4859..82825473c6a11c65472a0cce2b9b73a8e3dad154 100644 (file)
@@ -3254,57 +3254,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
     end
   end
 
-  describe "relays" do
-    test "POST /relay", %{conn: conn, admin: admin} do
-      conn =
-        post(conn, "/api/pleroma/admin/relay", %{
-          relay_url: "http://mastodon.example.org/users/admin"
-        })
-
-      assert json_response(conn, 200) == "http://mastodon.example.org/users/admin"
-
-      log_entry = Repo.one(ModerationLog)
-
-      assert ModerationLog.get_log_entry_message(log_entry) ==
-               "@#{admin.nickname} followed relay: http://mastodon.example.org/users/admin"
-    end
-
-    test "GET /relay", %{conn: conn} do
-      relay_user = Pleroma.Web.ActivityPub.Relay.get_actor()
-
-      ["http://mastodon.example.org/users/admin", "https://mstdn.io/users/mayuutann"]
-      |> Enum.each(fn ap_id ->
-        {:ok, user} = User.get_or_fetch_by_ap_id(ap_id)
-        User.follow(relay_user, user)
-      end)
-
-      conn = get(conn, "/api/pleroma/admin/relay")
-
-      assert json_response(conn, 200)["relays"] -- ["mastodon.example.org", "mstdn.io"] == []
-    end
-
-    test "DELETE /relay", %{conn: conn, admin: admin} do
-      post(conn, "/api/pleroma/admin/relay", %{
-        relay_url: "http://mastodon.example.org/users/admin"
-      })
-
-      conn =
-        delete(conn, "/api/pleroma/admin/relay", %{
-          relay_url: "http://mastodon.example.org/users/admin"
-        })
-
-      assert json_response(conn, 200) == "http://mastodon.example.org/users/admin"
-
-      [log_entry_one, log_entry_two] = Repo.all(ModerationLog)
-
-      assert ModerationLog.get_log_entry_message(log_entry_one) ==
-               "@#{admin.nickname} followed relay: http://mastodon.example.org/users/admin"
-
-      assert ModerationLog.get_log_entry_message(log_entry_two) ==
-               "@#{admin.nickname} unfollowed relay: http://mastodon.example.org/users/admin"
-    end
-  end
-
   describe "instances" do
     test "GET /instances/:instance/statuses", %{conn: conn} do
       user = insert(:user, local: false, nickname: "archaeme@archae.me")
diff --git a/test/web/admin_api/controllers/relay_controller_test.exs b/test/web/admin_api/controllers/relay_controller_test.exs
new file mode 100644 (file)
index 0000000..64086ad
--- /dev/null
@@ -0,0 +1,92 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.AdminAPI.RelayControllerTest do
+  use Pleroma.Web.ConnCase
+
+  import Pleroma.Factory
+
+  alias Pleroma.Config
+  alias Pleroma.ModerationLog
+  alias Pleroma.Repo
+  alias Pleroma.User
+
+  setup_all do
+    Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
+
+    :ok
+  end
+
+  setup do
+    admin = insert(:user, is_admin: true)
+    token = insert(:oauth_admin_token, user: admin)
+
+    conn =
+      build_conn()
+      |> assign(:user, admin)
+      |> assign(:token, token)
+
+    {:ok, %{admin: admin, token: token, conn: conn}}
+  end
+
+  describe "relays" do
+    test "POST /relay", %{conn: conn, admin: admin} do
+      conn =
+        conn
+        |> put_req_header("content-type", "application/json")
+        |> post("/api/pleroma/admin/relay", %{
+          relay_url: "http://mastodon.example.org/users/admin"
+        })
+
+      assert json_response_and_validate_schema(conn, 200) ==
+               "http://mastodon.example.org/users/admin"
+
+      log_entry = Repo.one(ModerationLog)
+
+      assert ModerationLog.get_log_entry_message(log_entry) ==
+               "@#{admin.nickname} followed relay: http://mastodon.example.org/users/admin"
+    end
+
+    test "GET /relay", %{conn: conn} do
+      relay_user = Pleroma.Web.ActivityPub.Relay.get_actor()
+
+      ["http://mastodon.example.org/users/admin", "https://mstdn.io/users/mayuutann"]
+      |> Enum.each(fn ap_id ->
+        {:ok, user} = User.get_or_fetch_by_ap_id(ap_id)
+        User.follow(relay_user, user)
+      end)
+
+      conn = get(conn, "/api/pleroma/admin/relay")
+
+      assert json_response_and_validate_schema(conn, 200)["relays"] --
+               ["mastodon.example.org", "mstdn.io"] == []
+    end
+
+    test "DELETE /relay", %{conn: conn, admin: admin} do
+      conn
+      |> put_req_header("content-type", "application/json")
+      |> post("/api/pleroma/admin/relay", %{
+        relay_url: "http://mastodon.example.org/users/admin"
+      })
+
+      conn =
+        conn
+        |> put_req_header("content-type", "application/json")
+        |> delete("/api/pleroma/admin/relay", %{
+          relay_url: "http://mastodon.example.org/users/admin"
+        })
+
+      assert json_response_and_validate_schema(conn, 200) ==
+               "http://mastodon.example.org/users/admin"
+
+      [log_entry_one, log_entry_two] = Repo.all(ModerationLog)
+
+      assert ModerationLog.get_log_entry_message(log_entry_one) ==
+               "@#{admin.nickname} followed relay: http://mastodon.example.org/users/admin"
+
+      assert ModerationLog.get_log_entry_message(log_entry_two) ==
+               "@#{admin.nickname} unfollowed relay: http://mastodon.example.org/users/admin"
+    end
+  end
+end