added admin api for MediaProxy cache invalidation
authorMaksim Pechnikov <parallel588@gmail.com>
Fri, 12 Jun 2020 11:49:54 +0000 (14:49 +0300)
committerMaksim Pechnikov <parallel588@gmail.com>
Fri, 12 Jun 2020 11:49:54 +0000 (14:49 +0300)
lib/pleroma/web/admin_api/controllers/media_proxy_cache_controller.ex [new file with mode: 0644]
lib/pleroma/web/admin_api/views/media_proxy_cache_view.ex [new file with mode: 0644]
lib/pleroma/web/api_spec/operations/admin/media_proxy_cache_operation.ex [new file with mode: 0644]
lib/pleroma/web/router.ex
test/web/admin_api/controllers/media_proxy_cache_controller_test.exs [new file with mode: 0644]

diff --git a/lib/pleroma/web/admin_api/controllers/media_proxy_cache_controller.ex b/lib/pleroma/web/admin_api/controllers/media_proxy_cache_controller.ex
new file mode 100644 (file)
index 0000000..7b28f7c
--- /dev/null
@@ -0,0 +1,38 @@
+# 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.MediaProxyCacheController do
+  use Pleroma.Web, :controller
+
+  alias Pleroma.Plugs.OAuthScopesPlug
+  alias Pleroma.Web.ApiSpec.Admin, as: Spec
+
+  plug(Pleroma.Web.ApiSpec.CastAndValidate)
+
+  plug(
+    OAuthScopesPlug,
+    %{scopes: ["read:media_proxy_caches"], admin: true} when action in [:index]
+  )
+
+  plug(
+    OAuthScopesPlug,
+    %{scopes: ["write:media_proxy_caches"], admin: true} when action in [:purge, :delete]
+  )
+
+  action_fallback(Pleroma.Web.AdminAPI.FallbackController)
+
+  defdelegate open_api_operation(action), to: Spec.MediaProxyCacheOperation
+
+  def index(%{assigns: %{user: _}} = conn, _) do
+    render(conn, "index.json", urls: [])
+  end
+
+  def delete(%{assigns: %{user: _}, body_params: %{urls: urls}} = conn, _) do
+    render(conn, "index.json", urls: urls)
+  end
+
+  def purge(%{assigns: %{user: _}, body_params: %{urls: urls, ban: _ban}} = conn, _) do
+    render(conn, "index.json", urls: urls)
+  end
+end
diff --git a/lib/pleroma/web/admin_api/views/media_proxy_cache_view.ex b/lib/pleroma/web/admin_api/views/media_proxy_cache_view.ex
new file mode 100644 (file)
index 0000000..c97400b
--- /dev/null
@@ -0,0 +1,11 @@
+# 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.MediaProxyCacheView do
+  use Pleroma.Web, :view
+
+  def render("index.json", %{urls: urls}) do
+    %{urls: urls}
+  end
+end
diff --git a/lib/pleroma/web/api_spec/operations/admin/media_proxy_cache_operation.ex b/lib/pleroma/web/api_spec/operations/admin/media_proxy_cache_operation.ex
new file mode 100644 (file)
index 0000000..0358cfb
--- /dev/null
@@ -0,0 +1,109 @@
+# 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.MediaProxyCacheOperation do
+  alias OpenApiSpex.Operation
+  alias OpenApiSpex.Schema
+  alias Pleroma.Web.ApiSpec.Schemas.ApiError
+
+  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", "MediaProxyCache"],
+      summary: "Fetch a paginated list of all banned MediaProxy URLs in Cachex",
+      operationId: "AdminAPI.MediaProxyCacheController.index",
+      security: [%{"oAuth" => ["read:media_proxy_caches"]}],
+      parameters: [
+        Operation.parameter(
+          :page,
+          :query,
+          %Schema{type: :integer, default: 1},
+          "Page"
+        ),
+        Operation.parameter(
+          :page_size,
+          :query,
+          %Schema{type: :integer, default: 50},
+          "Number of statuses to return"
+        )
+      ],
+      responses: %{
+        200 => success_response()
+      }
+    }
+  end
+
+  def delete_operation do
+    %Operation{
+      tags: ["Admin", "MediaProxyCache"],
+      summary: "Remove a banned MediaProxy URL from Cachex",
+      operationId: "AdminAPI.MediaProxyCacheController.delete",
+      security: [%{"oAuth" => ["write:media_proxy_caches"]}],
+      requestBody:
+        request_body(
+          "Parameters",
+          %Schema{
+            type: :object,
+            required: [:urls],
+            properties: %{
+              urls: %Schema{type: :array, items: %Schema{type: :string, format: :uri}}
+            }
+          },
+          required: true
+        ),
+      responses: %{
+        200 => success_response(),
+        400 => Operation.response("Error", "application/json", ApiError)
+      }
+    }
+  end
+
+  def purge_operation do
+    %Operation{
+      tags: ["Admin", "MediaProxyCache"],
+      summary: "Purge and optionally ban a MediaProxy URL",
+      operationId: "AdminAPI.MediaProxyCacheController.purge",
+      security: [%{"oAuth" => ["write:media_proxy_caches"]}],
+      requestBody:
+        request_body(
+          "Parameters",
+          %Schema{
+            type: :object,
+            required: [:urls],
+            properties: %{
+              urls: %Schema{type: :array, items: %Schema{type: :string, format: :uri}},
+              ban: %Schema{type: :boolean, default: true}
+            }
+          },
+          required: true
+        ),
+      responses: %{
+        200 => success_response(),
+        400 => Operation.response("Error", "application/json", ApiError)
+      }
+    }
+  end
+
+  defp success_response do
+    Operation.response("Array of banned MediaProxy URLs in Cachex", "application/json", %Schema{
+      type: :object,
+      properties: %{
+        urls: %Schema{
+          type: :array,
+          items: %Schema{
+            type: :string,
+            format: :uri,
+            description: "MediaProxy URLs"
+          }
+        }
+      }
+    })
+  end
+end
index 57570b672227ceab3aa7328c01d9f04e75d4bd82..eda74a171820688f6cef689143382d8cb4b4cfad 100644 (file)
@@ -209,6 +209,10 @@ defmodule Pleroma.Web.Router do
     post("/oauth_app", OAuthAppController, :create)
     patch("/oauth_app/:id", OAuthAppController, :update)
     delete("/oauth_app/:id", OAuthAppController, :delete)
+
+    get("/media_proxy_caches", MediaProxyCacheController, :index)
+    post("/media_proxy_caches/delete", MediaProxyCacheController, :delete)
+    post("/media_proxy_caches/purge", MediaProxyCacheController, :purge)
   end
 
   scope "/api/pleroma/emoji", Pleroma.Web.PleromaAPI do
diff --git a/test/web/admin_api/controllers/media_proxy_cache_controller_test.exs b/test/web/admin_api/controllers/media_proxy_cache_controller_test.exs
new file mode 100644 (file)
index 0000000..1b1d6bc
--- /dev/null
@@ -0,0 +1,66 @@
+# 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.MediaProxyCacheControllerTest do
+  use Pleroma.Web.ConnCase
+
+  import Pleroma.Factory
+
+  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 "GET /api/pleroma/admin/media_proxy_caches" do
+    test "shows banned MediaProxy URLs", %{conn: conn} do
+      response =
+        conn
+        |> get("/api/pleroma/admin/media_proxy_caches")
+        |> json_response_and_validate_schema(200)
+
+      assert response["urls"] == []
+    end
+  end
+
+  describe "DELETE /api/pleroma/admin/media_proxy_caches/delete" do
+    test "deleted MediaProxy URLs from banned", %{conn: conn} do
+      response =
+        conn
+        |> put_req_header("content-type", "application/json")
+        |> post("/api/pleroma/admin/media_proxy_caches/delete", %{
+          urls: ["http://example.com/media/a688346.jpg", "http://example.com/media/fb1f4d.jpg"]
+        })
+        |> json_response_and_validate_schema(200)
+
+      assert response["urls"] == [
+               "http://example.com/media/a688346.jpg",
+               "http://example.com/media/fb1f4d.jpg"
+             ]
+    end
+  end
+
+  describe "PURGE /api/pleroma/admin/media_proxy_caches/purge" do
+    test "perform invalidates cache of MediaProxy", %{conn: conn} do
+      response =
+        conn
+        |> put_req_header("content-type", "application/json")
+        |> post("/api/pleroma/admin/media_proxy_caches/purge", %{
+          urls: ["http://example.com/media/a688346.jpg", "http://example.com/media/fb1f4d.jpg"]
+        })
+        |> json_response_and_validate_schema(200)
+
+      assert response["urls"] == [
+               "http://example.com/media/a688346.jpg",
+               "http://example.com/media/fb1f4d.jpg"
+             ]
+    end
+  end
+end