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