diff options
Diffstat (limited to 'lib/pleroma/web/activity_pub')
-rw-r--r-- | lib/pleroma/web/activity_pub/activity_pub.ex | 56 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/relay.ex | 2 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/transmogrifier.ex | 47 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/utils.ex | 24 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/views/object_view.ex | 2 |
5 files changed, 100 insertions, 31 deletions
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 5b87f7462..82fffd324 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -92,7 +92,7 @@ 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"] do + if activity.data["type"] in ["Create", "Announce", "Delete"] do Pleroma.Web.Streamer.stream("user", activity) Pleroma.Web.Streamer.stream("list", activity) @@ -103,16 +103,18 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do Pleroma.Web.Streamer.stream("public:local", activity) end - activity.data["object"] - |> Map.get("tag", []) - |> Enum.filter(fn tag -> is_bitstring(tag) end) - |> Enum.map(fn tag -> Pleroma.Web.Streamer.stream("hashtag:" <> tag, activity) end) + if activity.data["type"] in ["Create"] do + activity.data["object"] + |> Map.get("tag", []) + |> Enum.filter(fn tag -> is_bitstring(tag) end) + |> Enum.map(fn tag -> Pleroma.Web.Streamer.stream("hashtag:" <> tag, activity) end) - if activity.data["object"]["attachment"] != [] do - Pleroma.Web.Streamer.stream("public:media", activity) + if activity.data["object"]["attachment"] != [] do + Pleroma.Web.Streamer.stream("public:media", activity) - if activity.local do - Pleroma.Web.Streamer.stream("public:local:media", activity) + if activity.local do + Pleroma.Web.Streamer.stream("public:local:media", activity) + end end end else @@ -138,8 +140,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do additional ), {:ok, activity} <- insert(create_data, local), - :ok <- maybe_federate(activity), - {:ok, _actor} <- User.increase_note_count(actor) do + # Changing note count prior to enqueuing federation task in order to avoid race conditions on updating user.info + {:ok, _actor} <- User.increase_note_count(actor), + :ok <- maybe_federate(activity) do {:ok, activity} end end @@ -224,10 +227,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do %User{ap_id: _} = user, %Object{data: %{"id" => _}} = object, activity_id \\ nil, - local \\ true + local \\ true, + public \\ true ) do with true <- is_public?(object), - announce_data <- make_announce_data(user, object, activity_id), + announce_data <- make_announce_data(user, object, activity_id, public), {:ok, activity} <- insert(announce_data, local), {:ok, object} <- add_announce_to_object(activity, object), :ok <- maybe_federate(activity) do @@ -285,8 +289,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do with {:ok, _} <- Object.delete(object), {:ok, activity} <- insert(data, local), - :ok <- maybe_federate(activity), - {:ok, _actor} <- User.decrease_note_count(user) do + # Changing note count prior to enqueuing federation task in order to avoid race conditions on updating user.info + {:ok, _actor} <- User.decrease_note_count(user), + :ok <- maybe_federate(activity) do {:ok, activity} end end @@ -796,13 +801,24 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do end end - def is_public?(%Object{data: %{"type" => "Tombstone"}}) do - false + def is_public?(%Object{data: %{"type" => "Tombstone"}}), do: false + def is_public?(%Object{data: data}), do: is_public?(data) + def is_public?(%Activity{data: data}), do: is_public?(data) + def is_public?(%{"directMessage" => true}), do: false + + def is_public?(data) do + "https://www.w3.org/ns/activitystreams#Public" in (data["to"] ++ (data["cc"] || [])) end - def is_public?(activity) do - "https://www.w3.org/ns/activitystreams#Public" in (activity.data["to"] ++ - (activity.data["cc"] || [])) + def is_private?(activity) do + !is_public?(activity) && Enum.any?(activity.data["to"], &String.contains?(&1, "/followers")) + end + + def is_direct?(%Activity{data: %{"directMessage" => true}}), do: true + def is_direct?(%Object{data: %{"directMessage" => true}}), do: true + + def is_direct?(activity) do + !is_public?(activity) && !is_private?(activity) end def visible_for_user?(activity, nil) do diff --git a/lib/pleroma/web/activity_pub/relay.ex b/lib/pleroma/web/activity_pub/relay.ex index abddbc790..c0a52e349 100644 --- a/lib/pleroma/web/activity_pub/relay.ex +++ b/lib/pleroma/web/activity_pub/relay.ex @@ -40,7 +40,7 @@ defmodule Pleroma.Web.ActivityPub.Relay do def publish(%Activity{data: %{"type" => "Create"}} = activity) do with %User{} = user <- get_actor(), %Object{} = object <- Object.normalize(activity.data["object"]["id"]) do - ActivityPub.announce(user, object) + ActivityPub.announce(user, object, nil, true, false) else e -> Logger.error("error: #{inspect(e)}") end diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 86d11c874..46b1646f7 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -93,12 +93,47 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do end end - def fix_addressing(map) do - map + def fix_explicit_addressing(%{"to" => to, "cc" => cc} = object, explicit_mentions) do + explicit_to = + to + |> Enum.filter(fn x -> x in explicit_mentions end) + + explicit_cc = + to + |> Enum.filter(fn x -> x not in explicit_mentions end) + + final_cc = + (cc ++ explicit_cc) + |> Enum.uniq() + + object + |> Map.put("to", explicit_to) + |> Map.put("cc", final_cc) + end + + def fix_explicit_addressing(object, _explicit_mentions), do: object + + # if directMessage flag is set to true, leave the addressing alone + def fix_explicit_addressing(%{"directMessage" => true} = object), do: object + + def fix_explicit_addressing(object) do + explicit_mentions = + object + |> Utils.determine_explicit_mentions() + + explicit_mentions = explicit_mentions ++ ["https://www.w3.org/ns/activitystreams#Public"] + + object + |> fix_explicit_addressing(explicit_mentions) + end + + def fix_addressing(object) do + object |> fix_addressing_list("to") |> fix_addressing_list("cc") |> fix_addressing_list("bto") |> fix_addressing_list("bcc") + |> fix_explicit_addressing end def fix_actor(%{"attributedTo" => actor} = object) do @@ -141,7 +176,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do case fetch_obj_helper(in_reply_to_id) do {:ok, replied_object} -> with %Activity{} = activity <- - Activity.get_create_activity_by_object_ap_id(replied_object.data["id"]) do + Activity.get_create_by_object_ap_id(replied_object.data["id"]) do object |> Map.put("inReplyTo", replied_object.data["id"]) |> Map.put("inReplyToAtomUri", object["inReplyToAtomUri"] || in_reply_to_id) @@ -334,7 +369,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do Map.put(data, "actor", actor) |> fix_addressing - with nil <- Activity.get_create_activity_by_object_ap_id(object["id"]), + with nil <- Activity.get_create_by_object_ap_id(object["id"]), %User{} = user <- User.get_or_fetch_by_ap_id(data["actor"]) do object = fix_object(data["object"]) @@ -348,6 +383,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do additional: Map.take(data, [ "cc", + "directMessage", "id" ]) } @@ -451,7 +487,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do with actor <- 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, activity, _object} <- ActivityPub.announce(actor, object, id, false) do + public <- ActivityPub.is_public?(data), + {:ok, activity, _object} <- ActivityPub.announce(actor, object, id, false, public) do {:ok, activity} else _e -> :error diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 6ecab773c..e40d05fcd 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -25,6 +25,20 @@ defmodule Pleroma.Web.ActivityPub.Utils do Map.put(params, "actor", get_ap_id(params["actor"])) end + def determine_explicit_mentions(%{"tag" => tag} = _object) when is_list(tag) do + tag + |> Enum.filter(fn x -> is_map(x) end) + |> Enum.filter(fn x -> x["type"] == "Mention" end) + |> Enum.map(fn x -> x["href"] end) + end + + def determine_explicit_mentions(%{"tag" => tag} = object) when is_map(tag) do + Map.put(object, "tag", [tag]) + |> determine_explicit_mentions() + end + + def determine_explicit_mentions(_), do: [] + defp recipient_in_collection(ap_id, coll) when is_binary(coll), do: ap_id == coll defp recipient_in_collection(ap_id, coll) when is_list(coll), do: ap_id in coll defp recipient_in_collection(_, _), do: false @@ -198,7 +212,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do # Update activities that already had this. Could be done in a seperate process. # Alternatively, just don't do this and fetch the current object each time. Most # could probably be taken from cache. - relevant_activities = Activity.all_by_object_ap_id(id) + relevant_activities = Activity.get_all_create_by_object_ap_id(id) Enum.map(relevant_activities, fn activity -> new_activity_data = activity.data |> Map.put("object", object.data) @@ -386,9 +400,10 @@ defmodule Pleroma.Web.ActivityPub.Utils do """ # for relayed messages, we only want to send to subscribers def make_announce_data( - %User{ap_id: ap_id, nickname: nil} = user, + %User{ap_id: ap_id} = user, %Object{data: %{"id" => id}} = object, - activity_id + activity_id, + false ) do data = %{ "type" => "Announce", @@ -405,7 +420,8 @@ defmodule Pleroma.Web.ActivityPub.Utils do def make_announce_data( %User{ap_id: ap_id} = user, %Object{data: %{"id" => id}} = object, - activity_id + activity_id, + true ) do data = %{ "type" => "Announce", diff --git a/lib/pleroma/web/activity_pub/views/object_view.ex b/lib/pleroma/web/activity_pub/views/object_view.ex index 193042056..394d82fbc 100644 --- a/lib/pleroma/web/activity_pub/views/object_view.ex +++ b/lib/pleroma/web/activity_pub/views/object_view.ex @@ -46,7 +46,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectView do "id" => "#{ap_id}/likes", "type" => "OrderedCollection", "totalItems" => length(likes), - "first" => collection(likes, "#{ap_id}/followers", 1) + "first" => collection(likes, "#{ap_id}/likes", 1) } |> Map.merge(Pleroma.Web.ActivityPub.Utils.make_json_ld_header()) end |