X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fweb%2Factivity_pub%2Futils.ex;h=a9a4c895b60b835d966df77422b7d0daa7fa3a2c;hb=6cadfcb21eb58de3d4c635fb563cd4bcebffd3e2;hp=8b41a3becbb26cad7af645d8bd6480316bd2a8c0;hpb=bd479606ba2b645db46ef5312f06323534cfd9c9;p=akkoma diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 8b41a3bec..a9a4c895b 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -1,5 +1,5 @@ defmodule Pleroma.Web.ActivityPub.Utils do - alias Pleroma.{Repo, Web, Object, Activity, User} + alias Pleroma.{Repo, Web, Object, Activity, User, Notification} alias Pleroma.Web.Router.Helpers alias Pleroma.Web.Endpoint alias Ecto.{Changeset, UUID} @@ -19,22 +19,58 @@ defmodule Pleroma.Web.ActivityPub.Utils do Map.put(params, "actor", get_ap_id(params["actor"])) end + 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 + + def recipient_in_message(ap_id, params) do + cond do + recipient_in_collection(ap_id, params["to"]) -> + true + + recipient_in_collection(ap_id, params["cc"]) -> + true + + recipient_in_collection(ap_id, params["bto"]) -> + true + + recipient_in_collection(ap_id, params["bcc"]) -> + true + + # if the message is unaddressed at all, then assume it is directly addressed + # to the recipient + !params["to"] && !params["cc"] && !params["bto"] && !params["bcc"] -> + true + + true -> + false + end + end + + defp extract_list(target) when is_binary(target), do: [target] + defp extract_list(lst) when is_list(lst), do: lst + defp extract_list(_), do: [] + + def maybe_splice_recipient(ap_id, params) do + need_splice = + !recipient_in_collection(ap_id, params["to"]) && + !recipient_in_collection(ap_id, params["cc"]) + + cc_list = extract_list(params["cc"]) + + if need_splice do + params + |> Map.put("cc", [ap_id | cc_list]) + else + params + end + end + def make_json_ld_header do %{ "@context" => [ "https://www.w3.org/ns/activitystreams", - "https://w3id.org/security/v1", - %{ - "manuallyApprovesFollowers" => "as:manuallyApprovesFollowers", - "sensitive" => "as:sensitive", - "Hashtag" => "as:Hashtag", - "ostatus" => "http://ostatus.org#", - "atomUri" => "ostatus:atomUri", - "inReplyToAtomUri" => "ostatus:inReplyToAtomUri", - "conversation" => "ostatus:conversation", - "toot" => "http://joinmastodon.org/ns#", - "Emoji" => "toot:Emoji" - } + "https://litepub.github.io/litepub/context.jsonld" ] } end @@ -59,6 +95,10 @@ defmodule Pleroma.Web.ActivityPub.Utils do "#{Web.base_url()}/#{type}/#{UUID.generate()}" end + def get_notified_from_object(object) do + Notification.get_notified_from_activity(%Activity{data: object}, false) + end + def create_context(context) do context = context || generate_id("contexts") changeset = Object.context_mapping(context) @@ -128,7 +168,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do Inserts a full object if it is contained in an activity. """ def insert_full_object(%{"object" => %{"type" => type} = object_data}) - when is_map(object_data) and type in ["Article", "Note"] do + when is_map(object_data) and type in ["Article", "Note", "Video", "Page"] do with {:ok, _} <- Object.create(object_data) do :ok end @@ -204,13 +244,17 @@ defmodule Pleroma.Web.ActivityPub.Utils do end def add_like_to_object(%Activity{data: %{"actor" => actor}}, object) do - with likes <- [actor | object.data["likes"] || []] |> Enum.uniq() do + likes = if is_list(object.data["likes"]), do: object.data["likes"], else: [] + + with likes <- [actor | likes] |> Enum.uniq() do update_likes_in_object(likes, object) end end def remove_like_from_object(%Activity{data: %{"actor" => actor}}, object) do - with likes <- (object.data["likes"] || []) |> List.delete(actor) do + likes = if is_list(object.data["likes"]), do: object.data["likes"], else: [] + + with likes <- likes |> List.delete(actor) do update_likes_in_object(likes, object) end end @@ -243,11 +287,11 @@ defmodule Pleroma.Web.ActivityPub.Utils do "actor" => follower_id, "to" => [followed_id], "cc" => ["https://www.w3.org/ns/activitystreams#Public"], - "object" => followed_id + "object" => followed_id, + "state" => "pending" } data = if activity_id, do: Map.put(data, "id", activity_id), else: data - data = if User.locked?(followed), do: Map.put(data, "state", "pending"), else: data data end @@ -302,6 +346,24 @@ defmodule Pleroma.Web.ActivityPub.Utils do @doc """ Make announce activity data for the given actor and object """ + # for relayed messages, we only want to send to subscribers + def make_announce_data( + %User{ap_id: ap_id, nickname: nil} = user, + %Object{data: %{"id" => id}} = object, + activity_id + ) do + data = %{ + "type" => "Announce", + "actor" => ap_id, + "object" => id, + "to" => [user.follower_address], + "cc" => [], + "context" => object.data["context"] + } + + if activity_id, do: Map.put(data, "id", activity_id), else: data + end + def make_announce_data( %User{ap_id: ap_id} = user, %Object{data: %{"id" => id}} = object, @@ -356,14 +418,27 @@ defmodule Pleroma.Web.ActivityPub.Utils do if activity_id, do: Map.put(data, "id", activity_id), else: data end - def add_announce_to_object(%Activity{data: %{"actor" => actor}}, object) do - with announcements <- [actor | object.data["announcements"] || []] |> Enum.uniq() do + def add_announce_to_object( + %Activity{ + data: %{"actor" => actor, "cc" => ["https://www.w3.org/ns/activitystreams#Public"]} + }, + object + ) do + announcements = + if is_list(object.data["announcements"]), do: object.data["announcements"], else: [] + + with announcements <- [actor | announcements] |> Enum.uniq() do update_element_in_object("announcement", announcements, object) end end + def add_announce_to_object(_, object), do: {:ok, object} + def remove_announce_from_object(%Activity{data: %{"actor" => actor}}, object) do - with announcements <- (object.data["announcements"] || []) |> List.delete(actor) do + announcements = + if is_list(object.data["announcements"]), do: object.data["announcements"], else: [] + + with announcements <- announcements |> List.delete(actor) do update_element_in_object("announcement", announcements, object) end end