Include Mastodon admin API views, use worker

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
marcin mikołajczak 2024-08-16 22:27:27 +02:00
parent e2df638432
commit 682350ae1f
6 changed files with 227 additions and 11 deletions

View file

@ -0,0 +1,65 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2024 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MastodonAPI.Admin.AccountView do
use Pleroma.Web, :view
alias Pleroma.User
alias Pleroma.Web.CommonAPI.Utils
alias Pleroma.Web.MastodonAPI
def render("index.json", %{users: users}) do
render_many(users, __MODULE__, "show.json", as: :user)
end
def render("show.json", %{user: user}) do
account =
MastodonAPI.AccountView.render("show.json", %{user: user, skip_visibility_check: true})
%{
id: user.id,
username: username_from_nickname(user.nickname),
domain: domain_from_nickname(user.nickname),
created_at: Utils.to_masto_date(user.inserted_at),
email: user.email,
ip: nil,
role: role(user),
confirmed: user.is_confirmed,
sensitized: nil,
suspened: nil,
silenced: nil,
disabled: !user.is_active,
approved: user.is_approved,
locale: nil,
invite_request: user.registration_reason,
ips: nil,
account: account
}
end
defp username_from_nickname(string) when is_binary(string) do
hd(String.split(string, "@"))
end
defp username_from_nickname(_), do: nil
defp domain_from_nickname(string) when is_binary(string) do
String.split(string, "@")
|> Enum.at(1, nil)
end
defp domain_from_nickname(_), do: nil
defp role(%User{is_admin: true}) do
"admin"
end
defp role(%User{is_moderator: true}) do
"moderator"
end
defp role(_user) do
nil
end
end

View file

@ -0,0 +1,54 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2024 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MastodonAPI.Admin.ReportView do
use Pleroma.Web, :view
alias Pleroma.HTML
alias Pleroma.Web.AdminAPI.Report
alias Pleroma.Web.CommonAPI.Utils
alias Pleroma.Web.MastodonAPI.Admin.AccountView
alias Pleroma.Web.MastodonAPI.StatusView
def render("index.json", %{reports: reports}) do
reports
|> Enum.map(&Report.extract_report_info/1)
|> Enum.map(&render(__MODULE__, "show.json", &1))
end
def render("show.json", %{
report: report,
user: account,
account: target_account,
statuses: statuses
}) do
created_at = Utils.to_masto_date(report.data["published"])
content =
unless is_nil(report.data["content"]) do
HTML.filter_tags(report.data["content"])
else
nil
end
%{
id: report.id,
action_taken: report.data["state"] != "open",
category: "other",
comment: content,
created_at: created_at,
updated_at: created_at,
account: AccountView.render("show.json", %{user: account}),
target_account: AccountView.render("show.json", %{user: target_account}),
assigned_account: nil,
action_taken_by_account: nil,
statuses:
StatusView.render("index.json", %{
activities: statuses,
as: :activity
}),
rules: []
}
end
end

View file

@ -8,28 +8,39 @@ defmodule Pleroma.Webhook.Notify do
alias Pleroma.User
alias Pleroma.Web.AdminAPI.Report
alias Pleroma.Webhook
alias Pleroma.Workers.WebhookWorker
def trigger_webhooks(%Activity{} = activity, :"report.created" = type) do
webhooks = Webhook.get_by_type(type)
Enum.each(webhooks, fn webhook ->
ConcurrentLimiter.limit(Webhook.Notify, fn ->
Task.start(fn -> report_created(webhook, activity) end)
end)
webhooks
|> Enum.map(fn webhook ->
WebhookWorker.new(%{
"op" => "notify",
"type" => type,
"webhook_id" => webhook.id,
"activity_id" => activity.id
})
end)
|> Oban.insert_all()
end
def trigger_webhooks(%User{} = user, :"account.created" = type) do
webhooks = Webhook.get_by_type(type)
Enum.each(webhooks, fn webhook ->
ConcurrentLimiter.limit(Webhook.Notify, fn ->
Task.start(fn -> account_created(webhook, user) end)
end)
webhooks
|> Enum.map(fn webhook ->
WebhookWorker.new(%{
"op" => "notify",
"type" => type,
"webhook_id" => webhook.id,
"user_id" => user.id
})
end)
|> Oban.insert_all()
end
defp report_created(%Webhook{} = webhook, %Activity{} = report) do
def report_created(%Webhook{} = webhook, %Activity{} = report) do
object =
View.render(
Pleroma.Web.MastodonAPI.Admin.ReportView,
@ -40,7 +51,7 @@ defmodule Pleroma.Webhook.Notify do
deliver(webhook, object, :"report.created")
end
defp account_created(%Webhook{} = webhook, %User{} = user) do
def account_created(%Webhook{} = webhook, %User{} = user) do
object =
View.render(
Pleroma.Web.MastodonAPI.Admin.AccountView,

View file

@ -0,0 +1,41 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Workers.WebhookWorker do
alias Pleroma.Activity
use Oban.Worker, queue: :background
@impl true
def perform(%Job{
args: %{
"op" => "notify",
"type" => "report.created",
"webhook_id" => webhook_id,
"activity_id" => report_id
}
}) do
webhook = Pleroma.Webhook.get(webhook_id)
report = Activity.get_by_id(report_id)
Pleroma.Webhook.Notify.report_created(webhook, report)
end
def perform(%Job{
args: %{
"op" => "notify",
"type" => "account.created",
"webhook_id" => webhook_id,
"user_id" => user_id
}
}) do
webhook = Pleroma.Webhook.get(webhook_id)
user = Pleroma.User.get_by_id(user_id)
Pleroma.Webhook.Notify.account_created(webhook, user)
end
@impl true
def timeout(_job), do: :timer.seconds(10)
end

View file

@ -10,6 +10,52 @@ defmodule Pleroma.Webhook.NotifyTest do
import Pleroma.Factory
test "triggers a webhook for a report" do
%{id: activity_id} = activity = insert(:report_activity)
url = "https://example.com/webhook"
Webhook.create(%{url: url, events: [:"report.created"]})
Tesla.Mock.mock(fn %{url: ^url, body: body} = _ ->
report =
body
|> Jason.decode!()
|> Map.get("object")
assert %{"id" => ^activity_id} = report
%Tesla.Env{status: 200, body: ""}
end)
[job] = Notify.trigger_webhooks(activity, :"report.created")
Pleroma.Workers.WebhookWorker.perform(job)
end
test "triggers a webhook for an account" do
%{id: account_id} = user = insert(:user)
url = "https://example.com/webhook"
Webhook.create(%{url: url, events: [:"account.created"]})
Tesla.Mock.mock(fn %{url: ^url, body: body} = _ ->
report =
body
|> Jason.decode!()
|> Map.get("object")
assert %{"id" => ^account_id} = report
%Tesla.Env{status: 200, body: ""}
end)
[job] = Notify.trigger_webhooks(user, :"account.created")
Pleroma.Workers.WebhookWorker.perform(job)
end
test "notifies have a valid signature" do
activity = insert(:report_activity)

View file

@ -5,7 +5,6 @@
defmodule Pleroma.WebhookTest do
use Pleroma.DataCase, async: true
alias Pleroma.Repo
alias Pleroma.Webhook
test "creating a webhook" do