X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fweb%2Factivity_pub%2Factivity_pub.ex;h=81c11dd766b94060b4f946950aedaaa169d1caf5;hb=7ca2a2ddeaa4396c86cd39a43a8fd0a4c8d3ce14;hp=ec605b694f49557b0f7dcfb472618ae98d324439;hpb=38361e7b5e24cbbd4654bd76fce4b3c66562ab59;p=akkoma diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index ec605b694..81c11dd76 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -12,8 +12,33 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do @instance Application.get_env(:pleroma, :instance) - def get_recipients(data) do - (data["to"] || []) ++ (data["cc"] || []) + # For Announce activities, we filter the recipients based on following status for any actors + # that match actual users. See issue #164 for more information about why this is necessary. + defp get_recipients(%{"type" => "Announce"} = data) do + to = data["to"] || [] + cc = data["cc"] || [] + recipients = to ++ cc + actor = User.get_cached_by_ap_id(data["actor"]) + + recipients + |> Enum.filter(fn recipient -> + case User.get_cached_by_ap_id(recipient) do + nil -> + true + + user -> + User.following?(user, actor) + end + end) + + {recipients, to, cc} + end + + defp get_recipients(data) do + to = data["to"] || [] + cc = data["cc"] || [] + recipients = to ++ cc + {recipients, to, cc} end defp check_actor_is_active(actor) do @@ -35,12 +60,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do :ok <- check_actor_is_active(map["actor"]), {:ok, map} <- MRF.filter(map), :ok <- insert_full_object(map) do + {recipients, _, _} = get_recipients(map) + {:ok, activity} = Repo.insert(%Activity{ data: map, local: local, actor: map["actor"], - recipients: get_recipients(map) + recipients: recipients }) Notification.create_notifications(activity) @@ -381,6 +408,20 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do defp restrict_tag(query, _), do: query + defp restrict_to_cc(query, recipients_to, recipients_cc) do + from( + activity in query, + where: + fragment( + "(?->'to' \\?| ?) or (?->'cc' \\?| ?)", + activity.data, + ^recipients_to, + activity.data, + ^recipients_cc + ) + ) + end + defp restrict_recipients(query, [], _user), do: query defp restrict_recipients(query, recipients, nil) do @@ -522,6 +563,13 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do |> Enum.reverse() end + def fetch_activities_bounded(recipients_to, recipients_cc, opts \\ %{}) do + fetch_activities_query([], opts) + |> restrict_to_cc(recipients_to, recipients_cc) + |> Repo.all() + |> Enum.reverse() + end + def upload(file) do data = Upload.store(file, Application.get_env(:pleroma, :instance)[:dedupe_media]) Repo.insert(%Object{data: data}) @@ -554,18 +602,29 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do "locked" => locked }, avatar: avatar, - nickname: "#{data["preferredUsername"]}@#{URI.parse(data["id"]).host}", name: data["name"], follower_address: data["followers"], bio: data["summary"] } + # nickname can be nil because of virtual actors + user_data = + if data["preferredUsername"] do + Map.put( + user_data, + :nickname, + "#{data["preferredUsername"]}@#{URI.parse(data["id"]).host}" + ) + else + Map.put(user_data, :nickname, nil) + end + {:ok, user_data} end def fetch_and_prepare_user_from_ap_id(ap_id) do with {:ok, %{status_code: 200, body: body}} <- - @httpoison.get(ap_id, Accept: "application/activity+json"), + @httpoison.get(ap_id, [Accept: "application/activity+json"], follow_redirect: true), {:ok, data} <- Jason.decode(body) do user_data_from_user_object(data) else @@ -688,6 +747,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do "actor" => data["attributedTo"], "object" => data }, + :ok <- Transmogrifier.contain_origin(id, params), {:ok, activity} <- Transmogrifier.handle_incoming(params) do {:ok, Object.normalize(activity.data["object"])} else