aboutsummaryrefslogtreecommitdiff
path: root/lib/pleroma/web/federator/publisher.ex
diff options
context:
space:
mode:
authordcc <dcc@logografos.com>2023-09-02 00:52:52 -0700
committerdcc <dcc@logografos.com>2023-09-02 00:52:52 -0700
commit3a4773c3c2bd0bbef244eb519b07208da9108e49 (patch)
tree973567a6f3abb37bfb0f785b1cad14ed55840ef5 /lib/pleroma/web/federator/publisher.ex
downloadanni-3a4773c3c2bd0bbef244eb519b07208da9108e49.tar.gz
anni-3a4773c3c2bd0bbef244eb519b07208da9108e49.tar.bz2
anni-3a4773c3c2bd0bbef244eb519b07208da9108e49.zip
First
Diffstat (limited to 'lib/pleroma/web/federator/publisher.ex')
-rw-r--r--lib/pleroma/web/federator/publisher.ex109
1 files changed, 109 insertions, 0 deletions
diff --git a/lib/pleroma/web/federator/publisher.ex b/lib/pleroma/web/federator/publisher.ex
new file mode 100644
index 0000000..a45796e
--- /dev/null
+++ b/lib/pleroma/web/federator/publisher.ex
@@ -0,0 +1,109 @@
+# 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()) :: :ok
+ def enqueue_one(module, %{} = params) do
+ PublisherWorker.enqueue(
+ "publish_one",
+ %{"module" => to_string(module), "params" => params}
+ )
+ 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