summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/pleroma/web/activity_pub/publisher.ex74
-rw-r--r--lib/pleroma/web/activity_pub/publisher/prepared.ex8
-rw-r--r--lib/pleroma/web/api_spec/operations/status_operation.ex8
-rw-r--r--lib/pleroma/web/federator.ex5
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/status_controller.ex3
-rw-r--r--lib/pleroma/web/plugs/o_auth_plug.ex2
6 files changed, 76 insertions, 24 deletions
diff --git a/lib/pleroma/web/activity_pub/publisher.ex b/lib/pleroma/web/activity_pub/publisher.ex
index f71652cb7..5cd982c6a 100644
--- a/lib/pleroma/web/activity_pub/publisher.ex
+++ b/lib/pleroma/web/activity_pub/publisher.ex
@@ -11,6 +11,7 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.User
+ alias Pleroma.Web.ActivityPub.Publisher.Prepared
alias Pleroma.Web.ActivityPub.Relay
alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Workers.PublisherWorker
@@ -76,14 +77,13 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
end
@doc """
- Publish a single message to a peer. Takes a struct with the following
- parameters set:
-
+ Prepare an activity for publishing from an Oban job
* `inbox`: the inbox to publish to
* `activity_id`: the internal activity id
* `cc`: the cc recipients relevant to this inbox (optional)
"""
- def publish_one(%{inbox: inbox, activity_id: activity_id} = params) do
+ @spec prepare_one(map()) :: Prepared.t()
+ def prepare_one(%{inbox: inbox, activity_id: activity_id} = params) do
activity = Activity.get_by_id_with_user_actor(activity_id)
actor = activity.user_actor
@@ -93,7 +93,7 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
{:ok, data} = Transmogrifier.prepare_outgoing(activity.data)
- cc = Map.get(params, :cc)
+ cc = Map.get(params, :cc, [])
json =
data
@@ -113,27 +113,49 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
date: date
})
+ %Prepared{
+ activity_id: activity_id,
+ json: json,
+ date: date,
+ signature: signature,
+ digest: digest,
+ inbox: inbox,
+ unreachable_since: params[:unreachable_since]
+ }
+ end
+
+ @doc """
+ Publish a single message to a peer. Takes a struct with the following
+ parameters set:
+ * `activity_id`: the activity id
+ * `json`: the json payload
+ * `date`: the signed date from Pleroma.Signature.signed_date()
+ * `signature`: the signature from Pleroma.Signature.sign/2
+ * `digest`: base64 encoded the hash of the json payload prefixed with "SHA-256="
+ * `inbox`: the inbox URI of this delivery
+ * `unreachable_since`: timestamp the instance was marked unreachable
+
+ """
+ def publish_one(%Prepared{} = p) do
with {:ok, %{status: code}} = result when code in 200..299 <-
HTTP.post(
- inbox,
- json,
+ p.inbox,
+ p.json,
[
{"Content-Type", "application/activity+json"},
- {"Date", date},
- {"signature", signature},
- {"digest", digest}
+ {"Date", p.date},
+ {"signature", p.signature},
+ {"digest", p.digest}
]
) do
- if not Map.has_key?(params, :unreachable_since) || params[:unreachable_since] do
- Instances.set_reachable(inbox)
- end
+ maybe_set_reachable(p.unreachable_since, p.inbox)
result
else
{_post_result, %{status: code} = response} = e ->
- unless params[:unreachable_since], do: Instances.set_unreachable(inbox)
- Logger.metadata(activity: activity_id, inbox: inbox, status: code)
- Logger.error("Publisher failed to inbox #{inbox} with status #{code}")
+ maybe_set_unreachable(p.unreachable_since, p.inbox)
+ Logger.metadata(activity: p.activity_id, inbox: p.inbox, status: code)
+ Logger.error("Publisher failed to inbox #{p.inbox} with status #{code}")
case response do
%{status: 400} -> {:cancel, :bad_request}
@@ -143,18 +165,30 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
_ -> {:error, e}
end
+ {:error, {:already_started, _}} ->
+ Logger.debug("Publisher snoozing worker job due worker :already_started race condition")
+ connection_pool_snooze()
+
{:error, :pool_full} ->
Logger.debug("Publisher snoozing worker job due to full connection pool")
- {:snooze, 30}
+ connection_pool_snooze()
e ->
- unless params[:unreachable_since], do: Instances.set_unreachable(inbox)
- Logger.metadata(activity: activity_id, inbox: inbox)
- Logger.error("Publisher failed to inbox #{inbox} #{inspect(e)}")
+ maybe_set_unreachable(p.unreachable_since, p.inbox)
+ Logger.metadata(activity: p.activity_id, inbox: p.inbox)
+ Logger.error("Publisher failed to inbox #{p.inbox} #{inspect(e)}")
{:error, e}
end
end
+ defp connection_pool_snooze, do: {:snooze, 3}
+
+ defp maybe_set_reachable(%NaiveDateTime{}, inbox), do: Instances.set_reachable(inbox)
+ defp maybe_set_reachable(_, _), do: :ok
+
+ defp maybe_set_unreachable(nil, inbox), do: Instances.set_unreachable(inbox)
+ defp maybe_set_unreachable(%NaiveDateTime{}, _), do: :ok
+
defp signature_host(%URI{port: port, scheme: scheme, host: host}) do
if port == URI.default_port(scheme) do
host
diff --git a/lib/pleroma/web/activity_pub/publisher/prepared.ex b/lib/pleroma/web/activity_pub/publisher/prepared.ex
new file mode 100644
index 000000000..ddd8167e1
--- /dev/null
+++ b/lib/pleroma/web/activity_pub/publisher/prepared.ex
@@ -0,0 +1,8 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.Publisher.Prepared do
+ @type t :: %__MODULE__{}
+ defstruct [:activity_id, :json, :date, :signature, :digest, :inbox, :unreachable_since]
+end
diff --git a/lib/pleroma/web/api_spec/operations/status_operation.ex b/lib/pleroma/web/api_spec/operations/status_operation.ex
index 1717c68c8..ef828feee 100644
--- a/lib/pleroma/web/api_spec/operations/status_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/status_operation.ex
@@ -31,12 +31,18 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
security: [%{"oAuth" => ["read:statuses"]}],
parameters: [
Operation.parameter(
- :ids,
+ :id,
:query,
%Schema{type: :array, items: FlakeID},
"Array of status IDs"
),
Operation.parameter(
+ :ids,
+ :query,
+ %Schema{type: :array, items: FlakeID},
+ "Deprecated, use `id` instead"
+ ),
+ Operation.parameter(
:with_muted,
:query,
BooleanLike.schema(),
diff --git a/lib/pleroma/web/federator.ex b/lib/pleroma/web/federator.ex
index c740fc85f..2df716556 100644
--- a/lib/pleroma/web/federator.ex
+++ b/lib/pleroma/web/federator.ex
@@ -80,7 +80,10 @@ defmodule Pleroma.Web.Federator do
# Job Worker Callbacks
@spec perform(atom(), any()) :: {:ok, any()} | {:error, any()}
- def perform(:publish_one, params), do: Publisher.publish_one(params)
+ def perform(:publish_one, params) do
+ Publisher.prepare_one(params)
+ |> Publisher.publish_one()
+ end
def perform(:publish, activity) do
Logger.debug(fn -> "Running publish for #{activity.data["id"]}" end)
diff --git a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex
index b9b236920..d5aef5ad2 100644
--- a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex
@@ -111,10 +111,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
`ids` query param is required
"""
def index(
- %{assigns: %{user: user}, private: %{open_api_spex: %{params: %{ids: ids} = params}}} =
+ %{assigns: %{user: user}, private: %{open_api_spex: %{params: params}}} =
conn,
_
) do
+ ids = Map.get(params, :id, Map.get(params, :ids))
limit = 100
activities =
diff --git a/lib/pleroma/web/plugs/o_auth_plug.ex b/lib/pleroma/web/plugs/o_auth_plug.ex
index b59ac9d3e..488968691 100644
--- a/lib/pleroma/web/plugs/o_auth_plug.ex
+++ b/lib/pleroma/web/plugs/o_auth_plug.ex
@@ -52,7 +52,7 @@ defmodule Pleroma.Web.Plugs.OAuthPlug do
where: t.token == ^token
)
- with %Token{user_id: user_id} = token_record <- Repo.one(token_query),
+ with %Token{user_id: user_id} = token_record <- Repo.one(token_query) |> Repo.preload(:user),
false <- is_nil(user_id),
%User{} = user <- User.get_cached_by_id(user_id) do
{:ok, user, token_record}