logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma git clone https://hacktivis.me/git/pleroma.git

publisher.ex (3146B)


  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Pleroma.Web.Federator.Publisher do
  5. alias Pleroma.Activity
  6. alias Pleroma.Config
  7. alias Pleroma.User
  8. alias Pleroma.Workers.PublisherWorker
  9. require Logger
  10. @moduledoc """
  11. Defines the contract used by federation implementations to publish messages to
  12. their peers.
  13. """
  14. @doc """
  15. Determine whether an activity can be relayed using the federation module.
  16. """
  17. @callback is_representable?(Pleroma.Activity.t()) :: boolean()
  18. @doc """
  19. Relays an activity to a specified peer, determined by the parameters. The
  20. parameters used are controlled by the federation module.
  21. """
  22. @callback publish_one(Map.t()) :: {:ok, Map.t()} | {:error, any()}
  23. @doc """
  24. Enqueue publishing a single activity.
  25. """
  26. @spec enqueue_one(module(), Map.t()) :: :ok
  27. def enqueue_one(module, %{} = params) do
  28. PublisherWorker.enqueue(
  29. "publish_one",
  30. %{"module" => to_string(module), "params" => params}
  31. )
  32. end
  33. @doc """
  34. Relays an activity to all specified peers.
  35. """
  36. @callback publish(User.t(), Activity.t()) :: :ok | {:error, any()}
  37. @spec publish(User.t(), Activity.t()) :: :ok
  38. def publish(%User{} = user, %Activity{} = activity) do
  39. Config.get([:instance, :federation_publisher_modules])
  40. |> Enum.each(fn module ->
  41. if module.is_representable?(activity) do
  42. Logger.debug("Publishing #{activity.data["id"]} using #{inspect(module)}")
  43. module.publish(user, activity)
  44. end
  45. end)
  46. :ok
  47. end
  48. @doc """
  49. Gathers links used by an outgoing federation module for WebFinger output.
  50. """
  51. @callback gather_webfinger_links(User.t()) :: list()
  52. @spec gather_webfinger_links(User.t()) :: list()
  53. def gather_webfinger_links(%User{} = user) do
  54. Config.get([:instance, :federation_publisher_modules])
  55. |> Enum.reduce([], fn module, links ->
  56. links ++ module.gather_webfinger_links(user)
  57. end)
  58. end
  59. @doc """
  60. Gathers nodeinfo protocol names supported by the federation module.
  61. """
  62. @callback gather_nodeinfo_protocol_names() :: list()
  63. @spec gather_nodeinfo_protocol_names() :: list()
  64. def gather_nodeinfo_protocol_names do
  65. Config.get([:instance, :federation_publisher_modules])
  66. |> Enum.reduce([], fn module, links ->
  67. links ++ module.gather_nodeinfo_protocol_names()
  68. end)
  69. end
  70. @doc """
  71. Gathers a set of remote users given an IR envelope.
  72. """
  73. def remote_users(%User{id: user_id}, %{data: %{"to" => to} = data}) do
  74. cc = Map.get(data, "cc", [])
  75. bcc =
  76. data
  77. |> Map.get("bcc", [])
  78. |> Enum.reduce([], fn ap_id, bcc ->
  79. case Pleroma.List.get_by_ap_id(ap_id) do
  80. %Pleroma.List{user_id: ^user_id} = list ->
  81. {:ok, following} = Pleroma.List.get_following(list)
  82. bcc ++ Enum.map(following, & &1.ap_id)
  83. _ ->
  84. bcc
  85. end
  86. end)
  87. [to, cc, bcc]
  88. |> Enum.concat()
  89. |> Enum.map(&User.get_cached_by_ap_id/1)
  90. |> Enum.filter(fn user -> user && !user.local end)
  91. end
  92. end