activitypub: implement reply visibility filter

This commit is contained in:
Ariadne Conill 2019-08-26 03:48:12 +00:00
parent c755d197f7
commit ff44200a5e
3 changed files with 75 additions and 11 deletions

View File

@ -250,7 +250,6 @@ config :pleroma, :instance,
safe_dm_mentions: false,
healthcheck: false,
remote_post_retention_days: 90,
skip_thread_containment: true,
limit_to_local_content: :unauthenticated,
dynamic_configuration: false,
user_bio_length: 5000,
@ -259,7 +258,8 @@ config :pleroma, :instance,
max_remote_account_fields: 20,
account_field_name_length: 512,
account_field_value_length: 512,
external_user_synchronization: true
external_user_synchronization: true,
default_reply_visibility: "public"
config :pleroma, :markup,
# XXX - unfortunately, inline images must be enabled by default right now, because

View File

@ -129,7 +129,6 @@ config :pleroma, Pleroma.Emails.Mailer,
* `remote_post_retention_days`: The default amount of days to retain remote posts when pruning the database.
* `user_bio_length`: A user bio maximum length (default: `5000`)
* `user_name_length`: A user name maximum length (default: `100`)
* `skip_thread_containment`: Skip filter out broken threads. The default is `false`.
* `limit_to_local_content`: Limit unauthenticated users to search for local statutes and users only. Possible values: `:unauthenticated`, `:all` and `false`. The default is `:unauthenticated`.
* `dynamic_configuration`: Allow transferring configuration to DB with the subsequent customization from Admin api.
* `max_account_fields`: The maximum number of custom fields in the user profile (default: `10`)
@ -137,7 +136,11 @@ config :pleroma, Pleroma.Emails.Mailer,
* `account_field_name_length`: An account field name maximum length (default: `512`)
* `account_field_value_length`: An account field value maximum length (default: `512`)
* `external_user_synchronization`: Enabling following/followers counters synchronization for external users.
* `default_reply_visibility`: The default reply visibility filter:
* "none": show all replies in timelines (like GNU Social)
* "public": show public replies in timelines (default)
* "following": show replies involving only people the user follows (like Mastodon)
* "self": show replies only from the user
## :logger

View File

@ -527,7 +527,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|> 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(
@ -696,13 +696,62 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
defp restrict_tag(query, _), do: query
defp restrict_recipients(query, [], _user), do: query
defp restrict_recipients(query, recipients, nil) do
from(activity in query, where: fragment("? && ?", ^recipients, activity.recipients))
defp get_friend_ap_ids(%User{} = user) do
from(u in User.get_friends_query(user), select: u.ap_id)
|> Repo.all()
end
defp restrict_recipients(query, recipients, user) do
defp restrict_recipients(query, [], _opts), do: query
defp restrict_recipients(query, recipients, %{
"user" => %User{} = user,
"reply_visibility" => visibility
})
when visibility in ["self", "following"] do
reply_recipients =
case visibility do
"self" -> [user.ap_id]
"following" -> [user.ap_id] ++ get_friend_ap_ids(user)
end
from(
[activity, object] in query,
where:
fragment(
"? && ? and (?->>'inReplyTo' is null or ? <@ ?)",
^recipients,
activity.recipients,
object.data,
activity.recipient_users,
^reply_recipients
)
)
end
defp restrict_recipients(query, recipients, %{
"user" => %User{} = user,
"reply_visibility" => "public"
}) do
reply_recipients = [user.ap_id] ++ get_friend_ap_ids(user)
public_recipients = [Pleroma.Constants.as_public()]
from(
[activity, object] in query,
where:
fragment(
"? && ? and (?->>'inReplyTo' is null or ? && ? or ? <@ ?)",
^recipients,
activity.recipients,
object.data,
activity.recipients,
^public_recipients,
activity.recipient_users,
^reply_recipients
)
)
end
defp restrict_recipients(query, recipients, %{"user" => %User{} = user}) do
from(
activity in query,
where: fragment("? && ?", ^recipients, activity.recipients),
@ -710,6 +759,10 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
)
end
defp restrict_recipients(query, recipients, _opts) do
from(activity in query, where: fragment("? && ?", ^recipients, activity.recipients))
end
defp restrict_local(query, %{"local_only" => true}) do
from(activity in query, where: activity.local == true)
end
@ -907,12 +960,20 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
defp maybe_order(query, _), do: query
def fetch_activities_query(recipients, opts \\ %{}) do
opts =
if !Map.has_key?(opts, "user") do
opts
else
default_vis = Pleroma.Config.get([:instance, :default_reply_visibility])
Map.put_new(opts, "reply_visibility", default_vis)
end
Activity
|> maybe_preload_objects(opts)
|> maybe_preload_bookmarks(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)