diff --git a/lib/pleroma/user/mailing_list.ex b/lib/pleroma/user/mailing_list.ex
index 2cc223cc7..b60069023 100644
--- a/lib/pleroma/user/mailing_list.ex
+++ b/lib/pleroma/user/mailing_list.ex
@@ -11,6 +11,8 @@ defmodule Pleroma.User.MailingList do
alias Pleroma.Repo
alias Pleroma.User
+ @header_row ["Email Address"]
+
defp subscribers_query do
User.Query.build(%{
local: true,
@@ -34,10 +36,11 @@ defmodule Pleroma.User.MailingList do
|> build_csv()
end
- defp build_row(%User{email: email}), do: email
+ defp build_row(%User{email: email}), do: [email]
defp build_csv(lines) do
- ["Email Address" | lines]
- |> Enum.join("\n")
+ [@header_row | lines]
+ |> CSV.encode()
+ |> Enum.join()
end
end
diff --git a/lib/pleroma/web/admin_api/controllers/email_list_controller.ex b/lib/pleroma/web/admin_api/controllers/email_list_controller.ex
new file mode 100644
index 000000000..dfe9009b8
--- /dev/null
+++ b/lib/pleroma/web/admin_api/controllers/email_list_controller.ex
@@ -0,0 +1,26 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2021 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.AdminAPI.EmailListController do
+ use Pleroma.Web, :controller
+
+ alias Pleroma.User.MailingList
+ alias Pleroma.Web.Plugs.OAuthScopesPlug
+
+ require Logger
+
+ plug(
+ OAuthScopesPlug,
+ %{scopes: ["admin:read:accounts"]} when action in [:subscribers]
+ )
+
+ def subscribers(conn, _params) do
+ csv = MailingList.generate_csv()
+
+ conn
+ |> put_resp_content_type("text/csv")
+ |> resp(200, csv)
+ |> send_resp()
+ end
+end
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index 72ad14f05..f825fadcd 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -257,6 +257,8 @@ defmodule Pleroma.Web.Router do
post("/frontends/install", FrontendController, :install)
post("/backups", AdminAPIController, :create_backup)
+
+ get("/email_list/subscribers.csv", EmailListController, :subscribers)
end
scope "/api/v1/pleroma/emoji", Pleroma.Web.PleromaAPI do
diff --git a/mix.exs b/mix.exs
index 436381f32..0b92ae146 100644
--- a/mix.exs
+++ b/mix.exs
@@ -132,6 +132,7 @@ defmodule Pleroma.Mixfile do
{:phoenix_html, "~> 2.14"},
{:calendar, "~> 1.0"},
{:cachex, "~> 3.2"},
+ {:csv, "~> 2.4"},
{:poison, "~> 3.0", override: true},
{:tesla, "~> 1.4.0", override: true},
{:castore, "~> 0.1"},
diff --git a/mix.lock b/mix.lock
index 99be81826..f26e5bc26 100644
--- a/mix.lock
+++ b/mix.lock
@@ -23,6 +23,7 @@
"credo": {:hex, :credo, "1.4.1", "16392f1edd2cdb1de9fe4004f5ab0ae612c92e230433968eab00aafd976282fc", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "155f8a2989ad77504de5d8291fa0d41320fdcaa6a1030472e9967f285f8c7692"},
"crontab": {:hex, :crontab, "1.1.8", "2ce0e74777dfcadb28a1debbea707e58b879e6aa0ffbf9c9bb540887bce43617", [:mix], [{:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"},
"crypt": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/crypt.git", "cf2aa3f11632e8b0634810a15b3e612c7526f6a3", [ref: "cf2aa3f11632e8b0634810a15b3e612c7526f6a3"]},
+ "csv": {:hex, :csv, "2.4.1", "50e32749953b6bf9818dbfed81cf1190e38cdf24f95891303108087486c5925e", [:mix], [{:parallel_stream, "~> 1.0.4", [hex: :parallel_stream, repo: "hexpm", optional: false]}], "hexpm", "54508938ac67e27966b10ef49606e3ad5995d665d7fc2688efb3eab1307c9079"},
"custom_base": {:hex, :custom_base, "0.2.1", "4a832a42ea0552299d81652aa0b1f775d462175293e99dfbe4d7dbaab785a706", [:mix], [], "hexpm", "8df019facc5ec9603e94f7270f1ac73ddf339f56ade76a721eaa57c1493ba463"},
"db_connection": {:hex, :db_connection, "2.3.1", "4c9f3ed1ef37471cbdd2762d6655be11e38193904d9c5c1c9389f1b891a3088e", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm", "abaab61780dde30301d840417890bd9f74131041afd02174cf4e10635b3a63f5"},
"decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"},
@@ -84,6 +85,7 @@
"oban": {:hex, :oban, "2.3.4", "ec7509b9af2524d55f529cb7aee93d36131ae0bf0f37706f65d2fe707f4d9fd8", [:mix], [{:ecto_sql, ">= 3.4.3", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.14", [hex: :postgrex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c70ca0434758fd1805422ea4446af5e910ddc697c0c861549c8f0eb0cfbd2fdf"},
"open_api_spex": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/open_api_spex.git", "f296ac0924ba3cf79c7a588c4c252889df4c2edd", [ref: "f296ac0924ba3cf79c7a588c4c252889df4c2edd"]},
"p1_utils": {:hex, :p1_utils, "1.0.18", "3fe224de5b2e190d730a3c5da9d6e8540c96484cf4b4692921d1e28f0c32b01c", [:rebar3], [], "hexpm", "1fc8773a71a15553b179c986b22fbeead19b28fe486c332d4929700ffeb71f88"},
+ "parallel_stream": {:hex, :parallel_stream, "1.0.6", "b967be2b23f0f6787fab7ed681b4c45a215a81481fb62b01a5b750fa8f30f76c", [:mix], [], "hexpm", "639b2e8749e11b87b9eb42f2ad325d161c170b39b288ac8d04c4f31f8f0823eb"},
"parse_trans": {:git, "https://github.com/uwiger/parse_trans.git", "76abb347c3c1d00fb0ccf9e4b43e22b3d2288484", [tag: "3.3.0"]},
"pbkdf2_elixir": {:hex, :pbkdf2_elixir, "1.2.1", "9cbe354b58121075bd20eb83076900a3832324b7dd171a6895fab57b6bb2752c", [:mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}], "hexpm", "d3b40a4a4630f0b442f19eca891fcfeeee4c40871936fed2f68e1c4faa30481f"},
"phoenix": {:hex, :phoenix, "1.5.6", "8298cdb4e0f943242ba8410780a6a69cbbe972fef199b341a36898dd751bdd66", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "0dc4d39af1306b6aa5122729b0a95ca779e42c708c6fe7abbb3d336d5379e956"},
diff --git a/test/pleroma/web/admin_api/controllers/email_list_controller_test.exs b/test/pleroma/web/admin_api/controllers/email_list_controller_test.exs
new file mode 100644
index 000000000..9fcd63a07
--- /dev/null
+++ b/test/pleroma/web/admin_api/controllers/email_list_controller_test.exs
@@ -0,0 +1,34 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2021 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.AdminAPI.EmailListControllerTest do
+ use Pleroma.Web.ConnCase, async: true
+
+ import Pleroma.Factory
+
+ defp admin_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/v1/pleroma/admin/email_list/subscribers.csv" do
+ setup do: admin_setup()
+
+ test "returns a CSV", %{conn: conn} do
+ result =
+ conn
+ |> get("/api/v1/pleroma/admin/email_list/subscribers.csv")
+ |> response(200)
+
+ assert result
+ end
+ end
+end