forked from AkkomaGang/akkoma
Fix create processing in direct message disabled
This commit is contained in:
parent
ab34680554
commit
037f881187
12 changed files with 111 additions and 25 deletions
|
@ -6,8 +6,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
|
||||
## Unreleased
|
||||
|
||||
## Added
|
||||
- Custom options for users to accept/reject private messages
|
||||
- options: everybody, nobody, people\_i\_follow
|
||||
- MRF to reject notes from accounts newer than a given age
|
||||
- this will have the side-effect of rejecting legitimate messages if your
|
||||
post gets boosted outside of your local bubble and people your instance
|
||||
does not know about reply to it.
|
||||
|
||||
## Fixed
|
||||
- Support for `streams` public key URIs
|
||||
- Bookmarks are cleaned up on DB prune now
|
||||
|
||||
## 2023.04
|
||||
|
||||
|
|
|
@ -418,6 +418,8 @@
|
|||
|
||||
config :pleroma, :mrf_follow_bot, follower_nickname: nil
|
||||
|
||||
config :pleroma, :mrf_reject_newly_created_account_notes, age: 86_400
|
||||
|
||||
config :pleroma, :rich_media,
|
||||
enabled: true,
|
||||
ignore_hosts: [],
|
||||
|
|
|
@ -160,7 +160,8 @@ defmodule Pleroma.User do
|
|||
field(:status_ttl_days, :integer, default: nil)
|
||||
|
||||
field(:accepts_direct_messages_from, Ecto.Enum,
|
||||
values: [:everybody, :people_i_follow, :nobody]
|
||||
values: [:everybody, :people_i_follow, :nobody],
|
||||
default: :everybody
|
||||
)
|
||||
|
||||
embeds_one(
|
||||
|
|
|
@ -12,7 +12,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.DirectMessageDisabledPolicy do
|
|||
@impl true
|
||||
def filter(
|
||||
%{
|
||||
"type" => "Note",
|
||||
"type" => "Create",
|
||||
"actor" => actor
|
||||
} = activity
|
||||
) do
|
||||
|
@ -24,9 +24,13 @@ def filter(
|
|||
should_filter?(sender, recv)
|
||||
end)
|
||||
|
||||
{:ok, Map.put(activity, :to, new_to)}
|
||||
{:ok,
|
||||
activity
|
||||
|> Map.put("to", new_to)
|
||||
|> maybe_replace_object_to(new_to)}
|
||||
else
|
||||
_ -> {:ok, activity}
|
||||
_ ->
|
||||
{:ok, activity}
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -43,4 +47,10 @@ defp should_filter?(sender, receiver_ap_id) do
|
|||
_ -> false
|
||||
end
|
||||
end
|
||||
|
||||
defp maybe_replace_object_to(%{"object" => %{"to" => _}} = activity, to) do
|
||||
Kernel.put_in(activity, ["object", "to"], to)
|
||||
end
|
||||
|
||||
defp maybe_replace_object_to(other, _), do: other
|
||||
end
|
||||
|
|
|
@ -16,9 +16,9 @@ def filter(
|
|||
when type in ["Note", "Create"] do
|
||||
min_age = Pleroma.Config.get([:mrf_reject_newly_created_account_notes, :age])
|
||||
|
||||
with %User{} = user <- Pleroma.User.get_cached_by_ap_id(actor),
|
||||
with %User{local: false} = user <- Pleroma.User.get_cached_by_ap_id(actor),
|
||||
true <- Timex.diff(Timex.now(), user.inserted_at, :seconds) < min_age do
|
||||
{:reject, "Account created too recently"}
|
||||
{:reject, "[RejectNewlyCreatedAccountNotesPolicy] Account created too recently"}
|
||||
else
|
||||
_ -> {:ok, activity}
|
||||
end
|
||||
|
|
|
@ -717,8 +717,7 @@ defp update_credentials_request do
|
|||
"people_i_follow"
|
||||
],
|
||||
nullable: true,
|
||||
description:
|
||||
"Who to accept DMs from"
|
||||
description: "Who to accept DMs from"
|
||||
}
|
||||
},
|
||||
example: %{
|
||||
|
|
|
@ -191,7 +191,7 @@ def update_credentials(%{assigns: %{user: user}, body_params: params} = conn, _p
|
|||
:show_role,
|
||||
:skip_thread_containment,
|
||||
:allow_following_move,
|
||||
:also_known_as,
|
||||
:also_known_as
|
||||
]
|
||||
|> Enum.reduce(%{}, fn key, acc ->
|
||||
Maps.put_if_present(acc, key, params[key], &{:ok, Params.truthy_param?(&1)})
|
||||
|
|
|
@ -8,7 +8,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.DirectMessageDisabledPolicyTest do
|
|||
describe "strips recipients" do
|
||||
test "when the user denies the direct message" do
|
||||
sender = insert(:user)
|
||||
recipient = insert(:user, %{accepts_direct_messages_from_not_followed: false})
|
||||
recipient = insert(:user, %{accepts_direct_messages_from: :nobody})
|
||||
|
||||
refute User.accepts_direct_messages?(recipient, sender)
|
||||
|
||||
|
@ -16,15 +16,15 @@ test "when the user denies the direct message" do
|
|||
"actor" => sender.ap_id,
|
||||
"to" => [recipient.ap_id],
|
||||
"cc" => [],
|
||||
"type" => "Note"
|
||||
"type" => "Create"
|
||||
}
|
||||
|
||||
assert {:ok, %{to: []}} = DirectMessageDisabledPolicy.filter(message)
|
||||
assert {:ok, %{"to" => []}} = DirectMessageDisabledPolicy.filter(message)
|
||||
end
|
||||
|
||||
test "when the user does not deny the direct message" do
|
||||
sender = insert(:user)
|
||||
recipient = insert(:user, %{accepts_direct_messages_from_not_followed: true})
|
||||
recipient = insert(:user, %{accepts_direct_messages_from: :everybody})
|
||||
|
||||
assert User.accepts_direct_messages?(recipient, sender)
|
||||
|
||||
|
@ -32,11 +32,11 @@ test "when the user does not deny the direct message" do
|
|||
"actor" => sender.ap_id,
|
||||
"to" => [recipient.ap_id],
|
||||
"cc" => [],
|
||||
"type" => "Note"
|
||||
"type" => "Create"
|
||||
}
|
||||
|
||||
assert {:ok, message} = DirectMessageDisabledPolicy.filter(message)
|
||||
assert message.to == [recipient.ap_id]
|
||||
assert message["to"] == [recipient.ap_id]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
defmodule Pleroma.Web.ActivityPub.MRF.RejectNewlyCreatedAccountNotesPolicyTest do
|
||||
use Pleroma.DataCase
|
||||
import Pleroma.Factory
|
||||
|
||||
alias Pleroma.Web.ActivityPub.MRF.RejectNewlyCreatedAccountNotesPolicy
|
||||
|
||||
describe "reject notes from new accounts" do
|
||||
test "rejects notes from accounts created more recently than `age`" do
|
||||
clear_config([:mrf_reject_newly_created_account_notes, :age], 86_400)
|
||||
sender = insert(:user, %{inserted_at: Timex.now(), local: false})
|
||||
|
||||
message = %{
|
||||
"actor" => sender.ap_id,
|
||||
"type" => "Create"
|
||||
}
|
||||
|
||||
assert {:reject, _} = RejectNewlyCreatedAccountNotesPolicy.filter(message)
|
||||
end
|
||||
|
||||
test "does not reject notes from accounts created longer ago" do
|
||||
clear_config([:mrf_reject_newly_created_account_notes, :age], 86_400)
|
||||
a_day_ago = Timex.shift(Timex.now(), days: -1)
|
||||
sender = insert(:user, %{inserted_at: a_day_ago, local: false})
|
||||
|
||||
message = %{
|
||||
"actor" => sender.ap_id,
|
||||
"type" => "Create"
|
||||
}
|
||||
|
||||
assert {:ok, _} = RejectNewlyCreatedAccountNotesPolicy.filter(message)
|
||||
end
|
||||
|
||||
test "does not affect local users" do
|
||||
clear_config([:mrf_reject_newly_created_account_notes, :age], 86_400)
|
||||
sender = insert(:user, %{inserted_at: Timex.now(), local: true})
|
||||
|
||||
message = %{
|
||||
"actor" => sender.ap_id,
|
||||
"type" => "Create"
|
||||
}
|
||||
|
||||
assert {:ok, _} = RejectNewlyCreatedAccountNotesPolicy.filter(message)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -102,7 +102,13 @@ test "it works as expected with noop policy" do
|
|||
clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.NoOpPolicy])
|
||||
|
||||
expected = %{
|
||||
mrf_policies: ["NoOpPolicy", "HashtagPolicy", "InlineQuotePolicy", "NormalizeMarkup"],
|
||||
mrf_policies: [
|
||||
"NoOpPolicy",
|
||||
"HashtagPolicy",
|
||||
"InlineQuotePolicy",
|
||||
"NormalizeMarkup",
|
||||
"DirectMessageDisabledPolicy"
|
||||
],
|
||||
mrf_hashtag: %{
|
||||
federated_timeline_removal: [],
|
||||
reject: [],
|
||||
|
@ -118,7 +124,13 @@ test "it works as expected with mock policy" do
|
|||
clear_config([:mrf, :policies], [MRFModuleMock])
|
||||
|
||||
expected = %{
|
||||
mrf_policies: ["MRFModuleMock", "HashtagPolicy", "InlineQuotePolicy", "NormalizeMarkup"],
|
||||
mrf_policies: [
|
||||
"MRFModuleMock",
|
||||
"HashtagPolicy",
|
||||
"InlineQuotePolicy",
|
||||
"NormalizeMarkup",
|
||||
"DirectMessageDisabledPolicy"
|
||||
],
|
||||
mrf_module_mock: "some config data",
|
||||
mrf_hashtag: %{
|
||||
federated_timeline_removal: [],
|
||||
|
|
|
@ -316,7 +316,7 @@ test "it strips internal reactions" do
|
|||
test "it correctly processes messages with non-array to field" do
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
|> Jason.decode!()
|
||||
|> Map.put("to", "https://www.w3.org/ns/activitystreams#Public")
|
||||
|> put_in(["object", "to"], "https://www.w3.org/ns/activitystreams#Public")
|
||||
|
||||
|
@ -333,7 +333,7 @@ test "it correctly processes messages with non-array to field" do
|
|||
test "it correctly processes messages with non-array cc field" do
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
|> Jason.decode!()
|
||||
|> Map.put("cc", "http://mastodon.example.org/users/admin/followers")
|
||||
|> put_in(["object", "cc"], "http://mastodon.example.org/users/admin/followers")
|
||||
|
||||
|
@ -346,7 +346,7 @@ test "it correctly processes messages with non-array cc field" do
|
|||
test "it correctly processes messages with weirdness in address fields" do
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
|> Jason.decode!()
|
||||
|> Map.put("cc", ["http://mastodon.example.org/users/admin/followers", ["¿"]])
|
||||
|> put_in(["object", "cc"], ["http://mastodon.example.org/users/admin/followers", ["¿"]])
|
||||
|
||||
|
@ -412,7 +412,7 @@ test "does NOT schedule background fetching of `replies` beyond max thread depth
|
|||
|
||||
activity =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
|> Jason.decode!()
|
||||
|> Kernel.put_in(["object", "replies"], replies)
|
||||
|
||||
%{activity: activity}
|
||||
|
|
|
@ -735,7 +735,9 @@ test "actor_type field has a higher priority than bot", %{conn: conn} do
|
|||
test "changing to :everybody", %{conn: conn} do
|
||||
account =
|
||||
conn
|
||||
|> patch("/api/v1/accounts/update_credentials", %{accepts_direct_messages_from: "everybody"})
|
||||
|> patch("/api/v1/accounts/update_credentials", %{
|
||||
accepts_direct_messages_from: "everybody"
|
||||
})
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert account["accepts_direct_messages_from"]
|
||||
|
@ -757,17 +759,23 @@ test "changing to :nobody", %{conn: conn} do
|
|||
test "changing to :people_i_follow", %{conn: conn} do
|
||||
account =
|
||||
conn
|
||||
|> patch("/api/v1/accounts/update_credentials", %{accepts_direct_messages_from: "people_i_follow"})
|
||||
|> patch("/api/v1/accounts/update_credentials", %{
|
||||
accepts_direct_messages_from: "people_i_follow"
|
||||
})
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert account["accepts_direct_messages_from"]
|
||||
assert account["accepts_direct_messages_from"] == "people_i_follow"
|
||||
assert Pleroma.User.get_by_ap_id(account["url"]).accepts_direct_messages_from == :people_i_follow
|
||||
|
||||
assert Pleroma.User.get_by_ap_id(account["url"]).accepts_direct_messages_from ==
|
||||
:people_i_follow
|
||||
end
|
||||
|
||||
test "changing to an unsupported value", %{conn: conn} do
|
||||
conn
|
||||
|> patch("/api/v1/accounts/update_credentials", %{accepts_direct_messages_from: "unsupported"})
|
||||
|> patch("/api/v1/accounts/update_credentials", %{
|
||||
accepts_direct_messages_from: "unsupported"
|
||||
})
|
||||
|> json_response(400)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue