Allow admins request user backups

This commit is contained in:
Egor Kislitsyn 2020-09-18 22:18:34 +04:00
parent 7fdd81d000
commit 7c22c9afb4
No known key found for this signature in database
GPG Key ID: 1B49CB15B71E7805
6 changed files with 57 additions and 12 deletions

View File

@ -30,12 +30,12 @@ defmodule Pleroma.Backup do
timestamps() timestamps()
end end
def create(user) do def create(user, admin_user_id \\ nil) do
with :ok <- validate_email_enabled(), with :ok <- validate_email_enabled(),
:ok <- validate_user_email(user), :ok <- validate_user_email(user),
:ok <- validate_limit(user), :ok <- validate_limit(user),
{:ok, backup} <- user |> new() |> Repo.insert() do {:ok, backup} <- user |> new() |> Repo.insert() do
BackupWorker.process(backup) BackupWorker.process(backup, admin_user_id)
end end
end end

View File

@ -190,14 +190,24 @@ def unsubscribe_url(user, notifications_type) do
Router.Helpers.subscription_url(Endpoint, :unsubscribe, token) Router.Helpers.subscription_url(Endpoint, :unsubscribe, token)
end 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) %{user: user} = Pleroma.Repo.preload(backup, :user)
download_url = Pleroma.Web.PleromaAPI.BackupView.download_url(backup) download_url = Pleroma.Web.PleromaAPI.BackupView.download_url(backup)
html_body = """ 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>You requested a full backup of your Pleroma account. It's ready for download:</p>
<p><a href="#{download_url}"></a></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() new()
|> to(recipient(user)) |> to(recipient(user))

View File

@ -23,12 +23,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
alias Pleroma.Web.Endpoint alias Pleroma.Web.Endpoint
alias Pleroma.Web.Router alias Pleroma.Web.Router
require Logger
@users_page_size 50 @users_page_size 50
plug( plug(
OAuthScopesPlug, OAuthScopesPlug,
%{scopes: ["read:accounts"], admin: true} %{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( plug(
@ -681,6 +683,14 @@ def stats(conn, params) do
json(conn, %{"status_visibility" => counters}) json(conn, %{"status_visibility" => counters})
end 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 defp page_params(params) do
{get_page(params["page"]), get_page_size(params["page_size"])} {get_page(params["page"]), get_page_size(params["page_size"])}
end end

View File

@ -129,6 +129,8 @@ defmodule Pleroma.Web.Router do
scope "/api/pleroma/admin", Pleroma.Web.AdminAPI do scope "/api/pleroma/admin", Pleroma.Web.AdminAPI do
pipe_through(:admin_api) pipe_through(:admin_api)
post("/backups", AdminAPIController, :create_backup)
post("/users/follow", AdminAPIController, :user_follow) post("/users/follow", AdminAPIController, :user_follow)
post("/users/unfollow", AdminAPIController, :user_unfollow) post("/users/unfollow", AdminAPIController, :user_unfollow)

View File

@ -8,8 +8,8 @@ defmodule Pleroma.Workers.BackupWorker do
alias Oban.Job alias Oban.Job
alias Pleroma.Backup alias Pleroma.Backup
def process(backup) do def process(backup, admin_user_id \\ nil) do
%{"op" => "process", "backup_id" => backup.id} %{"op" => "process", "backup_id" => backup.id, "admin_user_id" => admin_user_id}
|> new() |> new()
|> Oban.insert() |> Oban.insert()
end end
@ -30,14 +30,16 @@ def delete(backup) do
|> Oban.insert() |> Oban.insert()
end 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} <- with {:ok, %Backup{} = backup} <-
backup_id |> Backup.get() |> Backup.process(), backup_id |> Backup.get() |> Backup.process(),
{:ok, _job} <- schedule_deletion(backup), {:ok, _job} <- schedule_deletion(backup),
:ok <- Backup.remove_outdated(backup), :ok <- Backup.remove_outdated(backup),
{:ok, _} <- {:ok, _} <-
backup backup
|> Pleroma.Emails.UserEmail.backup_is_ready_email() |> Pleroma.Emails.UserEmail.backup_is_ready_email(admin_user_id)
|> Pleroma.Emails.Mailer.deliver() do |> Pleroma.Emails.Mailer.deliver() do
{:ok, backup} {:ok, backup}
end end

View File

@ -2024,6 +2024,27 @@ test "by instance", %{conn: conn} do
response["status_visibility"] response["status_visibility"]
end end
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 end
# Needed for testing # Needed for testing