forked from AkkomaGang/akkoma
1f863f0a36
Objects who got updated would just pass through several of the MRF policies, undoing moderation in some situations. In the relevant cases we now check not only for Create activities, but also Update activities. I checked which ones checked explicitly on type Create using `grep '"type" => "Create"' lib/pleroma/web/activity_pub/mrf/*`. The following from that list have not been changed: * lib/pleroma/web/activity_pub/mrf/follow_bot_policy.ex * Not relevant for moderation * lib/pleroma/web/activity_pub/mrf/keyword_policy.ex * Already had a test for Update * lib/pleroma/web/activity_pub/mrf/object_age_policy.ex * In practice only relevant when fetching old objects (e.g. through Like or Announce). These are always wrapped in a Create. * lib/pleroma/web/activity_pub/mrf/reject_non_public.ex * We don't allow changing scope with Update, so not relevant here
286 lines
7.2 KiB
Elixir
286 lines
7.2 KiB
Elixir
# Pleroma: A lightweight social networking server
|
|
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
|
# SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
defmodule Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicyTest do
|
|
use Pleroma.DataCase
|
|
import Pleroma.Factory
|
|
import ExUnit.CaptureLog
|
|
|
|
alias Pleroma.Web.ActivityPub.MRF
|
|
alias Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicy
|
|
|
|
@linkless_message %{
|
|
"type" => "Create",
|
|
"object" => %{
|
|
"content" => "hi world!"
|
|
}
|
|
}
|
|
|
|
@linkful_message %{
|
|
"type" => "Create",
|
|
"object" => %{
|
|
"content" => "<a href='https://example.com'>hi world!</a>"
|
|
}
|
|
}
|
|
|
|
@response_message %{
|
|
"type" => "Create",
|
|
"object" => %{
|
|
"name" => "yes",
|
|
"type" => "Answer"
|
|
}
|
|
}
|
|
|
|
@linkless_update_message %{
|
|
"type" => "Update",
|
|
"object" => %{
|
|
"content" => "hi world!"
|
|
}
|
|
}
|
|
|
|
@linkful_update_message %{
|
|
"type" => "Update",
|
|
"object" => %{
|
|
"content" => "<a href='https://example.com'>hi world!</a>"
|
|
}
|
|
}
|
|
|
|
@response_update_message %{
|
|
"type" => "Update",
|
|
"object" => %{
|
|
"name" => "yes",
|
|
"type" => "Answer"
|
|
}
|
|
}
|
|
|
|
describe "with new user" do
|
|
test "it allows posts without links" do
|
|
user = insert(:user, local: false)
|
|
|
|
assert user.note_count == 0
|
|
|
|
message =
|
|
@linkless_message
|
|
|> Map.put("actor", user.ap_id)
|
|
|
|
update_message =
|
|
@linkless_update_message
|
|
|> Map.put("actor", user.ap_id)
|
|
|
|
{:ok, _message} = AntiLinkSpamPolicy.filter(message)
|
|
{:ok, _update_message} = AntiLinkSpamPolicy.filter(update_message)
|
|
end
|
|
|
|
test "it disallows posts with links" do
|
|
user = insert(:user, local: false)
|
|
|
|
assert user.note_count == 0
|
|
|
|
message = %{
|
|
"type" => "Create",
|
|
"actor" => user.ap_id,
|
|
"object" => %{
|
|
"formerRepresentations" => %{
|
|
"type" => "OrderedCollection",
|
|
"orderedItems" => [
|
|
%{
|
|
"content" => "<a href='https://example.com'>hi world!</a>"
|
|
}
|
|
]
|
|
},
|
|
"content" => "mew"
|
|
}
|
|
}
|
|
|
|
update_message = %{
|
|
"type" => "Update",
|
|
"actor" => user.ap_id,
|
|
"object" => %{
|
|
"formerRepresentations" => %{
|
|
"type" => "OrderedCollection",
|
|
"orderedItems" => [
|
|
%{
|
|
"content" => "<a href='https://example.com'>hi world!</a>"
|
|
}
|
|
]
|
|
},
|
|
"content" => "mew"
|
|
}
|
|
}
|
|
|
|
{:reject, _} = MRF.filter_one(AntiLinkSpamPolicy, message)
|
|
{:reject, _} = MRF.filter_one(AntiLinkSpamPolicy, update_message)
|
|
end
|
|
|
|
test "it allows posts with links for local users" do
|
|
user = insert(:user)
|
|
|
|
assert user.note_count == 0
|
|
|
|
message =
|
|
@linkful_message
|
|
|> Map.put("actor", user.ap_id)
|
|
|
|
update_message =
|
|
@linkful_update_message
|
|
|> Map.put("actor", user.ap_id)
|
|
|
|
{:ok, _message} = AntiLinkSpamPolicy.filter(message)
|
|
{:ok, _update_message} = AntiLinkSpamPolicy.filter(update_message)
|
|
end
|
|
|
|
test "it disallows posts with links in history" do
|
|
user = insert(:user, local: false)
|
|
|
|
assert user.note_count == 0
|
|
|
|
message =
|
|
@linkful_message
|
|
|> Map.put("actor", user.ap_id)
|
|
|
|
update_message =
|
|
@linkful_update_message
|
|
|> Map.put("actor", user.ap_id)
|
|
|
|
{:reject, _} = AntiLinkSpamPolicy.filter(message)
|
|
{:reject, _} = AntiLinkSpamPolicy.filter(update_message)
|
|
end
|
|
end
|
|
|
|
describe "with old user" do
|
|
test "it allows posts without links" do
|
|
user = insert(:user, note_count: 1)
|
|
|
|
assert user.note_count == 1
|
|
|
|
message =
|
|
@linkless_message
|
|
|> Map.put("actor", user.ap_id)
|
|
|
|
update_message =
|
|
@linkless_update_message
|
|
|> Map.put("actor", user.ap_id)
|
|
|
|
{:ok, _message} = AntiLinkSpamPolicy.filter(message)
|
|
{:ok, _update_message} = AntiLinkSpamPolicy.filter(update_message)
|
|
end
|
|
|
|
test "it allows posts with links" do
|
|
user = insert(:user, note_count: 1)
|
|
|
|
assert user.note_count == 1
|
|
|
|
message =
|
|
@linkful_message
|
|
|> Map.put("actor", user.ap_id)
|
|
|
|
update_message =
|
|
@linkful_update_message
|
|
|> Map.put("actor", user.ap_id)
|
|
|
|
{:ok, _message} = AntiLinkSpamPolicy.filter(message)
|
|
{:ok, _update_message} = AntiLinkSpamPolicy.filter(update_message)
|
|
end
|
|
end
|
|
|
|
describe "with followed new user" do
|
|
test "it allows posts without links" do
|
|
user = insert(:user, follower_count: 1)
|
|
|
|
assert user.follower_count == 1
|
|
|
|
message =
|
|
@linkless_message
|
|
|> Map.put("actor", user.ap_id)
|
|
|
|
update_message =
|
|
@linkless_update_message
|
|
|> Map.put("actor", user.ap_id)
|
|
|
|
{:ok, _message} = AntiLinkSpamPolicy.filter(message)
|
|
{:ok, _update_message} = AntiLinkSpamPolicy.filter(update_message)
|
|
end
|
|
|
|
test "it allows posts with links" do
|
|
user = insert(:user, follower_count: 1)
|
|
|
|
assert user.follower_count == 1
|
|
|
|
message =
|
|
@linkful_message
|
|
|> Map.put("actor", user.ap_id)
|
|
|
|
update_message =
|
|
@linkful_update_message
|
|
|> Map.put("actor", user.ap_id)
|
|
|
|
{:ok, _message} = AntiLinkSpamPolicy.filter(message)
|
|
{:ok, _update_message} = AntiLinkSpamPolicy.filter(update_message)
|
|
end
|
|
end
|
|
|
|
describe "with unknown actors" do
|
|
setup do
|
|
Tesla.Mock.mock(fn
|
|
%{method: :get, url: "http://invalid.actor"} ->
|
|
%Tesla.Env{status: 500, body: ""}
|
|
end)
|
|
|
|
:ok
|
|
end
|
|
|
|
test "it rejects posts without links" do
|
|
message =
|
|
@linkless_message
|
|
|> Map.put("actor", "http://invalid.actor")
|
|
|
|
update_message =
|
|
@linkless_update_message
|
|
|> Map.put("actor", "http://invalid.actor")
|
|
|
|
assert capture_log(fn ->
|
|
{:reject, _} = AntiLinkSpamPolicy.filter(message)
|
|
end) =~ "[error] Could not decode user at fetch http://invalid.actor"
|
|
|
|
assert capture_log(fn ->
|
|
{:reject, _} = AntiLinkSpamPolicy.filter(update_message)
|
|
end) =~ "[error] Could not decode user at fetch http://invalid.actor"
|
|
end
|
|
|
|
test "it rejects posts with links" do
|
|
message =
|
|
@linkful_message
|
|
|> Map.put("actor", "http://invalid.actor")
|
|
|
|
update_message =
|
|
@linkful_update_message
|
|
|> Map.put("actor", "http://invalid.actor")
|
|
|
|
assert capture_log(fn ->
|
|
{:reject, _} = AntiLinkSpamPolicy.filter(message)
|
|
end) =~ "[error] Could not decode user at fetch http://invalid.actor"
|
|
|
|
assert capture_log(fn ->
|
|
{:reject, _} = AntiLinkSpamPolicy.filter(update_message)
|
|
end) =~ "[error] Could not decode user at fetch http://invalid.actor"
|
|
end
|
|
end
|
|
|
|
describe "with contentless-objects" do
|
|
test "it does not reject them or error out" do
|
|
user = insert(:user, note_count: 1)
|
|
|
|
message =
|
|
@response_message
|
|
|> Map.put("actor", user.ap_id)
|
|
|
|
update_message =
|
|
@response_update_message
|
|
|> Map.put("actor", user.ap_id)
|
|
|
|
{:ok, _message} = AntiLinkSpamPolicy.filter(message)
|
|
{:ok, _update_message} = AntiLinkSpamPolicy.filter(update_message)
|
|
end
|
|
end
|
|
end
|