X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fweb%2Factivity_pub%2Factivity_pub.ex;h=cb88ba308c105deb2d9411d257ed1eb9f75c41a0;hb=36f78c6dcdea48dfb0231a30561825832cdb4518;hp=70db419cad6cf400b92efb3d2fc1ea2a69e05634;hpb=0f42ea87d6bcb55d14a29c0ac4e600764359f30c;p=akkoma diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 70db419ca..cb88ba308 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.Pagination alias Pleroma.Repo alias Pleroma.Upload alias Pleroma.User @@ -89,15 +90,38 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do if is_public?(object), do: User.decrease_note_count(actor), else: {:ok, actor} end - def insert(map, local \\ true) when is_map(map) do + def increase_replies_count_if_reply(%{ + "object" => %{"inReplyTo" => reply_ap_id} = object, + "type" => "Create" + }) do + if is_public?(object) do + Activity.increase_replies_count(reply_ap_id) + Object.increase_replies_count(reply_ap_id) + end + end + + def increase_replies_count_if_reply(_create_data), do: :noop + + def decrease_replies_count_if_reply(%Object{ + data: %{"inReplyTo" => reply_ap_id} = object + }) do + if is_public?(object) do + Activity.decrease_replies_count(reply_ap_id) + Object.decrease_replies_count(reply_ap_id) + end + end + + def decrease_replies_count_if_reply(_object), do: :noop + + def insert(map, local \\ true, fake \\ false) when is_map(map) do with nil <- Activity.normalize(map), - map <- lazy_put_activity_defaults(map), + map <- lazy_put_activity_defaults(map, fake), :ok <- check_actor_is_active(map["actor"]), {_, true} <- {:remote_limit_error, check_remote_limit(map)}, {:ok, map} <- MRF.filter(map), - :ok <- insert_full_object(map) do - {recipients, _, _} = get_recipients(map) - + {recipients, _, _} = get_recipients(map), + {:fake, false, map, recipients} <- {:fake, fake, map, recipients}, + {:ok, object} <- insert_full_object(map) do {:ok, activity} = Repo.insert(%Activity{ data: map, @@ -106,6 +130,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do recipients: recipients }) + # Splice in the child object if we have one. + activity = + if !is_nil(object) do + Map.put(activity, :object, object) + else + activity + end + Task.start(fn -> Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity) end) @@ -114,8 +146,23 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do stream_out(activity) {:ok, activity} else - %Activity{} = activity -> {:ok, activity} - error -> {:error, error} + %Activity{} = activity -> + {:ok, activity} + + {:fake, true, map, recipients} -> + activity = %Activity{ + data: map, + local: local, + actor: map["actor"], + recipients: recipients, + id: "pleroma:fakeid" + } + + Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity) + {:ok, activity} + + error -> + {:error, error} end end @@ -158,7 +205,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do end end - def create(%{to: to, actor: actor, context: context, object: object} = params) do + def create(%{to: to, actor: actor, context: context, object: object} = params, fake \\ false) do additional = params[:additional] || %{} # only accept false as false value local = !(params[:local] == false) @@ -169,12 +216,17 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do %{to: to, actor: actor, published: published, context: context, object: object}, additional ), - {:ok, activity} <- insert(create_data, local), + {:ok, activity} <- insert(create_data, local, fake), + {:fake, false, activity} <- {:fake, fake, activity}, + _ <- increase_replies_count_if_reply(create_data), # Changing note count prior to enqueuing federation task in order to avoid # race conditions on updating user.info {:ok, _actor} <- increase_note_count_if_public(actor, activity), :ok <- maybe_federate(activity) do {:ok, activity} + else + {:fake, true, activity} -> + {:ok, activity} end end @@ -321,6 +373,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do "deleted_activity_id" => activity && activity.id }, {:ok, activity} <- insert(data, local), + _ <- decrease_replies_count_if_reply(object), # Changing note count prior to enqueuing federation task in order to avoid # race conditions on updating user.info {:ok, _actor} <- decrease_note_count_if_public(user, object), @@ -370,20 +423,38 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do content: content } = params ) do - additional = params[:additional] || %{} - # only accept false as false value local = !(params[:local] == false) + forward = !(params[:forward] == false) - %{ + additional = params[:additional] || %{} + + params = %{ actor: actor, context: context, account: account, statuses: statuses, content: content } - |> make_flag_data(additional) - |> insert(local) + + additional = + if forward do + Map.merge(additional, %{"to" => [], "cc" => [account.ap_id]}) + else + Map.merge(additional, %{"to" => [], "cc" => []}) + end + + with flag_data <- make_flag_data(params, additional), + {:ok, activity} <- insert(flag_data, local), + :ok <- maybe_federate(activity) do + Enum.each(User.all_superusers(), fn superuser -> + superuser + |> Pleroma.Emails.AdminEmail.report(actor, account, statuses, content) + |> Pleroma.Emails.Mailer.deliver_async() + end) + + {:ok, activity} + end end def fetch_activities_for_context(context, opts \\ %{}) do @@ -412,6 +483,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do ), order_by: [desc: :id] ) + |> Activity.with_preloaded_object() Repo.all(query) end @@ -421,7 +493,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do q |> restrict_unlisted() - |> Repo.all() + |> Pagination.fetch_paginated(opts) |> Enum.reverse() end @@ -564,26 +636,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do ) end - defp restrict_limit(query, %{"limit" => limit}) do - from(activity in query, limit: ^limit) - end - - defp restrict_limit(query, _), do: query - defp restrict_local(query, %{"local_only" => true}) do from(activity in query, where: activity.local == true) end defp restrict_local(query, _), do: query - defp restrict_max(query, %{"max_id" => ""}), do: query - - defp restrict_max(query, %{"max_id" => max_id}) do - from(activity in query, where: activity.id < ^max_id) - end - - defp restrict_max(query, _), do: query - defp restrict_actor(query, %{"actor_id" => actor_id}) do from(activity in query, where: activity.actor == ^actor_id) end @@ -654,7 +712,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do from( activity in query, where: fragment("not (? = ANY(?))", activity.actor, ^blocks), - where: fragment("not (?->'to' \\?| ?)", activity.data, ^blocks), + where: fragment("not (? && ?)", activity.recipients, ^blocks), + where: + fragment( + "not (?->>'type' = 'Announce' and ?->'to' \\?| ?)", + activity.data, + activity.data, + ^blocks + ), where: fragment("not (split_part(?, '/', 3) = ANY(?))", activity.actor, ^domain_blocks) ) end @@ -679,23 +744,41 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do defp restrict_pinned(query, _), do: query + defp restrict_muted_reblogs(query, %{"muting_user" => %User{info: info}}) do + muted_reblogs = info.muted_reblogs || [] + + from( + activity in query, + where: + fragment( + "not ( ?->>'type' = 'Announce' and ? = ANY(?))", + activity.data, + activity.actor, + ^muted_reblogs + ) + ) + end + + defp restrict_muted_reblogs(query, _), do: query + + defp maybe_preload_objects(query, %{"skip_preload" => true}), do: query + + defp maybe_preload_objects(query, _) do + query + |> Activity.with_preloaded_object() + end + def fetch_activities_query(recipients, opts \\ %{}) do - base_query = - from( - activity in Activity, - limit: 20, - order_by: [fragment("? desc nulls last", activity.id)] - ) + base_query = from(activity in Activity) base_query + |> maybe_preload_objects(opts) |> restrict_recipients(recipients, opts["user"]) |> restrict_tag(opts) |> restrict_tag_reject(opts) |> restrict_tag_all(opts) |> restrict_since(opts) |> restrict_local(opts) - |> restrict_limit(opts) - |> restrict_max(opts) |> restrict_actor(opts) |> restrict_type(opts) |> restrict_favorited_by(opts) @@ -706,18 +789,19 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do |> restrict_replies(opts) |> restrict_reblogs(opts) |> restrict_pinned(opts) + |> restrict_muted_reblogs(opts) end def fetch_activities(recipients, opts \\ %{}) do fetch_activities_query(recipients, opts) - |> Repo.all() + |> Pagination.fetch_paginated(opts) |> 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() + |> Pagination.fetch_paginated(opts) |> Enum.reverse() end @@ -909,7 +993,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do }, :ok <- Transmogrifier.contain_origin(id, params), {:ok, activity} <- Transmogrifier.handle_incoming(params) do - {:ok, Object.normalize(activity.data["object"])} + {:ok, Object.normalize(activity)} else {:error, {:reject, nil}} -> {:reject, nil} @@ -921,7 +1005,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do 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.data["object"])} + {:ok, [activity | _]} -> {:ok, Object.normalize(activity)} e -> e end end