Allow users to create backups without providing email address
authorTusooa Zhu <tusooa@kazv.moe>
Sat, 7 May 2022 04:20:50 +0000 (00:20 -0400)
committerFrancis Dinh <normandy@biribiri.dev>
Wed, 3 Aug 2022 02:16:54 +0000 (22:16 -0400)
Ref: backup-without-email

lib/pleroma/user/backup.ex
lib/pleroma/workers/backup_worker.ex
test/pleroma/user/backup_test.exs
test/pleroma/web/pleroma_api/controllers/backup_controller_test.exs

index cba94248f969958949dba986aacf1f6726395f39..2c63782651fcd95eb2689492a07bd6ed88d5824f 100644 (file)
@@ -32,9 +32,7 @@ defmodule Pleroma.User.Backup do
   end
 
   def create(user, admin_id \\ nil) do
-    with :ok <- validate_email_enabled(),
-         :ok <- validate_user_email(user),
-         :ok <- validate_limit(user, admin_id),
+    with :ok <- validate_limit(user, admin_id),
          {:ok, backup} <- user |> new() |> Repo.insert() do
       BackupWorker.process(backup, admin_id)
     end
@@ -86,20 +84,6 @@ defmodule Pleroma.User.Backup do
     end
   end
 
-  defp validate_email_enabled do
-    if Pleroma.Config.get([Pleroma.Emails.Mailer, :enabled]) do
-      :ok
-    else
-      {:error, dgettext("errors", "Backups require enabled email")}
-    end
-  end
-
-  defp validate_user_email(%User{email: nil}) do
-    {:error, dgettext("errors", "Email is required")}
-  end
-
-  defp validate_user_email(%User{email: email}) when is_binary(email), do: :ok
-
   def get_last(user_id) do
     __MODULE__
     |> where(user_id: ^user_id)
index 9b763b04b915b59a0f5afdc239ae7662020a7c52..66c5c35916e9b59da4fe69ca84f43dfa9833ccc3 100644 (file)
@@ -37,10 +37,7 @@ defmodule Pleroma.Workers.BackupWorker do
            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(admin_user_id)
-           |> Pleroma.Emails.Mailer.deliver() do
+         :ok <- maybe_deliver_email(backup, admin_user_id) do
       {:ok, backup}
     end
   end
@@ -51,4 +48,23 @@ defmodule Pleroma.Workers.BackupWorker do
       nil -> :ok
     end
   end
+
+  defp has_email?(user) do
+    not is_nil(user.email) and user.email != ""
+  end
+
+  defp maybe_deliver_email(backup, admin_user_id) do
+    has_mailer = Pleroma.Config.get([Pleroma.Emails.Mailer, :enabled])
+    backup = backup |> Pleroma.Repo.preload(:user)
+
+    if has_email?(backup.user) and has_mailer do
+      backup
+      |> Pleroma.Emails.UserEmail.backup_is_ready_email(admin_user_id)
+      |> Pleroma.Emails.Mailer.deliver()
+
+      :ok
+    else
+      :ok
+    end
+  end
 end
index b16152876aac735446589db3e7afcea8ff596285..029bbbf5644640dbb4bea8c68aca12a3f5ef8f7c 100644 (file)
@@ -22,15 +22,15 @@ defmodule Pleroma.User.BackupTest do
     clear_config([Pleroma.Emails.Mailer, :enabled], true)
   end
 
-  test "it requries enabled email" do
+  test "it does not requrie enabled email" do
     clear_config([Pleroma.Emails.Mailer, :enabled], false)
     user = insert(:user)
-    assert {:error, "Backups require enabled email"} == Backup.create(user)
+    assert {:ok, _} = Backup.create(user)
   end
 
-  test "it requries user's email" do
+  test "it does not require user's email" do
     user = insert(:user, %{email: nil})
-    assert {:error, "Email is required"} == Backup.create(user)
+    assert {:ok, _} = Backup.create(user)
   end
 
   test "it creates a backup record and an Oban job" do
@@ -75,6 +75,43 @@ defmodule Pleroma.User.BackupTest do
     )
   end
 
+  test "it does not send an email if the user does not have an email" do
+    clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local)
+    %{id: user_id} = user = insert(:user, %{email: nil})
+
+    assert {:ok, %Oban.Job{args: %{"backup_id" => backup_id} = args}} = Backup.create(user)
+    assert {:ok, backup} = perform_job(BackupWorker, args)
+    assert backup.file_size > 0
+    assert %Backup{id: ^backup_id, processed: true, user_id: ^user_id} = backup
+
+    assert_no_email_sent()
+  end
+
+  test "it does not send an email if mailer is not on" do
+    clear_config([Pleroma.Emails.Mailer, :enabled], false)
+    clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local)
+    %{id: user_id} = user = insert(:user)
+
+    assert {:ok, %Oban.Job{args: %{"backup_id" => backup_id} = args}} = Backup.create(user)
+    assert {:ok, backup} = perform_job(BackupWorker, args)
+    assert backup.file_size > 0
+    assert %Backup{id: ^backup_id, processed: true, user_id: ^user_id} = backup
+
+    assert_no_email_sent()
+  end
+
+  test "it does not send an email if the user has an empty email" do
+    clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local)
+    %{id: user_id} = user = insert(:user, %{email: ""})
+
+    assert {:ok, %Oban.Job{args: %{"backup_id" => backup_id} = args}} = Backup.create(user)
+    assert {:ok, backup} = perform_job(BackupWorker, args)
+    assert backup.file_size > 0
+    assert %Backup{id: ^backup_id, processed: true, user_id: ^user_id} = backup
+
+    assert_no_email_sent()
+  end
+
   test "it removes outdated backups after creating a fresh one" do
     clear_config([Backup, :limit_days], -1)
     clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local)
index 3ee660a0581711a510daf651cde686bca3c4fd21..ba17636daf0905477b82f1fd4233708764fa577a 100644 (file)
@@ -82,4 +82,24 @@ defmodule Pleroma.Web.PleromaAPI.BackupControllerTest do
              |> post("/api/v1/pleroma/backups")
              |> json_response_and_validate_schema(400)
   end
+
+  test "Backup without email address" do
+    user = Pleroma.Factory.insert(:user, email: nil)
+    %{conn: conn} = oauth_access(["read:accounts"], user: user)
+
+    assert is_nil(user.email)
+
+    assert [
+             %{
+               "content_type" => "application/zip",
+               "url" => _url,
+               "file_size" => 0,
+               "processed" => false,
+               "inserted_at" => _
+             }
+           ] =
+             conn
+             |> post("/api/v1/pleroma/backups")
+             |> json_response_and_validate_schema(:ok)
+  end
 end