Allow admins request user backups
authorEgor Kislitsyn <egor@kislitsyn.com>
Fri, 18 Sep 2020 18:18:34 +0000 (22:18 +0400)
committerEgor Kislitsyn <egor@kislitsyn.com>
Wed, 7 Oct 2020 14:34:31 +0000 (18:34 +0400)
lib/pleroma/backup.ex
lib/pleroma/emails/user_email.ex
lib/pleroma/web/admin_api/controllers/admin_api_controller.ex
lib/pleroma/web/router.ex
lib/pleroma/workers/backup_worker.ex
test/web/admin_api/controllers/admin_api_controller_test.exs

index 450dd5b84f61ae917e0c93709eac2fecaa25867f..d589f12f1beac02e04dae7077b5ab52e89435a58 100644 (file)
@@ -30,12 +30,12 @@ defmodule Pleroma.Backup do
     timestamps()
   end
 
-  def create(user) do
+  def create(user, admin_user_id \\ nil) do
     with :ok <- validate_email_enabled(),
          :ok <- validate_user_email(user),
          :ok <- validate_limit(user),
          {:ok, backup} <- user |> new() |> Repo.insert() do
-      BackupWorker.process(backup)
+      BackupWorker.process(backup, admin_user_id)
     end
   end
 
index f943dda0df59349cde11f395c79d02a0dc679a66..5745794ec261b88178e1c16c94293c4bcb1c3c27 100644 (file)
@@ -190,14 +190,24 @@ defmodule Pleroma.Emails.UserEmail do
     Router.Helpers.subscription_url(Endpoint, :unsubscribe, token)
   end
 
-  def backup_is_ready_email(backup) do
+  def backup_is_ready_email(backup, admin_user_id \\ nil) do
     %{user: user} = Pleroma.Repo.preload(backup, :user)
     download_url = Pleroma.Web.PleromaAPI.BackupView.download_url(backup)
 
-    html_body = """
-    <p>You requested a full backup of your Pleroma account. It's ready for download:</p>
-    <p><a href="#{download_url}"></a></p>
-    """
+    html_body =
+      if is_nil(admin_user_id) do
+        """
+        <p>You requested a full backup of your Pleroma account. It's ready for download:</p>
+        <p><a href="#{download_url}"></a></p>
+        """
+      else
+        admin = Pleroma.Repo.get(User, admin_user_id)
+
+        """
+        <p>Admin @#{admin.nickname} requested a full backup of your Pleroma account. It's ready for download:</p>
+        <p><a href="#{download_url}"></a></p>
+        """
+      end
 
     new()
     |> to(recipient(user))
index d5713c3dd968265b4bd2ba30b90274c00281d29f..f7d2fe5b1ff2e856887b55c73dc27409d3005cb0 100644 (file)
@@ -23,12 +23,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
   alias Pleroma.Web.Endpoint
   alias Pleroma.Web.Router
 
+  require Logger
+
   @users_page_size 50
 
   plug(
     OAuthScopesPlug,
     %{scopes: ["read:accounts"], admin: true}
-    when action in [:list_users, :user_show, :right_get, :show_user_credentials]
+    when action in [:list_users, :user_show, :right_get, :show_user_credentials, :create_backup]
   )
 
   plug(
@@ -681,6 +683,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
     json(conn, %{"status_visibility" => counters})
   end
 
+  def create_backup(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do
+    with %User{} = user <- User.get_by_nickname(nickname),
+         {:ok, _} <- Pleroma.Backup.create(user, admin.id) do
+      Logger.info("Admin @#{admin.nickname} requested account backup for @{nickname}")
+      json(conn, "")
+    end
+  end
+
   defp page_params(params) do
     {get_page(params["page"]), get_page_size(params["page_size"])}
   end
index a1a5a1cb54f476b7d4fe19c56e34356ad5f9652a..e539eeeebf8f1963b56d2c67bf9391b51d59baea 100644 (file)
@@ -129,6 +129,8 @@ defmodule Pleroma.Web.Router do
   scope "/api/pleroma/admin", Pleroma.Web.AdminAPI do
     pipe_through(:admin_api)
 
+    post("/backups", AdminAPIController, :create_backup)
+
     post("/users/follow", AdminAPIController, :user_follow)
     post("/users/unfollow", AdminAPIController, :user_unfollow)
 
index 405d55269b4307d836934049a15f678d2d65adc8..65754b6a2ede1fba53dfc897e7833eb64c4d7b47 100644 (file)
@@ -8,8 +8,8 @@ defmodule Pleroma.Workers.BackupWorker do
   alias Oban.Job
   alias Pleroma.Backup
 
-  def process(backup) do
-    %{"op" => "process", "backup_id" => backup.id}
+  def process(backup, admin_user_id \\ nil) do
+    %{"op" => "process", "backup_id" => backup.id, "admin_user_id" => admin_user_id}
     |> new()
     |> Oban.insert()
   end
@@ -30,14 +30,16 @@ defmodule Pleroma.Workers.BackupWorker do
     |> Oban.insert()
   end
 
-  def perform(%Job{args: %{"op" => "process", "backup_id" => backup_id}}) do
+  def perform(%Job{
+        args: %{"op" => "process", "backup_id" => backup_id, "admin_user_id" => admin_user_id}
+      }) do
     with {:ok, %Backup{} = backup} <-
            backup_id |> Backup.get() |> Backup.process(),
          {:ok, _job} <- schedule_deletion(backup),
          :ok <- Backup.remove_outdated(backup),
          {:ok, _} <-
            backup
-           |> Pleroma.Emails.UserEmail.backup_is_ready_email()
+           |> Pleroma.Emails.UserEmail.backup_is_ready_email(admin_user_id)
            |> Pleroma.Emails.Mailer.deliver() do
       {:ok, backup}
     end
index cba6b43d32a7d1a3e8519d5ebcc74d55e025256b..4d331779e4b15591fcfc5c0310faac0ce616f6db 100644 (file)
@@ -2024,6 +2024,27 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
                response["status_visibility"]
     end
   end
+
+  describe "/api/pleroma/backups" do
+    test "it creates a backup", %{conn: conn} do
+      admin = insert(:user, is_admin: true)
+      token = insert(:oauth_admin_token, user: admin)
+      user = insert(:user)
+
+      assert "" ==
+               conn
+               |> assign(:user, admin)
+               |> assign(:token, token)
+               |> post("/api/pleroma/admin/backups", %{nickname: user.nickname})
+               |> json_response(200)
+
+      assert [backup] = Repo.all(Pleroma.Backup)
+
+      ObanHelpers.perform_all()
+
+      assert_email_sent(Pleroma.Emails.UserEmail.backup_is_ready_email(backup, admin.id))
+    end
+  end
 end
 
 # Needed for testing