Merge branch 'remove-multiple-federator-modules' into 'develop'

Remove support for multiple federation publisher modules

See merge request pleroma/pleroma!4019
This commit is contained in:
Haelwenn 2023-12-29 03:35:24 +00:00
commit 7f3a83d3ed
10 changed files with 60 additions and 141 deletions

View File

@ -0,0 +1 @@
Removed support for multiple federator modules as we only support ActivityPub

View File

@ -192,9 +192,6 @@ config :pleroma, :instance,
federating: true, federating: true,
federation_incoming_replies_max_depth: 100, federation_incoming_replies_max_depth: 100,
federation_reachability_timeout_days: 7, federation_reachability_timeout_days: 7,
federation_publisher_modules: [
Pleroma.Web.ActivityPub.Publisher
],
allow_relay: true, allow_relay: true,
public: true, public: true,
quarantined_instances: [], quarantined_instances: [],

View File

@ -13,19 +13,56 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.ActivityPub.Relay alias Pleroma.Web.ActivityPub.Relay
alias Pleroma.Web.ActivityPub.Transmogrifier alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Workers.PublisherWorker
require Pleroma.Constants require Pleroma.Constants
import Pleroma.Web.ActivityPub.Visibility import Pleroma.Web.ActivityPub.Visibility
@behaviour Pleroma.Web.Federator.Publisher
require Logger require Logger
@moduledoc """ @moduledoc """
ActivityPub outgoing federation module. ActivityPub outgoing federation module.
""" """
@doc """
Enqueue publishing a single activity.
"""
@spec enqueue_one(Map.t(), Keyword.t()) :: {:ok, %Oban.Job{}}
def enqueue_one(%{} = params, worker_args \\ []) do
PublisherWorker.enqueue(
"publish_one",
%{"params" => params},
worker_args
)
end
@doc """
Gathers a set of remote users given an IR envelope.
"""
def remote_users(%User{id: user_id}, %{data: %{"to" => to} = data}) do
cc = Map.get(data, "cc", [])
bcc =
data
|> Map.get("bcc", [])
|> Enum.reduce([], fn ap_id, bcc ->
case Pleroma.List.get_by_ap_id(ap_id) do
%Pleroma.List{user_id: ^user_id} = list ->
{:ok, following} = Pleroma.List.get_following(list)
bcc ++ Enum.map(following, & &1.ap_id)
_ ->
bcc
end
end)
[to, cc, bcc]
|> Enum.concat()
|> Enum.map(&User.get_cached_by_ap_id/1)
|> Enum.filter(fn user -> user && !user.local end)
end
@doc """ @doc """
Determine if an activity can be represented by running it through Transmogrifier. Determine if an activity can be represented by running it through Transmogrifier.
""" """
@ -138,7 +175,7 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
[] []
end end
mentioned = Pleroma.Web.Federator.Publisher.remote_users(actor, activity) mentioned = remote_users(actor, activity)
non_mentioned = (followers ++ fetchers) -- mentioned non_mentioned = (followers ++ fetchers) -- mentioned
[mentioned, non_mentioned] [mentioned, non_mentioned]
@ -223,7 +260,7 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
|> Map.put("cc", cc) |> Map.put("cc", cc)
|> Jason.encode!() |> Jason.encode!()
Pleroma.Web.Federator.Publisher.enqueue_one(__MODULE__, %{ __MODULE__.enqueue_one(%{
inbox: inbox, inbox: inbox,
json: json, json: json,
actor_id: actor.id, actor_id: actor.id,
@ -262,8 +299,7 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
inboxes inboxes
|> Instances.filter_reachable() |> Instances.filter_reachable()
|> Enum.each(fn {inbox, unreachable_since} -> |> Enum.each(fn {inbox, unreachable_since} ->
Pleroma.Web.Federator.Publisher.enqueue_one( __MODULE__.enqueue_one(
__MODULE__,
%{ %{
inbox: inbox, inbox: inbox,
json: json, json: json,

View File

@ -6,9 +6,9 @@ defmodule Pleroma.Web.Federator do
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Object.Containment alias Pleroma.Object.Containment
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.ActivityPub.Publisher
alias Pleroma.Web.ActivityPub.Transmogrifier alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.Federator.Publisher
alias Pleroma.Workers.PublisherWorker alias Pleroma.Workers.PublisherWorker
alias Pleroma.Workers.ReceiverWorker alias Pleroma.Workers.ReceiverWorker

View File

@ -1,110 +0,0 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Federator.Publisher do
alias Pleroma.Activity
alias Pleroma.Config
alias Pleroma.User
alias Pleroma.Workers.PublisherWorker
require Logger
@moduledoc """
Defines the contract used by federation implementations to publish messages to
their peers.
"""
@doc """
Determine whether an activity can be relayed using the federation module.
"""
@callback is_representable?(Pleroma.Activity.t()) :: boolean()
@doc """
Relays an activity to a specified peer, determined by the parameters. The
parameters used are controlled by the federation module.
"""
@callback publish_one(Map.t()) :: {:ok, Map.t()} | {:error, any()}
@doc """
Enqueue publishing a single activity.
"""
@spec enqueue_one(module(), Map.t(), Keyword.t()) :: {:ok, %Oban.Job{}}
def enqueue_one(module, %{} = params, worker_args \\ []) do
PublisherWorker.enqueue(
"publish_one",
%{"module" => to_string(module), "params" => params},
worker_args
)
end
@doc """
Relays an activity to all specified peers.
"""
@callback publish(User.t(), Activity.t()) :: :ok | {:error, any()}
@spec publish(User.t(), Activity.t()) :: :ok
def publish(%User{} = user, %Activity{} = activity) do
Config.get([:instance, :federation_publisher_modules])
|> Enum.each(fn module ->
if module.is_representable?(activity) do
Logger.debug("Publishing #{activity.data["id"]} using #{inspect(module)}")
module.publish(user, activity)
end
end)
:ok
end
@doc """
Gathers links used by an outgoing federation module for WebFinger output.
"""
@callback gather_webfinger_links(User.t()) :: list()
@spec gather_webfinger_links(User.t()) :: list()
def gather_webfinger_links(%User{} = user) do
Config.get([:instance, :federation_publisher_modules])
|> Enum.reduce([], fn module, links ->
links ++ module.gather_webfinger_links(user)
end)
end
@doc """
Gathers nodeinfo protocol names supported by the federation module.
"""
@callback gather_nodeinfo_protocol_names() :: list()
@spec gather_nodeinfo_protocol_names() :: list()
def gather_nodeinfo_protocol_names do
Config.get([:instance, :federation_publisher_modules])
|> Enum.reduce([], fn module, links ->
links ++ module.gather_nodeinfo_protocol_names()
end)
end
@doc """
Gathers a set of remote users given an IR envelope.
"""
def remote_users(%User{id: user_id}, %{data: %{"to" => to} = data}) do
cc = Map.get(data, "cc", [])
bcc =
data
|> Map.get("bcc", [])
|> Enum.reduce([], fn ap_id, bcc ->
case Pleroma.List.get_by_ap_id(ap_id) do
%Pleroma.List{user_id: ^user_id} = list ->
{:ok, following} = Pleroma.List.get_following(list)
bcc ++ Enum.map(following, & &1.ap_id)
_ ->
bcc
end
end)
[to, cc, bcc]
|> Enum.concat()
|> Enum.map(&User.get_cached_by_ap_id/1)
|> Enum.filter(fn user -> user && !user.local end)
end
end

View File

@ -6,7 +6,7 @@ defmodule Pleroma.Web.Nodeinfo.Nodeinfo do
alias Pleroma.Config alias Pleroma.Config
alias Pleroma.Stats alias Pleroma.Stats
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.Federator.Publisher alias Pleroma.Web.ActivityPub.Publisher
alias Pleroma.Web.MastodonAPI.InstanceView alias Pleroma.Web.MastodonAPI.InstanceView
# returns a nodeinfo 2.0 map, since 2.1 just adds a repository field # returns a nodeinfo 2.0 map, since 2.1 just adds a repository field

View File

@ -5,8 +5,8 @@
defmodule Pleroma.Web.WebFinger do defmodule Pleroma.Web.WebFinger do
alias Pleroma.HTTP alias Pleroma.HTTP
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.ActivityPub.Publisher
alias Pleroma.Web.Endpoint alias Pleroma.Web.Endpoint
alias Pleroma.Web.Federator.Publisher
alias Pleroma.Web.XML alias Pleroma.Web.XML
alias Pleroma.XmlBuilder alias Pleroma.XmlBuilder
require Jason require Jason

View File

@ -18,9 +18,9 @@ defmodule Pleroma.Workers.PublisherWorker do
Federator.perform(:publish, activity) Federator.perform(:publish, activity)
end end
def perform(%Job{args: %{"op" => "publish_one", "module" => module_name, "params" => params}}) do def perform(%Job{args: %{"op" => "publish_one", "params" => params}}) do
params = Map.new(params, fn {k, v} -> {String.to_atom(k), v} end) params = Map.new(params, fn {k, v} -> {String.to_atom(k), v} end)
Federator.perform(:publish_one, String.to_atom(module_name), params) Federator.perform(:publish_one, params)
end end
@impl Oban.Worker @impl Oban.Worker

View File

@ -140,7 +140,6 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
federating: true, federating: true,
federation_incoming_replies_max_depth: 100, federation_incoming_replies_max_depth: 100,
federation_reachability_timeout_days: 7, federation_reachability_timeout_days: 7,
federation_publisher_modules: [Pleroma.Web.ActivityPub.Publisher],
allow_relay: true, allow_relay: true,
public: true, public: true,
quarantined_instances: [], quarantined_instances: [],
@ -184,7 +183,7 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
{:ok, file} = File.read(temp_file) {:ok, file} = File.read(temp_file)
assert file == assert file ==
"import Config\n\nconfig :pleroma, :instance,\n name: \"Pleroma\",\n email: \"example@example.com\",\n notify_email: \"noreply@example.com\",\n description: \"A Pleroma instance, an alternative fediverse server\",\n limit: 5000,\n chat_limit: 5000,\n remote_limit: 100_000,\n upload_limit: 16_000_000,\n avatar_upload_limit: 2_000_000,\n background_upload_limit: 4_000_000,\n banner_upload_limit: 4_000_000,\n poll_limits: %{\n max_expiration: 31_536_000,\n max_option_chars: 200,\n max_options: 20,\n min_expiration: 0\n },\n registrations_open: true,\n federating: true,\n federation_incoming_replies_max_depth: 100,\n federation_reachability_timeout_days: 7,\n federation_publisher_modules: [Pleroma.Web.ActivityPub.Publisher],\n allow_relay: true,\n public: true,\n quarantined_instances: [],\n managed_config: true,\n static_dir: \"instance/static/\",\n allowed_post_formats: [\"text/plain\", \"text/html\", \"text/markdown\", \"text/bbcode\"],\n autofollowed_nicknames: [],\n max_pinned_statuses: 1,\n attachment_links: false,\n max_report_comment_size: 1000,\n safe_dm_mentions: false,\n healthcheck: false,\n remote_post_retention_days: 90,\n skip_thread_containment: true,\n limit_to_local_content: :unauthenticated,\n user_bio_length: 5000,\n user_name_length: 100,\n max_account_fields: 10,\n max_remote_account_fields: 20,\n account_field_name_length: 512,\n account_field_value_length: 2048,\n external_user_synchronization: true,\n extended_nickname_format: true,\n multi_factor_authentication: [\n totp: [digits: 6, period: 30],\n backup_codes: [number: 2, length: 6]\n ]\n" "import Config\n\nconfig :pleroma, :instance,\n name: \"Pleroma\",\n email: \"example@example.com\",\n notify_email: \"noreply@example.com\",\n description: \"A Pleroma instance, an alternative fediverse server\",\n limit: 5000,\n chat_limit: 5000,\n remote_limit: 100_000,\n upload_limit: 16_000_000,\n avatar_upload_limit: 2_000_000,\n background_upload_limit: 4_000_000,\n banner_upload_limit: 4_000_000,\n poll_limits: %{\n max_expiration: 31_536_000,\n max_option_chars: 200,\n max_options: 20,\n min_expiration: 0\n },\n registrations_open: true,\n federating: true,\n federation_incoming_replies_max_depth: 100,\n federation_reachability_timeout_days: 7,\n allow_relay: true,\n public: true,\n quarantined_instances: [],\n managed_config: true,\n static_dir: \"instance/static/\",\n allowed_post_formats: [\"text/plain\", \"text/html\", \"text/markdown\", \"text/bbcode\"],\n autofollowed_nicknames: [],\n max_pinned_statuses: 1,\n attachment_links: false,\n max_report_comment_size: 1000,\n safe_dm_mentions: false,\n healthcheck: false,\n remote_post_retention_days: 90,\n skip_thread_containment: true,\n limit_to_local_content: :unauthenticated,\n user_bio_length: 5000,\n user_name_length: 100,\n max_account_fields: 10,\n max_remote_account_fields: 20,\n account_field_name_length: 512,\n account_field_value_length: 2048,\n external_user_synchronization: true,\n extended_nickname_format: true,\n multi_factor_authentication: [\n totp: [digits: 6, period: 30],\n backup_codes: [number: 2, length: 6]\n ]\n"
end end
end end

View File

@ -268,7 +268,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
describe "publish/2" do describe "publish/2" do
test_with_mock "doesn't publish a non-public activity to quarantined instances.", test_with_mock "doesn't publish a non-public activity to quarantined instances.",
Pleroma.Web.Federator.Publisher, Pleroma.Web.ActivityPub.Publisher,
[:passthrough], [:passthrough],
[] do [] do
Config.put([:instance, :quarantined_instances], [{"domain.com", "some reason"}]) Config.put([:instance, :quarantined_instances], [{"domain.com", "some reason"}])
@ -295,7 +295,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
assert res == :ok assert res == :ok
assert not called( assert not called(
Pleroma.Web.Federator.Publisher.enqueue_one(Publisher, %{ Publisher.enqueue_one(%{
inbox: "https://domain.com/users/nick1/inbox", inbox: "https://domain.com/users/nick1/inbox",
actor_id: actor.id, actor_id: actor.id,
id: note_activity.data["id"] id: note_activity.data["id"]
@ -304,7 +304,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
end end
test_with_mock "Publishes a non-public activity to non-quarantined instances.", test_with_mock "Publishes a non-public activity to non-quarantined instances.",
Pleroma.Web.Federator.Publisher, Pleroma.Web.ActivityPub.Publisher,
[:passthrough], [:passthrough],
[] do [] do
Config.put([:instance, :quarantined_instances], [{"somedomain.com", "some reason"}]) Config.put([:instance, :quarantined_instances], [{"somedomain.com", "some reason"}])
@ -331,8 +331,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
assert res == :ok assert res == :ok
assert called( assert called(
Pleroma.Web.Federator.Publisher.enqueue_one( Publisher.enqueue_one(
Publisher,
%{ %{
inbox: "https://domain.com/users/nick1/inbox", inbox: "https://domain.com/users/nick1/inbox",
actor_id: actor.id, actor_id: actor.id,
@ -344,7 +343,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
end end
test_with_mock "Publishes to directly addressed actors with higher priority.", test_with_mock "Publishes to directly addressed actors with higher priority.",
Pleroma.Web.Federator.Publisher, Pleroma.Web.ActivityPub.Publisher,
[:passthrough], [:passthrough],
[] do [] do
note_activity = insert(:direct_note_activity) note_activity = insert(:direct_note_activity)
@ -356,8 +355,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
assert res == :ok assert res == :ok
assert called( assert called(
Pleroma.Web.Federator.Publisher.enqueue_one( Publisher.enqueue_one(
Publisher,
%{ %{
inbox: :_, inbox: :_,
actor_id: actor.id, actor_id: actor.id,
@ -369,7 +367,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
end end
test_with_mock "publishes an activity with BCC to all relevant peers.", test_with_mock "publishes an activity with BCC to all relevant peers.",
Pleroma.Web.Federator.Publisher, Pleroma.Web.ActivityPub.Publisher,
[:passthrough], [:passthrough],
[] do [] do
follower = follower =
@ -393,7 +391,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
assert res == :ok assert res == :ok
assert called( assert called(
Pleroma.Web.Federator.Publisher.enqueue_one(Publisher, %{ Publisher.enqueue_one(%{
inbox: "https://domain.com/users/nick1/inbox", inbox: "https://domain.com/users/nick1/inbox",
actor_id: actor.id, actor_id: actor.id,
id: note_activity.data["id"] id: note_activity.data["id"]
@ -402,7 +400,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
end end
test_with_mock "publishes a delete activity to peers who signed fetch requests to the create acitvity/object.", test_with_mock "publishes a delete activity to peers who signed fetch requests to the create acitvity/object.",
Pleroma.Web.Federator.Publisher, Pleroma.Web.ActivityPub.Publisher,
[:passthrough], [:passthrough],
[] do [] do
fetcher = fetcher =
@ -443,8 +441,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
assert res == :ok assert res == :ok
assert called( assert called(
Pleroma.Web.Federator.Publisher.enqueue_one( Publisher.enqueue_one(
Publisher,
%{ %{
inbox: "https://domain.com/users/nick1/inbox", inbox: "https://domain.com/users/nick1/inbox",
actor_id: actor.id, actor_id: actor.id,
@ -455,8 +452,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
) )
assert called( assert called(
Pleroma.Web.Federator.Publisher.enqueue_one( Publisher.enqueue_one(
Publisher,
%{ %{
inbox: "https://domain2.com/users/nick1/inbox", inbox: "https://domain2.com/users/nick1/inbox",
actor_id: actor.id, actor_id: actor.id,