# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Object.Fetcher do
+ @behaviour HTTPSignatures.Adapter
alias Pleroma.HTTP
alias Pleroma.Instances
alias Pleroma.Maps
+ alias Pleroma.Keys
alias Pleroma.Object
alias Pleroma.Object.Containment
alias Pleroma.Signature
{:object, data, Object.normalize(activity, fetch: false)} do
{:ok, object}
else
- {:allowed_depth, false} ->
- {:error, "Max thread distance exceeded."}
+ {:allowed_depth, false} = e ->
+ log_fetch_error(id, e)
+ {:error, :allowed_depth}
- {:containment, _} ->
- {:error, "Object containment failed."}
+ {:containment, reason} = e ->
+ log_fetch_error(id, e)
+ {:error, reason}
- {:transmogrifier, {:error, {:reject, e}}} ->
- {:reject, e}
+ {:transmogrifier, {:error, {:reject, reason}}} = e ->
+ log_fetch_error(id, e)
+ {:reject, reason}
- {:transmogrifier, {:reject, e}} ->
- {:reject, e}
+ {:transmogrifier, {:reject, reason}} = e ->
+ log_fetch_error(id, e)
+ {:reject, reason}
- {:transmogrifier, _} = e ->
- {:error, e}
+ {:transmogrifier, reason} = e ->
+ log_fetch_error(id, e)
+ {:error, reason}
{:object, data, nil} ->
reinject_object(%Object{}, data)
{:fetch_object, %Object{} = object} ->
{:ok, object}
- {:fetch, {:error, error}} ->
- {:error, error}
+ {:fetch, {:error, reason}} = e ->
+ log_fetch_error(id, e)
+ {:error, reason}
e ->
- e
+ log_fetch_error(id, e)
+ {:error, e}
end
end
+ defp log_fetch_error(id, error) do
+ Logger.metadata(object: id)
+ Logger.error("Object rejected while fetching #{id} #{inspect(error)}")
+ end
+
defp prepare_activity_params(data) do
%{
"type" => "Create",
|> Maps.put_if_present("bcc", data["bcc"])
end
- def fetch_object_from_id!(id, options \\ []) do
- with {:ok, object} <- fetch_object_from_id(id, options) do
- object
- else
- {:error, %Tesla.Mock.Error{}} ->
- nil
-
- {:error, "Object has been deleted"} ->
- nil
-
- {:reject, reason} ->
- Logger.info("Rejected #{id} while fetching: #{inspect(reason)}")
- nil
-
- e ->
- Logger.error("Error while fetching #{id}: #{inspect(e)}")
- nil
- end
- end
-
defp make_signature(id, date) do
uri = URI.parse(id)
- signature =
+ spoofed_pem = Pleroma.Config.get([:activitypub, :spoofed_key])
+ # workaround for syntax shite disallowing me from defining signature in "if" block
+ spoofed_key = if Pleroma.Config.get([:activitypub, :spoof_object_fetch_signatures]) do
+ with {:ok, private_key, _} <- Keys.keys_from_pem(spoofed_pem) do
+ private_key
+ end
+ else
+ ""
+ end
+ spoofed_instance = Pleroma.Config.get([:activitypub, :spoofed_instance])
+
+ signature = if Pleroma.Config.get([:activitypub, :spoof_object_fetch_signatures]) do
+ HTTPSignatures.sign(spoofed_key, spoofed_instance <> "/internal/fetch#main-key", %{
+ "(request-target)": "get #{uri.path}",
+ host: uri.host,
+ date: date
+ })
+ else
InternalFetchActor.get_actor()
|> Signature.sign(%{
"(request-target)": "get #{uri.path}",
host: uri.host,
date: date
})
+ end
{"signature", signature}
end
{:error, {:content_type, nil}}
end
+ {:ok, %{status: code}} when code in [401, 403] ->
+ {:error, :forbidden}
+
{:ok, %{status: code}} when code in [404, 410] ->
- {:error, "Object has been deleted"}
+ {:error, :not_found}
{:error, e} ->
{:error, e}