summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/pleroma/activity.ex10
-rw-r--r--lib/pleroma/emails/admin_email.ex63
-rw-r--r--lib/pleroma/emails/mailer.ex6
-rw-r--r--lib/pleroma/user.ex11
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub.ex25
-rw-r--r--lib/pleroma/web/activity_pub/utils.ex16
-rw-r--r--lib/pleroma/web/common_api/common_api.ex27
-rw-r--r--lib/pleroma/web/common_api/utils.ex18
-rw-r--r--lib/pleroma/web/mastodon_api/mastodon_api_controller.ex15
-rw-r--r--lib/pleroma/web/mastodon_api/views/report_view.ex14
-rw-r--r--lib/pleroma/web/router.ex2
-rw-r--r--lib/pleroma/web/twitter_api/twitter_api.ex2
12 files changed, 207 insertions, 2 deletions
diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex
index cdfe7ea9e..66854dc2d 100644
--- a/lib/pleroma/activity.ex
+++ b/lib/pleroma/activity.ex
@@ -113,4 +113,14 @@ defmodule Pleroma.Activity do
end
def mastodon_notification_type(%Activity{}), do: nil
+
+ def all_by_actor_and_id(actor, status_ids \\ [])
+ def all_by_actor_and_id(_actor, []), do: []
+
+ def all_by_actor_and_id(actor, status_ids) do
+ Activity
+ |> where([s], s.id in ^status_ids)
+ |> where([s], s.actor == ^actor)
+ |> Repo.all()
+ end
end
diff --git a/lib/pleroma/emails/admin_email.ex b/lib/pleroma/emails/admin_email.ex
new file mode 100644
index 000000000..9b20c7e08
--- /dev/null
+++ b/lib/pleroma/emails/admin_email.ex
@@ -0,0 +1,63 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.AdminEmail do
+ @moduledoc "Admin emails"
+
+ import Swoosh.Email
+
+ alias Pleroma.Web.Router.Helpers
+
+ defp instance_config, do: Pleroma.Config.get(:instance)
+ defp instance_name, do: instance_config()[:name]
+ defp instance_email, do: instance_config()[:email]
+
+ defp user_url(user) do
+ Helpers.o_status_url(Pleroma.Web.Endpoint, :feed_redirect, user.nickname)
+ end
+
+ def report(to, reporter, account, statuses, comment) do
+ comment_html =
+ if comment do
+ "<p>Comment: #{comment}"
+ else
+ ""
+ end
+
+ statuses_html =
+ if length(statuses) > 0 do
+ statuses_list_html =
+ statuses
+ |> Enum.map(fn %{id: id} ->
+ status_url = Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, id)
+ "<li><a href=\"#{status_url}\">#{status_url}</li>"
+ end)
+ |> Enum.join("\n")
+
+ """
+ <p> Statuses:
+ <ul>
+ #{statuses_list_html}
+ </ul>
+ </p>
+ """
+ else
+ ""
+ end
+
+ html_body = """
+ <p>Reported by: <a href="#{user_url(reporter)}">#{reporter.nickname}</a></p>
+ <p>Reported Account: <a href="#{user_url(account)}">#{account.nickname}</a></p>
+ #{comment_html}
+ #{statuses_html}
+ """
+
+ new()
+ |> to({to.name, to.email})
+ |> from({instance_name(), instance_email()})
+ |> reply_to({reporter.name, reporter.email})
+ |> subject("#{instance_name()} Report")
+ |> html_body(html_body)
+ end
+end
diff --git a/lib/pleroma/emails/mailer.ex b/lib/pleroma/emails/mailer.ex
index 8d12641f2..f7e3aa78b 100644
--- a/lib/pleroma/emails/mailer.ex
+++ b/lib/pleroma/emails/mailer.ex
@@ -4,4 +4,10 @@
defmodule Pleroma.Mailer do
use Swoosh.Mailer, otp_app: :pleroma
+
+ def deliver_async(email, config \\ []) do
+ Pleroma.Jobs.enqueue(:mailer, __MODULE__, [:deliver_async, email, config])
+ end
+
+ def perform(:deliver_async, email, config), do: deliver(email, config)
end
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index 35ba4ad99..c98b942ff 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -273,7 +273,7 @@ defmodule Pleroma.User do
Pleroma.Config.get([:instance, :account_activation_required]) do
user
|> Pleroma.UserEmail.account_confirmation_email()
- |> Pleroma.Mailer.deliver()
+ |> Pleroma.Mailer.deliver_async()
else
{:ok, :noop}
end
@@ -1284,4 +1284,13 @@ defmodule Pleroma.User do
inserted_at: NaiveDateTime.utc_now()
}
end
+
+ def all_superusers do
+ from(
+ u in User,
+ where: u.local == true,
+ where: fragment("?->'is_admin' @> 'true' OR ?->'is_moderator' @> 'true'", u.info, u.info)
+ )
+ |> Repo.all()
+ end
end
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index cb8a2139e..d1ac8172e 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -353,6 +353,31 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end
end
+ def flag(
+ %{
+ actor: actor,
+ context: context,
+ account: account,
+ statuses: statuses,
+ content: content
+ } = params
+ ) do
+ additional = params[:additional] || %{}
+
+ # only accept false as false value
+ local = !(params[:local] == false)
+
+ %{
+ actor: actor,
+ context: context,
+ account: account,
+ statuses: statuses,
+ content: content
+ }
+ |> make_flag_data(additional)
+ |> insert(local)
+ end
+
def fetch_activities_for_context(context, opts \\ %{}) do
public = ["https://www.w3.org/ns/activitystreams#Public"]
diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex
index 6a89374d0..88f4779c8 100644
--- a/lib/pleroma/web/activity_pub/utils.ex
+++ b/lib/pleroma/web/activity_pub/utils.ex
@@ -598,4 +598,20 @@ defmodule Pleroma.Web.ActivityPub.Utils do
}
|> Map.merge(additional)
end
+
+ #### Flag-related helpers
+
+ def make_flag_data(params, additional) do
+ status_ap_ids = Enum.map(params.statuses || [], & &1.data["id"])
+ object = [params.account.ap_id] ++ status_ap_ids
+
+ %{
+ "type" => "Flag",
+ "actor" => params.actor.ap_id,
+ "content" => params.content,
+ "object" => object,
+ "context" => params.context
+ }
+ |> Map.merge(additional)
+ end
end
diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex
index 90b208e54..e788337cc 100644
--- a/lib/pleroma/web/common_api/common_api.ex
+++ b/lib/pleroma/web/common_api/common_api.ex
@@ -243,4 +243,31 @@ defmodule Pleroma.Web.CommonAPI do
_ -> true
end
end
+
+ def report(user, data) do
+ with {:account_id, %{"account_id" => account_id}} <- {:account_id, data},
+ {:account, %User{} = account} <- {:account, User.get_by_id(account_id)},
+ {:ok, content_html} <- make_report_content_html(data["comment"]),
+ {:ok, statuses} <- get_report_statuses(account, data),
+ {:ok, activity} <-
+ ActivityPub.flag(%{
+ context: Utils.generate_context_id(),
+ actor: user,
+ account: account,
+ statuses: statuses,
+ content: content_html
+ }) do
+ Enum.each(User.all_superusers(), fn superuser ->
+ superuser
+ |> Pleroma.AdminEmail.report(user, account, statuses, content_html)
+ |> Pleroma.Mailer.deliver_async()
+ end)
+
+ {:ok, activity}
+ else
+ {:error, err} -> {:error, err}
+ {:account_id, %{}} -> {:error, "Valid `account_id` required"}
+ {:account, nil} -> {:error, "Account not found"}
+ end
+ end
end
diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex
index abdeee947..1d3a314ce 100644
--- a/lib/pleroma/web/common_api/utils.ex
+++ b/lib/pleroma/web/common_api/utils.ex
@@ -322,4 +322,22 @@ defmodule Pleroma.Web.CommonAPI.Utils do
end
def maybe_extract_mentions(_), do: []
+
+ def make_report_content_html(nil), do: {:ok, nil}
+
+ def make_report_content_html(comment) do
+ max_size = Pleroma.Config.get([:instance, :max_report_comment_size], 1000)
+
+ if String.length(comment) <= max_size do
+ {:ok, format_input(comment, [], [], "text/plain")}
+ else
+ {:error, "Comment must be up to #{max_size} characters"}
+ end
+ end
+
+ def get_report_statuses(%User{ap_id: actor}, %{"status_ids" => status_ids}) do
+ {:ok, Activity.all_by_actor_and_id(actor, status_ids)}
+ end
+
+ def get_report_statuses(_, _), do: {:ok, nil}
end
diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
index 17b95eb44..60738301b 100644
--- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
+++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
@@ -24,6 +24,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
alias Pleroma.Web.MastodonAPI.MastodonView
alias Pleroma.Web.MastodonAPI.PushSubscriptionView
alias Pleroma.Web.MastodonAPI.StatusView
+ alias Pleroma.Web.MastodonAPI.ReportView
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.OAuth.App
@@ -1533,6 +1534,20 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
end
end
+ def reports(%{assigns: %{user: user}} = conn, params) do
+ case CommonAPI.report(user, params) do
+ {:ok, activity} ->
+ conn
+ |> put_view(ReportView)
+ |> try_render("report.json", %{activity: activity})
+
+ {:error, err} ->
+ conn
+ |> put_status(:bad_request)
+ |> json(%{error: err})
+ end
+ end
+
def try_render(conn, target, params)
when is_binary(target) do
res = render(conn, target, params)
diff --git a/lib/pleroma/web/mastodon_api/views/report_view.ex b/lib/pleroma/web/mastodon_api/views/report_view.ex
new file mode 100644
index 000000000..a16e7ff10
--- /dev/null
+++ b/lib/pleroma/web/mastodon_api/views/report_view.ex
@@ -0,0 +1,14 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.MastodonAPI.ReportView do
+ use Pleroma.Web, :view
+
+ def render("report.json", %{activity: activity}) do
+ %{
+ id: to_string(activity.id),
+ action_taken: false
+ }
+ end
+end
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index 559d3aa0c..357ed7843 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -275,6 +275,8 @@ defmodule Pleroma.Web.Router do
delete("/filters/:id", MastodonAPIController, :delete_filter)
post("/pleroma/flavour/:flavour", MastodonAPIController, :set_flavour)
+
+ post("/reports", MastodonAPIController, :reports)
end
scope [] do
diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex
index db521a3ad..efdd0bf43 100644
--- a/lib/pleroma/web/twitter_api/twitter_api.ex
+++ b/lib/pleroma/web/twitter_api/twitter_api.ex
@@ -216,7 +216,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
{:ok, token_record} <- Pleroma.PasswordResetToken.create_token(user) do
user
|> UserEmail.password_reset_email(token_record.token)
- |> Mailer.deliver()
+ |> Mailer.deliver_async()
else
false ->
{:error, "bad user identifier"}