summaryrefslogtreecommitdiff
path: root/lib/pleroma/web/activity_pub
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pleroma/web/activity_pub')
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub.ex67
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub_controller.ex3
-rw-r--r--lib/pleroma/web/activity_pub/transmogrifier.ex94
-rw-r--r--lib/pleroma/web/activity_pub/utils.ex10
4 files changed, 38 insertions, 136 deletions
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index 54dd4097c..1a3b47cb3 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
alias Pleroma.Instances
alias Pleroma.Notification
alias Pleroma.Object
+ alias Pleroma.Object.Fetcher
alias Pleroma.Pagination
alias Pleroma.Repo
alias Pleroma.Upload
@@ -14,7 +15,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
alias Pleroma.Web.ActivityPub.MRF
alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Web.Federator
- alias Pleroma.Web.OStatus
alias Pleroma.Web.WebFinger
import Ecto.Query
@@ -121,7 +121,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
{:ok, map} <- MRF.filter(map),
{recipients, _, _} = get_recipients(map),
{:fake, false, map, recipients} <- {:fake, fake, map, recipients},
- {:ok, object} <- insert_full_object(map) do
+ {:ok, map, object} <- insert_full_object(map) do
{:ok, activity} =
Repo.insert(%Activity{
data: map,
@@ -169,7 +169,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
def stream_out(activity) do
public = "https://www.w3.org/ns/activitystreams#Public"
- if activity.data["type"] in ["Create", "Announce", "Delete"] do
+ if activity.data["type"] in ["Create", "Announce"] do
+ object = Object.normalize(activity.data["object"])
Pleroma.Web.Streamer.stream("user", activity)
Pleroma.Web.Streamer.stream("list", activity)
@@ -181,12 +182,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end
if activity.data["type"] in ["Create"] do
- activity.data["object"]
+ object.data
|> Map.get("tag", [])
|> Enum.filter(fn tag -> is_bitstring(tag) end)
|> Enum.each(fn tag -> Pleroma.Web.Streamer.stream("hashtag:" <> tag, activity) end)
- if activity.data["object"]["attachment"] != [] do
+ if object.data["attachment"] != [] do
Pleroma.Web.Streamer.stream("public:media", activity)
if activity.local do
@@ -859,7 +860,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end
def fetch_and_prepare_user_from_ap_id(ap_id) do
- with {:ok, data} <- fetch_and_contain_remote_object_from_id(ap_id) do
+ with {:ok, data} <- Fetcher.fetch_and_contain_remote_object_from_id(ap_id) do
user_data_from_user_object(data)
else
e -> Logger.error("Could not decode user at fetch #{ap_id}, #{inspect(e)}")
@@ -969,60 +970,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end
end
- # TODO:
- # This will create a Create activity, which we need internally at the moment.
- def fetch_object_from_id(id) do
- if object = Object.get_cached_by_ap_id(id) do
- {:ok, object}
- else
- with {:ok, data} <- fetch_and_contain_remote_object_from_id(id),
- nil <- Object.normalize(data),
- params <- %{
- "type" => "Create",
- "to" => data["to"],
- "cc" => data["cc"],
- "actor" => data["actor"] || data["attributedTo"],
- "object" => data
- },
- :ok <- Transmogrifier.contain_origin(id, params),
- {:ok, activity} <- Transmogrifier.handle_incoming(params) do
- {:ok, Object.normalize(activity)}
- else
- {:error, {:reject, nil}} ->
- {:reject, nil}
-
- object = %Object{} ->
- {:ok, object}
-
- _e ->
- Logger.info("Couldn't get object via AP, trying out OStatus fetching...")
-
- case OStatus.fetch_activity_from_url(id) do
- {:ok, [activity | _]} -> {:ok, Object.normalize(activity)}
- e -> e
- end
- end
- end
- end
-
- def fetch_and_contain_remote_object_from_id(id) do
- Logger.info("Fetching object #{id} via AP")
-
- with true <- String.starts_with?(id, "http"),
- {:ok, %{body: body, status: code}} when code in 200..299 <-
- @httpoison.get(
- id,
- [{:Accept, "application/activity+json"}]
- ),
- {:ok, data} <- Jason.decode(body),
- :ok <- Transmogrifier.contain_origin_from_id(id, data) do
- {:ok, data}
- else
- e ->
- {:error, e}
- end
- end
-
# filter out broken threads
def contain_broken_threads(%Activity{} = activity, %User{} = user) do
entire_thread_visible_for_user?(activity, user)
diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex
index 3331ebebd..0b80566bf 100644
--- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex
@@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
alias Pleroma.Activity
alias Pleroma.Object
+ alias Pleroma.Object.Fetcher
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.ObjectView
@@ -173,7 +174,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
"Signature missing or not from author, relayed Create message, fetching object from source"
)
- ActivityPub.fetch_object_from_id(params["object"]["id"])
+ Fetcher.fetch_object_from_id(params["object"]["id"])
json(conn, "ok")
end
diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex
index 39cd31921..0637b18dc 100644
--- a/lib/pleroma/web/activity_pub/transmogrifier.ex
+++ b/lib/pleroma/web/activity_pub/transmogrifier.ex
@@ -6,6 +6,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
@moduledoc """
A module to handle coding from internal to wire ActivityPub and back.
"""
+ alias Pleroma.User
+ alias Pleroma.Object
+ alias Pleroma.Object.Containment
alias Pleroma.Activity
alias Pleroma.Object
alias Pleroma.Repo
@@ -18,56 +21,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
require Logger
- def get_actor(%{"actor" => actor}) when is_binary(actor) do
- actor
- end
-
- def get_actor(%{"actor" => actor}) when is_list(actor) do
- if is_binary(Enum.at(actor, 0)) do
- Enum.at(actor, 0)
- else
- Enum.find(actor, fn %{"type" => type} -> type in ["Person", "Service", "Application"] end)
- |> Map.get("id")
- end
- end
-
- def get_actor(%{"actor" => %{"id" => id}}) when is_bitstring(id) do
- id
- end
-
- def get_actor(%{"actor" => nil, "attributedTo" => actor}) when not is_nil(actor) do
- get_actor(%{"actor" => actor})
- end
-
- @doc """
- Checks that an imported AP object's actor matches the domain it came from.
- """
- def contain_origin(_id, %{"actor" => nil}), do: :error
-
- def contain_origin(id, %{"actor" => _actor} = params) do
- id_uri = URI.parse(id)
- actor_uri = URI.parse(get_actor(params))
-
- if id_uri.host == actor_uri.host do
- :ok
- else
- :error
- end
- end
-
- def contain_origin_from_id(_id, %{"id" => nil}), do: :error
-
- def contain_origin_from_id(id, %{"id" => other_id} = _params) do
- id_uri = URI.parse(id)
- other_uri = URI.parse(other_id)
-
- if id_uri.host == other_uri.host do
- :ok
- else
- :error
- end
- end
-
@doc """
Modifies an incoming AP object (mastodon format) to our internal format.
"""
@@ -188,7 +141,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def fix_actor(%{"attributedTo" => actor} = object) do
object
- |> Map.put("actor", get_actor(%{"actor" => actor}))
+ |> Map.put("actor", Containment.get_actor(%{"actor" => actor}))
end
# Check for standardisation
@@ -223,7 +176,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
""
end
- case fetch_obj_helper(in_reply_to_id) do
+ case get_obj_helper(in_reply_to_id) do
{:ok, replied_object} ->
with %Activity{} = _activity <-
Activity.get_create_by_object_ap_id(replied_object.data["id"]) do
@@ -448,7 +401,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
# - emoji
def handle_incoming(%{"type" => "Create", "object" => %{"type" => objtype} = object} = data)
when objtype in ["Article", "Note", "Video", "Page"] do
- actor = get_actor(data)
+ actor = Containment.get_actor(data)
data =
Map.put(data, "actor", actor)
@@ -506,7 +459,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def handle_incoming(
%{"type" => "Accept", "object" => follow_object, "actor" => _actor, "id" => _id} = data
) do
- with actor <- get_actor(data),
+ with actor <- Containment.get_actor(data),
%User{} = followed <- User.get_or_fetch_by_ap_id(actor),
{:ok, follow_activity} <- get_follow_activity(follow_object, followed),
{:ok, follow_activity} <- Utils.update_follow_state(follow_activity, "accept"),
@@ -532,7 +485,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def handle_incoming(
%{"type" => "Reject", "object" => follow_object, "actor" => _actor, "id" => _id} = data
) do
- with actor <- get_actor(data),
+ with actor <- Containment.get_actor(data),
%User{} = followed <- User.get_or_fetch_by_ap_id(actor),
{:ok, follow_activity} <- get_follow_activity(follow_object, followed),
{:ok, follow_activity} <- Utils.update_follow_state(follow_activity, "reject"),
@@ -556,9 +509,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def handle_incoming(
%{"type" => "Like", "object" => object_id, "actor" => _actor, "id" => id} = data
) do
- with actor <- get_actor(data),
+ with actor <- Containment.get_actor(data),
%User{} = actor <- User.get_or_fetch_by_ap_id(actor),
- {:ok, object} <- get_obj_helper(object_id) || fetch_obj_helper(object_id),
+ {:ok, object} <- get_obj_helper(object_id),
{:ok, activity, _object} <- ActivityPub.like(actor, object, id, false) do
{:ok, activity}
else
@@ -569,9 +522,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def handle_incoming(
%{"type" => "Announce", "object" => object_id, "actor" => _actor, "id" => id} = data
) do
- with actor <- get_actor(data),
+ with actor <- Containment.get_actor(data),
%User{} = actor <- User.get_or_fetch_by_ap_id(actor),
- {:ok, object} <- get_obj_helper(object_id) || fetch_obj_helper(object_id),
+ {:ok, object} <- get_obj_helper(object_id),
public <- Visibility.is_public?(data),
{:ok, activity, _object} <- ActivityPub.announce(actor, object, id, false, public) do
{:ok, activity}
@@ -624,10 +577,10 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
) do
object_id = Utils.get_ap_id(object_id)
- with actor <- get_actor(data),
+ with actor <- Containment.get_actor(data),
%User{} = actor <- User.get_or_fetch_by_ap_id(actor),
- {:ok, object} <- get_obj_helper(object_id) || fetch_obj_helper(object_id),
- :ok <- contain_origin(actor.ap_id, object.data),
+ {:ok, object} <- get_obj_helper(object_id),
+ :ok <- Containment.contain_origin(actor.ap_id, object.data),
{:ok, activity} <- ActivityPub.delete(object, false) do
{:ok, activity}
else
@@ -643,9 +596,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
"id" => id
} = data
) do
- with actor <- get_actor(data),
+ with actor <- Containment.get_actor(data),
%User{} = actor <- User.get_or_fetch_by_ap_id(actor),
- {:ok, object} <- get_obj_helper(object_id) || fetch_obj_helper(object_id),
+ {:ok, object} <- get_obj_helper(object_id),
{:ok, activity, _} <- ActivityPub.unannounce(actor, object, id, false) do
{:ok, activity}
else
@@ -713,9 +666,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
"id" => id
} = data
) do
- with actor <- get_actor(data),
+ with actor <- Containment.get_actor(data),
%User{} = actor <- User.get_or_fetch_by_ap_id(actor),
- {:ok, object} <- get_obj_helper(object_id) || fetch_obj_helper(object_id),
+ {:ok, object} <- get_obj_helper(object_id),
{:ok, activity, _, _} <- ActivityPub.unlike(actor, object, id, false) do
{:ok, activity}
else
@@ -725,9 +678,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def handle_incoming(_), do: :error
- def fetch_obj_helper(id) when is_bitstring(id), do: ActivityPub.fetch_object_from_id(id)
- def fetch_obj_helper(obj) when is_map(obj), do: ActivityPub.fetch_object_from_id(obj["id"])
-
def get_obj_helper(id) do
if object = Object.normalize(id), do: {:ok, object}, else: nil
end
@@ -764,9 +714,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
# internal -> Mastodon
# """
- def prepare_outgoing(%{"type" => "Create", "object" => object} = data) do
+ def prepare_outgoing(%{"type" => "Create", "object" => object_id} = data) do
object =
- object
+ Object.normalize(object_id).data
|> prepare_object
data =
@@ -827,7 +777,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def maybe_fix_object_url(data) do
if is_binary(data["object"]) and not String.starts_with?(data["object"], "http") do
- case fetch_obj_helper(data["object"]) do
+ case get_obj_helper(data["object"]) do
{:ok, relative_object} ->
if relative_object.data["external_url"] do
_data =
diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex
index ccc9da7c6..581b9d1ab 100644
--- a/lib/pleroma/web/activity_pub/utils.ex
+++ b/lib/pleroma/web/activity_pub/utils.ex
@@ -234,14 +234,18 @@ defmodule Pleroma.Web.ActivityPub.Utils do
@doc """
Inserts a full object if it is contained in an activity.
"""
- def insert_full_object(%{"object" => %{"type" => type} = object_data})
+ def insert_full_object(%{"object" => %{"type" => type} = object_data} = map)
when is_map(object_data) and type in @supported_object_types do
with {:ok, object} <- Object.create(object_data) do
- {:ok, object}
+ map =
+ map
+ |> Map.put("object", object.data["id"])
+
+ {:ok, map, object}
end
end
- def insert_full_object(_), do: {:ok, nil}
+ def insert_full_object(map), do: {:ok, map, nil}
def update_object_in_activities(%{data: %{"id" => id}} = object) do
# TODO