aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/pleroma/user.ex14
-rw-r--r--lib/pleroma/user/query.ex4
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub.ex75
-rw-r--r--lib/pleroma/web/common_api/activity_draft.ex16
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex1
5 files changed, 94 insertions, 16 deletions
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index 477237756..b451202b2 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -832,6 +832,7 @@ defmodule Pleroma.User do
def set_cache(%User{} = user) do
Cachex.put(:user_cache, "ap_id:#{user.ap_id}", user)
Cachex.put(:user_cache, "nickname:#{user.nickname}", user)
+ Cachex.put(:user_cache, "friends_ap_ids:#{user.nickname}", get_user_friends_ap_ids(user))
{:ok, user}
end
@@ -847,9 +848,22 @@ defmodule Pleroma.User do
end
end
+ def get_user_friends_ap_ids(user) do
+ from(u in User.get_friends_query(user), select: u.ap_id)
+ |> Repo.all()
+ end
+
+ @spec get_cached_user_friends_ap_ids(User.t()) :: [String.t()]
+ def get_cached_user_friends_ap_ids(user) do
+ Cachex.fetch!(:user_cache, "friends_ap_ids:#{user.ap_id}", fn _ ->
+ get_user_friends_ap_ids(user)
+ end)
+ end
+
def invalidate_cache(user) do
Cachex.del(:user_cache, "ap_id:#{user.ap_id}")
Cachex.del(:user_cache, "nickname:#{user.nickname}")
+ Cachex.del(:user_cache, "friends_ap_ids:#{user.ap_id}")
end
@spec get_cached_by_ap_id(String.t()) :: User.t() | nil
diff --git a/lib/pleroma/user/query.ex b/lib/pleroma/user/query.ex
index ec88088cf..ac77aab71 100644
--- a/lib/pleroma/user/query.ex
+++ b/lib/pleroma/user/query.ex
@@ -54,13 +54,13 @@ defmodule Pleroma.User.Query do
select: term(),
limit: pos_integer()
}
- | %{}
+ | map()
@ilike_criteria [:nickname, :name, :query]
@equal_criteria [:email]
@contains_criteria [:ap_id, :nickname]
- @spec build(criteria()) :: Query.t()
+ @spec build(Query.t(), criteria()) :: Query.t()
def build(query \\ base_query(), criteria) do
prepare_query(query, criteria)
end
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index c67b3335d..8b170b7f8 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -270,9 +270,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
),
{:ok, activity} <- insert(create_data, local, fake),
{:fake, false, activity} <- {:fake, fake, activity},
+ {:quick_insert, false, activity} <- {:quick_insert, quick_insert?, activity},
_ <- increase_replies_count_if_reply(create_data),
_ <- increase_poll_votes_if_vote(create_data),
- {:quick_insert, false, activity} <- {:quick_insert, quick_insert?, activity},
{:ok, _actor} <- increase_note_count_if_public(actor, activity),
:ok <- maybe_federate(activity) do
{:ok, activity}
@@ -700,12 +700,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
do: [opts["user"].ap_id | User.following(opts["user"])] ++ public,
else: public
+ opts = Map.put(opts, "user", opts["user"])
+
from(activity in Activity)
|> maybe_preload_objects(opts)
|> maybe_preload_bookmarks(opts)
|> maybe_set_thread_muted_field(opts)
|> restrict_blocked(opts)
- |> restrict_recipients(recipients, opts["user"])
+ |> restrict_recipients(recipients, opts)
|> where(
[activity],
fragment(
@@ -740,7 +742,10 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
@spec fetch_public_activities(map(), Pagination.type()) :: [Activity.t()]
def fetch_public_activities(opts \\ %{}, pagination \\ :keyset) do
- opts = Map.drop(opts, ["user"])
+ opts =
+ opts
+ |> Map.put("reply_user", opts["user"])
+ |> Map.delete("user")
[Constants.as_public()]
|> fetch_activities_query(opts)
@@ -976,13 +981,65 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
defp restrict_tag(query, _), do: query
- defp restrict_recipients(query, [], _user), do: query
+ defp reply_recipients(user, "following") do
+ [user.ap_id | User.get_cached_user_friends_ap_ids(user)]
+ end
+
+ defp reply_recipients(user, "self"), do: [user.ap_id]
+
+ defp restrict_recipients(query, [], _opts), do: query
+
+ defp restrict_recipients(
+ query,
+ recipients,
+ %{"user" => nil, "reply_user" => user, "reply_visibility" => visibility}
+ )
+ when not is_nil(user) and visibility in ["following", "self"] do
+ reply_recipients = reply_recipients(user, visibility)
- defp restrict_recipients(query, recipients, nil) do
- from(activity in query, where: fragment("? && ?", ^recipients, activity.recipients))
+ from([activity, object] in query,
+ where:
+ fragment(
+ "? && ? AND (?->>'inReplyTo' IS NULL OR array_remove(?, ?) && ? OR ? = ?)",
+ ^recipients,
+ activity.recipients,
+ object.data,
+ activity.recipients,
+ activity.actor,
+ ^reply_recipients,
+ activity.actor,
+ ^user.ap_id
+ )
+ )
end
- defp restrict_recipients(query, recipients, user) do
+ defp restrict_recipients(query, recipients, %{"user" => nil}) do
+ from(activity in query,
+ where: fragment("? && ?", ^recipients, activity.recipients)
+ )
+ end
+
+ defp restrict_recipients(query, recipients, %{"user" => user, "reply_visibility" => visibility})
+ when visibility in ["following", "self"] do
+ reply_recipients = reply_recipients(user, visibility)
+
+ from(
+ [activity, object] in query,
+ where:
+ fragment(
+ "? && ? AND (?->>'inReplyTo' IS NULL OR array_remove(?, ?) && ?)",
+ ^recipients,
+ activity.recipients,
+ object.data,
+ activity.recipients,
+ activity.actor,
+ ^reply_recipients
+ ),
+ or_where: activity.actor == ^user.ap_id
+ )
+ end
+
+ defp restrict_recipients(query, recipients, %{"user" => user}) do
from(
activity in query,
where: fragment("? && ?", ^recipients, activity.recipients),
@@ -1254,13 +1311,15 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
skip_thread_containment: Config.get([:instance, :skip_thread_containment])
}
+ opts = Map.put(opts, "user", opts["user"])
+
Activity
|> maybe_preload_objects(opts)
|> maybe_preload_bookmarks(opts)
|> maybe_preload_report_notes(opts)
|> maybe_set_thread_muted_field(opts)
|> maybe_order(opts)
- |> restrict_recipients(recipients, opts["user"])
+ |> restrict_recipients(recipients, opts)
|> restrict_tag(opts)
|> restrict_tag_reject(opts)
|> restrict_tag_all(opts)
diff --git a/lib/pleroma/web/common_api/activity_draft.ex b/lib/pleroma/web/common_api/activity_draft.ex
index c1cd15bb2..244cf2be5 100644
--- a/lib/pleroma/web/common_api/activity_draft.ex
+++ b/lib/pleroma/web/common_api/activity_draft.ex
@@ -84,14 +84,18 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
%__MODULE__{draft | attachments: attachments}
end
- defp in_reply_to(draft) do
- case Map.get(draft.params, "in_reply_to_status_id") do
- "" -> draft
- nil -> draft
- id -> %__MODULE__{draft | in_reply_to: Activity.get_by_id(id)}
- end
+ defp in_reply_to(%{params: %{"in_reply_to_status_id" => ""}} = draft), do: draft
+
+ defp in_reply_to(%{params: %{"in_reply_to_status_id" => id}} = draft) when is_binary(id) do
+ %__MODULE__{draft | in_reply_to: Activity.get_by_id(id)}
end
+ defp in_reply_to(%{params: %{"in_reply_to_status_id" => %Activity{} = in_reply_to}} = draft) do
+ %__MODULE__{draft | in_reply_to: in_reply_to}
+ end
+
+ defp in_reply_to(draft), do: draft
+
defp in_reply_to_conversation(draft) do
in_reply_to_conversation = Participation.get(draft.params["in_reply_to_conversation_id"])
%__MODULE__{draft | in_reply_to_conversation: in_reply_to_conversation}
diff --git a/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex b/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex
index b3c58005e..a2ac9301e 100644
--- a/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex
@@ -100,6 +100,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|> Map.put("local_only", local_only)
|> Map.put("blocking_user", user)
|> Map.put("muting_user", user)
+ |> Map.put("user", user)
|> ActivityPub.fetch_public_activities()
conn