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.ex141
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub_controller.ex8
-rw-r--r--lib/pleroma/web/activity_pub/mrf.ex2
-rw-r--r--lib/pleroma/web/activity_pub/mrf/keyword_policy.ex38
-rw-r--r--lib/pleroma/web/activity_pub/relay.ex6
-rw-r--r--lib/pleroma/web/activity_pub/transmogrifier.ex98
-rw-r--r--lib/pleroma/web/activity_pub/utils.ex69
-rw-r--r--lib/pleroma/web/activity_pub/views/object_view.ex4
-rw-r--r--lib/pleroma/web/activity_pub/views/user_view.ex31
9 files changed, 307 insertions, 90 deletions
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index adb42b9ab..6e1ed7ec9 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -4,17 +4,17 @@
defmodule Pleroma.Web.ActivityPub.ActivityPub do
alias Pleroma.Activity
- alias Pleroma.Repo
+ alias Pleroma.Instances
+ alias Pleroma.Notification
alias Pleroma.Object
+ alias Pleroma.Repo
alias Pleroma.Upload
alias Pleroma.User
- alias Pleroma.Notification
- alias Pleroma.Instances
- alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Web.ActivityPub.MRF
- alias Pleroma.Web.WebFinger
+ alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Web.Federator
alias Pleroma.Web.OStatus
+ alias Pleroma.Web.WebFinger
import Ecto.Query
import Pleroma.Web.ActivityPub.Utils
@@ -89,13 +89,37 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
if is_public?(object), do: User.decrease_note_count(actor), else: {:ok, actor}
end
+ def increase_replies_count_if_reply(%{
+ "object" =>
+ %{"inReplyTo" => reply_ap_id, "inReplyToStatusId" => reply_status_id} = object,
+ "type" => "Create"
+ }) do
+ if is_public?(object) do
+ Activity.increase_replies_count(reply_status_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, "inReplyToStatusId" => reply_status_id} = object
+ }) do
+ if is_public?(object) do
+ Activity.decrease_replies_count(reply_status_id)
+ Object.decrease_replies_count(reply_ap_id)
+ end
+ end
+
+ def decrease_replies_count_if_reply(_object), do: :noop
+
def insert(map, local \\ true) when is_map(map) do
with nil <- Activity.normalize(map),
map <- lazy_put_activity_defaults(map),
: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
+ {:ok, object} <- insert_full_object(map) do
{recipients, _, _} = get_recipients(map)
{:ok, activity} =
@@ -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)
@@ -170,7 +202,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
additional
),
{:ok, activity} <- insert(create_data, local),
- # Changing note count prior to enqueuing federation task in order to avoid race conditions on updating user.info
+ _ <- 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}
@@ -309,18 +343,20 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
def delete(%Object{data: %{"id" => id, "actor" => actor}} = object, local \\ true) do
user = User.get_cached_by_ap_id(actor)
- to = object.data["to"] || [] ++ object.data["cc"] || []
+ to = (object.data["to"] || []) ++ (object.data["cc"] || [])
- data = %{
- "type" => "Delete",
- "actor" => actor,
- "object" => id,
- "to" => to
- }
-
- with {:ok, _} <- Object.delete(object),
+ with {:ok, object, activity} <- Object.delete(object),
+ data <- %{
+ "type" => "Delete",
+ "actor" => actor,
+ "object" => id,
+ "to" => to,
+ "deleted_activity_id" => activity && activity.id
+ },
{:ok, activity} <- insert(data, local),
- # Changing note count prior to enqueuing federation task in order to avoid race conditions on updating user.info
+ _ <- 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),
:ok <- maybe_federate(activity) do
{:ok, activity}
@@ -368,20 +404,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.AdminEmail.report(actor, account, statuses, content)
+ |> Pleroma.Mailer.deliver_async()
+ end)
+
+ {:ok, activity}
+ end
end
def fetch_activities_for_context(context, opts \\ %{}) do
@@ -410,6 +464,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
),
order_by: [desc: :id]
)
+ |> Activity.with_preloaded_object()
Repo.all(query)
end
@@ -502,7 +557,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
when is_list(tag_reject) and tag_reject != [] do
from(
activity in query,
- where: fragment("(not (? #> '{\"object\",\"tag\"}') \\?| ?)", activity.data, ^tag_reject)
+ where: fragment(~s(\(not \(? #> '{"object","tag"}'\) \\?| ?\)), activity.data, ^tag_reject)
)
end
@@ -512,7 +567,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
when is_list(tag_all) and tag_all != [] do
from(
activity in query,
- where: fragment("(? #> '{\"object\",\"tag\"}') \\?& ?", activity.data, ^tag_all)
+ where: fragment(~s(\(? #> '{"object","tag"}'\) \\?& ?), activity.data, ^tag_all)
)
end
@@ -521,14 +576,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
defp restrict_tag(query, %{"tag" => tag}) when is_list(tag) do
from(
activity in query,
- where: fragment("(? #> '{\"object\",\"tag\"}') \\?| ?", activity.data, ^tag)
+ where: fragment(~s(\(? #> '{"object","tag"}'\) \\?| ?), activity.data, ^tag)
)
end
defp restrict_tag(query, %{"tag" => tag}) when is_binary(tag) do
from(
activity in query,
- where: fragment("? <@ (? #> '{\"object\",\"tag\"}')", ^tag, activity.data)
+ where: fragment(~s(? <@ (? #> '{"object","tag"}'\)), ^tag, activity.data)
)
end
@@ -601,7 +656,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
defp restrict_favorited_by(query, %{"favorited_by" => ap_id}) do
from(
activity in query,
- where: fragment("? <@ (? #> '{\"object\",\"likes\"}')", ^ap_id, activity.data)
+ where: fragment(~s(? <@ (? #> '{"object","likes"}'\)), ^ap_id, activity.data)
)
end
@@ -610,7 +665,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
defp restrict_media(query, %{"only_media" => val}) when val == "true" or val == "1" do
from(
activity in query,
- where: fragment("not (? #> '{\"object\",\"attachment\"}' = ?)", activity.data, ^[])
+ where: fragment(~s(not (? #> '{"object","attachment"}' = ?\)), activity.data, ^[])
)
end
@@ -677,6 +732,30 @@ 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(
@@ -686,6 +765,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
)
base_query
+ |> maybe_preload_objects(opts)
|> restrict_recipients(recipients, opts["user"])
|> restrict_tag(opts)
|> restrict_tag_reject(opts)
@@ -704,6 +784,7 @@ 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
@@ -907,7 +988,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}
@@ -919,7 +1000,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
diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex
index ff924a536..7091d6927 100644
--- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex
@@ -6,15 +6,15 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
use Pleroma.Web, :controller
alias Pleroma.Activity
- alias Pleroma.User
alias Pleroma.Object
- alias Pleroma.Web.ActivityPub.ObjectView
- alias Pleroma.Web.ActivityPub.UserView
+ alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
- alias Pleroma.Web.ActivityPub.Visibility
+ alias Pleroma.Web.ActivityPub.ObjectView
alias Pleroma.Web.ActivityPub.Relay
alias Pleroma.Web.ActivityPub.Transmogrifier
+ alias Pleroma.Web.ActivityPub.UserView
alias Pleroma.Web.ActivityPub.Utils
+ alias Pleroma.Web.ActivityPub.Visibility
alias Pleroma.Web.Federator
require Logger
diff --git a/lib/pleroma/web/activity_pub/mrf.ex b/lib/pleroma/web/activity_pub/mrf.ex
index eebea207c..1aaa20050 100644
--- a/lib/pleroma/web/activity_pub/mrf.ex
+++ b/lib/pleroma/web/activity_pub/mrf.ex
@@ -16,7 +16,7 @@ defmodule Pleroma.Web.ActivityPub.MRF do
end)
end
- def get_policies() do
+ def get_policies do
Application.get_env(:pleroma, :instance, [])
|> Keyword.get(:rewrite_policy, [])
|> get_policies()
diff --git a/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex b/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex
index 5fdc03414..e8dfba672 100644
--- a/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex
@@ -4,6 +4,10 @@
defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicy do
@behaviour Pleroma.Web.ActivityPub.MRF
+ defp string_matches?(string, _) when not is_binary(string) do
+ false
+ end
+
defp string_matches?(string, pattern) when is_binary(pattern) do
String.contains?(string, pattern)
end
@@ -44,14 +48,29 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicy do
end
defp check_replace(%{"object" => %{"content" => content, "summary" => summary}} = message) do
+ content =
+ if is_binary(content) do
+ content
+ else
+ ""
+ end
+
+ summary =
+ if is_binary(summary) do
+ summary
+ else
+ ""
+ end
+
{content, summary} =
- Enum.reduce(Pleroma.Config.get([:mrf_keyword, :replace]), {content, summary}, fn {pattern,
- replacement},
- {content_acc,
- summary_acc} ->
- {String.replace(content_acc, pattern, replacement),
- String.replace(summary_acc, pattern, replacement)}
- end)
+ Enum.reduce(
+ Pleroma.Config.get([:mrf_keyword, :replace]),
+ {content, summary},
+ fn {pattern, replacement}, {content_acc, summary_acc} ->
+ {String.replace(content_acc, pattern, replacement),
+ String.replace(summary_acc, pattern, replacement)}
+ end
+ )
{:ok,
message
@@ -60,11 +79,6 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicy do
end
@impl true
- def filter(%{"object" => %{"content" => nil}} = message) do
- {:ok, message}
- end
-
- @impl true
def filter(%{"type" => "Create", "object" => %{"content" => _content}} = message) do
with {:ok, message} <- check_reject(message),
{:ok, message} <- check_ftl_removal(message),
diff --git a/lib/pleroma/web/activity_pub/relay.ex b/lib/pleroma/web/activity_pub/relay.ex
index c496063ea..a7a20ca37 100644
--- a/lib/pleroma/web/activity_pub/relay.ex
+++ b/lib/pleroma/web/activity_pub/relay.ex
@@ -3,9 +3,9 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.Relay do
- alias Pleroma.User
- alias Pleroma.Object
alias Pleroma.Activity
+ alias Pleroma.Object
+ alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
require Logger
@@ -41,7 +41,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
+ %Object{} = object <- Object.normalize(activity) do
ActivityPub.announce(user, object, nil, true, false)
else
e -> Logger.error("error: #{inspect(e)}")
diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex
index 88007aa16..f733ae7e1 100644
--- a/lib/pleroma/web/activity_pub/transmogrifier.ex
+++ b/lib/pleroma/web/activity_pub/transmogrifier.ex
@@ -7,9 +7,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
A module to handle coding from internal to wire ActivityPub and back.
"""
alias Pleroma.Activity
- alias Pleroma.User
alias Pleroma.Object
alias Pleroma.Repo
+ alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.ActivityPub.Visibility
@@ -86,11 +86,15 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
end
def fix_addressing_list(map, field) do
- if is_binary(map[field]) do
- map
- |> Map.put(field, [map[field]])
- else
- map
+ cond do
+ is_binary(map[field]) ->
+ Map.put(map, field, [map[field]])
+
+ is_nil(map[field]) ->
+ Map.put(map, field, [])
+
+ true ->
+ map
end
end
@@ -128,13 +132,42 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|> fix_explicit_addressing(explicit_mentions)
end
+ # if as:Public is addressed, then make sure the followers collection is also addressed
+ # so that the activities will be delivered to local users.
+ def fix_implicit_addressing(%{"to" => to, "cc" => cc} = object, followers_collection) do
+ recipients = to ++ cc
+
+ if followers_collection not in recipients do
+ cond do
+ "https://www.w3.org/ns/activitystreams#Public" in cc ->
+ to = to ++ [followers_collection]
+ Map.put(object, "to", to)
+
+ "https://www.w3.org/ns/activitystreams#Public" in to ->
+ cc = cc ++ [followers_collection]
+ Map.put(object, "cc", cc)
+
+ true ->
+ object
+ end
+ else
+ object
+ end
+ end
+
+ def fix_implicit_addressing(object, _), do: object
+
def fix_addressing(object) do
+ %User{} = user = User.get_or_fetch_by_ap_id(object["actor"])
+ followers_collection = User.ap_followers(user)
+
object
|> fix_addressing_list("to")
|> fix_addressing_list("cc")
|> fix_addressing_list("bto")
|> fix_addressing_list("bcc")
|> fix_explicit_addressing
+ |> fix_implicit_addressing(followers_collection)
end
def fix_actor(%{"attributedTo" => actor} = object) do
@@ -355,6 +388,40 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
end
end
+ # Flag objects are placed ahead of the ID check because Mastodon 2.8 and earlier send them
+ # with nil ID.
+ def handle_incoming(%{"type" => "Flag", "object" => objects, "actor" => actor} = data) do
+ with context <- data["context"] || Utils.generate_context_id(),
+ content <- data["content"] || "",
+ %User{} = actor <- User.get_cached_by_ap_id(actor),
+
+ # Reduce the object list to find the reported user.
+ %User{} = account <-
+ Enum.reduce_while(objects, nil, fn ap_id, _ ->
+ with %User{} = user <- User.get_cached_by_ap_id(ap_id) do
+ {:halt, user}
+ else
+ _ -> {:cont, nil}
+ end
+ end),
+
+ # Remove the reported user from the object list.
+ statuses <- Enum.filter(objects, fn ap_id -> ap_id != account.ap_id end) do
+ params = %{
+ actor: actor,
+ context: context,
+ account: account,
+ statuses: statuses,
+ content: content,
+ additional: %{
+ "cc" => [account.ap_id]
+ }
+ }
+
+ ActivityPub.flag(params)
+ end
+ end
+
# disallow objects with bogus IDs
def handle_incoming(%{"id" => nil}), do: :error
def handle_incoming(%{"id" => ""}), do: :error
@@ -650,10 +717,10 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
if object = Object.normalize(id), do: {:ok, object}, else: nil
end
- def set_reply_to_uri(%{"inReplyTo" => inReplyTo} = object) when is_binary(inReplyTo) do
- with false <- String.starts_with?(inReplyTo, "http"),
- {:ok, %{data: replied_to_object}} <- get_obj_helper(inReplyTo) do
- Map.put(object, "inReplyTo", replied_to_object["external_url"] || inReplyTo)
+ def set_reply_to_uri(%{"inReplyTo" => in_reply_to} = object) when is_binary(in_reply_to) do
+ with false <- String.starts_with?(in_reply_to, "http"),
+ {:ok, %{data: replied_to_object}} <- get_obj_helper(in_reply_to) do
+ Map.put(object, "inReplyTo", replied_to_object["external_url"] || in_reply_to)
else
_e -> object
end
@@ -736,6 +803,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def prepare_outgoing(%{"type" => _type} = data) do
data =
data
+ |> strip_internal_fields
|> maybe_fix_object_url
|> Map.merge(Utils.make_json_ld_header())
@@ -829,10 +897,10 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
end
def add_attributed_to(object) do
- attributedTo = object["attributedTo"] || object["actor"]
+ attributed_to = object["attributedTo"] || object["actor"]
object
- |> Map.put("attributedTo", attributedTo)
+ |> Map.put("attributedTo", attributed_to)
end
def add_likes(%{"id" => id, "like_count" => likes} = object) do
@@ -870,7 +938,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
"announcements",
"announcement_count",
"emoji",
- "context_id"
+ "context_id",
+ "deleted_activity_id"
])
end
@@ -886,7 +955,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
defp strip_internal_tags(object), do: object
defp user_upgrade_task(user) do
- old_follower_address = User.ap_followers(user)
+ # we pass a fake user so that the followers collection is stripped away
+ old_follower_address = User.ap_followers(%User{nickname: user.nickname})
q =
from(
diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex
index 9e50789db..77841278a 100644
--- a/lib/pleroma/web/activity_pub/utils.ex
+++ b/lib/pleroma/web/activity_pub/utils.ex
@@ -3,17 +3,17 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.Utils do
+ alias Ecto.Changeset
+ alias Ecto.UUID
+ alias Pleroma.Activity
+ alias Pleroma.Notification
+ alias Pleroma.Object
alias Pleroma.Repo
+ alias Pleroma.User
alias Pleroma.Web
- alias Pleroma.Object
- alias Pleroma.Activity
alias Pleroma.Web.ActivityPub.Visibility
- alias Pleroma.User
- alias Pleroma.Notification
- alias Pleroma.Web.Router.Helpers
alias Pleroma.Web.Endpoint
- alias Ecto.Changeset
- alias Ecto.UUID
+ alias Pleroma.Web.Router.Helpers
import Ecto.Query
@@ -209,12 +209,12 @@ defmodule Pleroma.Web.ActivityPub.Utils do
"""
def insert_full_object(%{"object" => %{"type" => type} = object_data})
when is_map(object_data) and type in @supported_object_types do
- with {:ok, _} <- Object.create(object_data) do
- :ok
+ with {:ok, object} <- Object.create(object_data) do
+ {:ok, object}
end
end
- def insert_full_object(_), do: :ok
+ def insert_full_object(_), do: {:ok, nil}
def update_object_in_activities(%{data: %{"id" => id}} = object) do
# TODO
@@ -354,7 +354,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do
[state, actor, object]
)
- activity = Repo.get(Activity, activity.id)
+ activity = Activity.get_by_id(activity.id)
{:ok, activity}
rescue
e ->
@@ -621,7 +621,13 @@ defmodule Pleroma.Web.ActivityPub.Utils do
#### Flag-related helpers
def make_flag_data(params, additional) do
- status_ap_ids = Enum.map(params.statuses || [], & &1.data["id"])
+ status_ap_ids =
+ Enum.map(params.statuses || [], fn
+ %Activity{} = act -> act.data["id"]
+ act when is_map(act) -> act["id"]
+ act when is_binary(act) -> act
+ end)
+
object = [params.account.ap_id] ++ status_ap_ids
%{
@@ -633,4 +639,43 @@ defmodule Pleroma.Web.ActivityPub.Utils do
}
|> Map.merge(additional)
end
+
+ @doc """
+ Fetches the OrderedCollection/OrderedCollectionPage from `from`, limiting the amount of pages fetched after
+ the first one to `pages_left` pages.
+ If the amount of pages is higher than the collection has, it returns whatever was there.
+ """
+ def fetch_ordered_collection(from, pages_left, acc \\ []) do
+ with {:ok, response} <- Tesla.get(from),
+ {:ok, collection} <- Poison.decode(response.body) do
+ case collection["type"] do
+ "OrderedCollection" ->
+ # If we've encountered the OrderedCollection and not the page,
+ # just call the same function on the page address
+ fetch_ordered_collection(collection["first"], pages_left)
+
+ "OrderedCollectionPage" ->
+ if pages_left > 0 do
+ # There are still more pages
+ if Map.has_key?(collection, "next") do
+ # There are still more pages, go deeper saving what we have into the accumulator
+ fetch_ordered_collection(
+ collection["next"],
+ pages_left - 1,
+ acc ++ collection["orderedItems"]
+ )
+ else
+ # No more pages left, just return whatever we already have
+ acc ++ collection["orderedItems"]
+ end
+ else
+ # Got the amount of pages needed, add them all to the accumulator
+ acc ++ collection["orderedItems"]
+ end
+
+ _ ->
+ {:error, "Not an OrderedCollection or OrderedCollectionPage"}
+ end
+ end
+ end
end
diff --git a/lib/pleroma/web/activity_pub/views/object_view.ex b/lib/pleroma/web/activity_pub/views/object_view.ex
index 84fa94e32..6028b773c 100644
--- a/lib/pleroma/web/activity_pub/views/object_view.ex
+++ b/lib/pleroma/web/activity_pub/views/object_view.ex
@@ -17,7 +17,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectView do
def render("object.json", %{object: %Activity{data: %{"type" => "Create"}} = activity}) do
base = Pleroma.Web.ActivityPub.Utils.make_json_ld_header()
- object = Object.normalize(activity.data["object"])
+ object = Object.normalize(activity)
additional =
Transmogrifier.prepare_object(activity.data)
@@ -28,7 +28,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectView do
def render("object.json", %{object: %Activity{} = activity}) do
base = Pleroma.Web.ActivityPub.Utils.make_json_ld_header()
- object = Object.normalize(activity.data["object"])
+ object = Object.normalize(activity)
additional =
Transmogrifier.prepare_object(activity.data)
diff --git a/lib/pleroma/web/activity_pub/views/user_view.ex b/lib/pleroma/web/activity_pub/views/user_view.ex
index 415cbd47a..5926a3294 100644
--- a/lib/pleroma/web/activity_pub/views/user_view.ex
+++ b/lib/pleroma/web/activity_pub/views/user_view.ex
@@ -5,15 +5,15 @@
defmodule Pleroma.Web.ActivityPub.UserView do
use Pleroma.Web, :view
- alias Pleroma.Web.WebFinger
- alias Pleroma.Web.Salmon
- alias Pleroma.User
alias Pleroma.Repo
+ alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Web.ActivityPub.Utils
- alias Pleroma.Web.Router.Helpers
alias Pleroma.Web.Endpoint
+ alias Pleroma.Web.Router.Helpers
+ alias Pleroma.Web.Salmon
+ alias Pleroma.Web.WebFinger
import Ecto.Query
@@ -87,16 +87,10 @@ defmodule Pleroma.Web.ActivityPub.UserView do
"publicKeyPem" => public_key
},
"endpoints" => endpoints,
- "icon" => %{
- "type" => "Image",
- "url" => User.avatar_url(user)
- },
- "image" => %{
- "type" => "Image",
- "url" => User.banner_url(user)
- },
"tag" => user.info.source_data["tag"] || []
}
+ |> Map.merge(maybe_make_image(&User.avatar_url/2, "icon", user))
+ |> Map.merge(maybe_make_image(&User.banner_url/2, "image", user))
|> Map.merge(Utils.make_json_ld_header())
end
@@ -294,4 +288,17 @@ defmodule Pleroma.Web.ActivityPub.UserView do
map
end
end
+
+ defp maybe_make_image(func, key, user) do
+ if image = func.(user, no_default: true) do
+ %{
+ key => %{
+ "type" => "Image",
+ "url" => image
+ }
+ }
+ else
+ %{}
+ end
+ end
end