74
lib/federation/activity_pub/fetcher.ex
Normal file
74
lib/federation/activity_pub/fetcher.ex
Normal file
@@ -0,0 +1,74 @@
|
||||
defmodule Mobilizon.Federation.ActivityPub.Fetcher do
|
||||
@moduledoc """
|
||||
Module to handle direct URL ActivityPub fetches to remote content
|
||||
|
||||
If you need to first get cached data, see `Mobilizon.Federation.ActivityPub.fetch_object_from_url/2`
|
||||
"""
|
||||
require Logger
|
||||
|
||||
alias Mobilizon.Federation.HTTPSignatures.Signature
|
||||
alias Mobilizon.Federation.ActivityPub.{Relay, Transmogrifier}
|
||||
alias Mobilizon.Service.HTTP.ActivityPub, as: ActivityPubClient
|
||||
|
||||
import Mobilizon.Federation.ActivityPub.Utils,
|
||||
only: [maybe_date_fetch: 2, sign_fetch: 4, origin_check?: 2]
|
||||
|
||||
@spec fetch(String.t(), Keyword.t()) :: {:ok, map()}
|
||||
def fetch(url, options \\ []) do
|
||||
on_behalf_of = Keyword.get(options, :on_behalf_of, Relay.get_actor())
|
||||
|
||||
with date <- Signature.generate_date_header(),
|
||||
headers <-
|
||||
[{:Accept, "application/activity+json"}]
|
||||
|> maybe_date_fetch(date)
|
||||
|> sign_fetch(on_behalf_of, url, date),
|
||||
client <-
|
||||
ActivityPubClient.client(headers: headers),
|
||||
{:ok, %Tesla.Env{body: data, status: code}} when code in 200..299 <-
|
||||
ActivityPubClient.get(client, url) do
|
||||
{:ok, data}
|
||||
end
|
||||
end
|
||||
|
||||
@spec fetch_and_create(String.t(), Keyword.t()) :: {:ok, map(), struct()}
|
||||
def fetch_and_create(url, options \\ []) do
|
||||
with {:ok, data} when is_map(data) <- fetch(url, options),
|
||||
:ok <- Logger.debug("inspect body from fetch_object_from_url #{url}"),
|
||||
:ok <- Logger.debug(inspect(data)),
|
||||
{:origin_check, true} <- {:origin_check, origin_check?(url, data)},
|
||||
params <- %{
|
||||
"type" => "Create",
|
||||
"to" => data["to"],
|
||||
"cc" => data["cc"],
|
||||
"actor" => data["attributedTo"] || data["actor"],
|
||||
"object" => data
|
||||
} do
|
||||
Transmogrifier.handle_incoming(params)
|
||||
else
|
||||
{:origin_check, false} ->
|
||||
Logger.warn("Object origin check failed")
|
||||
{:error, "Object origin check failed"}
|
||||
end
|
||||
end
|
||||
|
||||
@spec fetch_and_update(String.t(), Keyword.t()) :: {:ok, map(), struct()}
|
||||
def fetch_and_update(url, options \\ []) do
|
||||
with {:ok, data} when is_map(data) <- fetch(url, options),
|
||||
:ok <- Logger.debug("inspect body from fetch_object_from_url #{url}"),
|
||||
:ok <- Logger.debug(inspect(data)),
|
||||
{:origin_check, true} <- {:origin_check, origin_check?(url, data)},
|
||||
params <- %{
|
||||
"type" => "Update",
|
||||
"to" => data["to"],
|
||||
"cc" => data["cc"],
|
||||
"actor" => data["attributedTo"] || data["actor"],
|
||||
"object" => data
|
||||
} do
|
||||
Transmogrifier.handle_incoming(params)
|
||||
else
|
||||
{:origin_check, false} ->
|
||||
Logger.warn("Object origin check failed")
|
||||
{:error, "Object origin check failed"}
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user