Skip to content

Commit

Permalink
$INSTANCE$host$ replacement
Browse files Browse the repository at this point in the history
Signed-off-by: marcin mikołajczak <[email protected]>
  • Loading branch information
mkljczk committed Sep 2, 2024
1 parent f67e29b commit faa2f34
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 28 deletions.
18 changes: 14 additions & 4 deletions lib/pleroma/web/activity_pub/activity_pub_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,15 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
with ap_id <- Endpoint.url() <> conn.request_path,
%Object{} = object <- Object.get_cached_by_ap_id(ap_id),
user <- Map.get(assigns, :user, nil),
{_, true} <- {:visible?, Visibility.visible_for_user?(object, user)} do
{_, true} <- {:visible?, Visibility.visible_for_user?(object, user)},
host <- maybe_get_host(Map.get(assigns, :actor_id, nil)) do
conn
|> maybe_skip_cache(user)
|> assign(:tracking_fun_data, object.id)
|> set_cache_ttl_for(object)
|> put_resp_content_type("application/activity+json")
|> put_view(ObjectView)
|> render("object.json", object: object)
|> render("object.json", object: object, host: host)
else
{:visible?, false} -> {:error, :not_found}
nil -> {:error, :not_found}
Expand All @@ -121,21 +122,30 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
%Activity{} = activity <- Activity.normalize(ap_id),
{_, true} <- {:local?, activity.local},
user <- Map.get(assigns, :user, nil),
{_, true} <- {:visible?, Visibility.visible_for_user?(activity, user)} do
{_, true} <- {:visible?, Visibility.visible_for_user?(activity, user)},
host <- maybe_get_host(Map.get(assigns, :actor_id, nil)) do
conn
|> maybe_skip_cache(user)
|> maybe_set_tracking_data(activity)
|> set_cache_ttl_for(activity)
|> put_resp_content_type("application/activity+json")
|> put_view(ObjectView)
|> render("object.json", object: activity)
|> render("object.json", object: activity, host: host)
else
{:visible?, false} -> {:error, :not_found}
{:local?, false} -> {:error, :not_found}
nil -> {:error, :not_found}
end
end

defp maybe_get_host(actor_id) when is_binary(actor_id) do
%{host: host} = URI.parse(actor_id)

host
end

defp maybe_get_host(_), do: nil

defp maybe_set_tracking_data(conn, %Activity{data: %{"type" => "Create"}} = activity) do
object_id = Object.normalize(activity, fetch: false).id
assign(conn, :tracking_fun_data, object_id)
Expand Down
4 changes: 2 additions & 2 deletions lib/pleroma/web/activity_pub/publisher.ex
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ defmodule Pleroma.Web.ActivityPub.Publisher do

ap_id = activity.data["id"]
Logger.debug("Federating #{ap_id} to #{inbox}")
uri = %{path: path} = URI.parse(inbox)
uri = %{host: host, path: path} = URI.parse(inbox)

{:ok, data} = Transmogrifier.prepare_outgoing(activity.data)
{:ok, data} = Transmogrifier.prepare_outgoing(activity.data, host)

cc = Map.get(params, :cc, [])

Expand Down
77 changes: 63 additions & 14 deletions lib/pleroma/web/activity_pub/transmogrifier.ex
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
defp set_voters_count(obj), do: obj

# Prepares the object of an outgoing create activity.
def prepare_object(object) do
def prepare_object(object, host \\ nil) do
object
|> add_hashtags
|> add_mention_tags
Expand All @@ -738,23 +738,29 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|> strip_internal_fields
|> strip_internal_tags
|> set_type
|> maybe_process_history
|> maybe_process_history(host)
|> patch_object(host)
end

defp maybe_process_history(%{"formerRepresentations" => %{"orderedItems" => history}} = object) do
defp maybe_process_history(object, host)

defp maybe_process_history(
%{"formerRepresentations" => %{"orderedItems" => history}} = object,
host
) do
processed_history =
Enum.map(
history,
fn
item when is_map(item) -> prepare_object(item)
item when is_map(item) -> prepare_object(item, host)
item -> item
end
)

put_in(object, ["formerRepresentations", "orderedItems"], processed_history)
end

defp maybe_process_history(object) do
defp maybe_process_history(object, _host) do
object
end

Expand All @@ -763,7 +769,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
# internal -> Mastodon
# """

def prepare_outgoing(%{"type" => activity_type, "object" => object_id} = data)
def prepare_outgoing(data, host \\ nil)

def prepare_outgoing(%{"type" => activity_type, "object" => object_id} = data, host)
when activity_type in ["Create", "Listen"] do
object =
object_id
Expand All @@ -772,32 +780,38 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do

data =
data
|> Map.put("object", prepare_object(object))
|> Map.put("object", prepare_object(object, host))
|> Map.merge(Utils.make_json_ld_header(object))
|> Map.delete("bcc")

{:ok, data}
end

def prepare_outgoing(%{"type" => "Update", "object" => %{"type" => objtype} = object} = data)
def prepare_outgoing(
%{"type" => "Update", "object" => %{"type" => objtype} = object} = data,
host
)
when objtype in Pleroma.Constants.updatable_object_types() do
data =
data
|> Map.put("object", prepare_object(object))
|> Map.put("object", prepare_object(object, host))
|> Map.merge(Utils.make_json_ld_header(object))
|> Map.delete("bcc")

{:ok, data}
end

def prepare_outgoing(%{"type" => "Announce", "actor" => ap_id, "object" => object_id} = data) do
def prepare_outgoing(
%{"type" => "Announce", "actor" => ap_id, "object" => object_id} = data,
host
) do
object =
object_id
|> Object.normalize(fetch: false)

data =
if Visibility.private?(object) && object.data["actor"] == ap_id do
data |> Map.put("object", object |> Map.get(:data) |> prepare_object)
data |> Map.put("object", object |> Map.get(:data) |> prepare_object(host))
else
data |> maybe_fix_object_url
end
Expand All @@ -813,7 +827,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do

# Mastodon Accept/Reject requires a non-normalized object containing the actor URIs,
# because of course it does.
def prepare_outgoing(%{"type" => "Accept"} = data) do
def prepare_outgoing(%{"type" => "Accept"} = data, _host) do
with follow_activity <- Activity.normalize(data["object"]) do
object = %{
"actor" => follow_activity.actor,
Expand All @@ -831,7 +845,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
end
end

def prepare_outgoing(%{"type" => "Reject"} = data) do
def prepare_outgoing(%{"type" => "Reject"} = data, _host) do
with follow_activity <- Activity.normalize(data["object"]) do
object = %{
"actor" => follow_activity.actor,
Expand All @@ -849,7 +863,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
end
end

def prepare_outgoing(%{"type" => _type} = data) do
def prepare_outgoing(%{"type" => _type} = data, _host) do
data =
data
|> strip_internal_fields
Expand Down Expand Up @@ -1000,4 +1014,39 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def maybe_fix_user_url(data), do: data

def maybe_fix_user_object(data), do: maybe_fix_user_url(data)

defp patch_object(nil, _host), do: nil

defp patch_object(object, nil), do: object

defp patch_object(object, host) do
object
|> update_if_exists("source", &patch_object(&1, host))
|> update_if_exists("content", &replace_instance_host(&1, host))
|> patch_content_map(host)
end

defp patch_content_map(%{"contentMap" => %{} = content_map}, host) do
content_map
|> Enum.map(fn {key, value} -> {key, replace_instance_host(value, host)} end)
|> Map.new()
end

defp patch_content_map(content_map, _host), do: content_map

defp replace_instance_host(content, host) when is_binary(content) and is_binary(host) do
content
|> String.replace("$INSTANCE$host$", host)
end

defp replace_instance_host(content, _), do: content

defp update_if_exists(map, key, func) do
if Map.has_key?(map, key) do
value = Map.get(map, key)
Map.put(map, key, func.(value))
else
map
end
end
end
15 changes: 9 additions & 6 deletions lib/pleroma/web/activity_pub/views/object_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,34 @@ defmodule Pleroma.Web.ActivityPub.ObjectView do
alias Pleroma.Object
alias Pleroma.Web.ActivityPub.Transmogrifier

def render("object.json", %{object: %Object{} = object}) do
def render("object.json", %{object: %Object{} = object, host: host}) do
base = Pleroma.Web.ActivityPub.Utils.make_json_ld_header(object.data)

additional = Transmogrifier.prepare_object(object.data)
additional = Transmogrifier.prepare_object(object.data, host)
Map.merge(base, additional)
end

def render("object.json", %{object: %Activity{data: %{"type" => activity_type}} = activity})
def render("object.json", %{
object: %Activity{data: %{"type" => activity_type}} = activity,
host: host
})
when activity_type in ["Create", "Listen"] do
base = Pleroma.Web.ActivityPub.Utils.make_json_ld_header(activity.data)
object = Object.normalize(activity, fetch: false)

additional =
Transmogrifier.prepare_object(activity.data)
|> Map.put("object", Transmogrifier.prepare_object(object.data))
|> Map.put("object", Transmogrifier.prepare_object(object.data, host))

Map.merge(base, additional)
end

def render("object.json", %{object: %Activity{} = activity}) do
def render("object.json", %{object: %Activity{} = activity, host: host}) do
base = Pleroma.Web.ActivityPub.Utils.make_json_ld_header(activity.data)
object_id = Object.normalize(activity, id_only: true)

additional =
Transmogrifier.prepare_object(activity.data)
Transmogrifier.prepare_object(activity.data, host)
|> Map.put("object", object_id)

Map.merge(base, additional)
Expand Down
2 changes: 1 addition & 1 deletion lib/pleroma/web/activity_pub/views/user_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do
pinned_objects
|> Enum.sort_by(fn {_, pinned_at} -> pinned_at end, &>=/2)
|> Enum.map(fn {id, _} ->
ObjectView.render("object.json", %{object: Object.get_cached_by_ap_id(id)})
ObjectView.render("object.json", %{object: Object.get_cached_by_ap_id(id), host: nil})
end)

%{
Expand Down
2 changes: 1 addition & 1 deletion test/pleroma/web/activity_pub/transmogrifier_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
}
}

processed = Transmogrifier.prepare_object(original)
processed = Transmogrifier.prepare_object(original, "huj")

history_item = Enum.at(processed["formerRepresentations"]["orderedItems"], 0)

Expand Down

0 comments on commit faa2f34

Please sign in to comment.