forked from YokaiRick/akkoma
Also use actor_type to determine if an account is a bot in antiFollowbotPolicy
This commit is contained in:
parent
3fd87b6a75
commit
661d0ba481
4 changed files with 66 additions and 15 deletions
|
@ -117,6 +117,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
- Improved Twittercard and OpenGraph meta tag generation including thumbnails and image dimension metadata when available.
|
||||
- AdminAPI: sort users so the newest are at the top.
|
||||
- ActivityPub Client-to-Server(C2S): Limitation on the type of Activity/Object are lifted as they are now passed through ObjectValidators
|
||||
- MRF (`AntiFollowbotPolicy`): Bot accounts are now also considered followbots. Users can still allow bots to follow them by first following the bot.
|
||||
|
||||
### Added
|
||||
|
||||
|
|
|
@ -125,6 +125,8 @@ To add configuration to your config file, you can copy it from the base config.
|
|||
* `Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy`: Sets a default expiration on all posts made by users of the local instance. Requires `Pleroma.Workers.PurgeExpiredActivity` to be enabled for processing the scheduled delections.
|
||||
* `Pleroma.Web.ActivityPub.MRF.ForceBotUnlistedPolicy`: Makes all bot posts to disappear from public timelines.
|
||||
* `Pleroma.Web.ActivityPub.MRF.FollowBotPolicy`: Automatically follows newly discovered users from the specified bot account. Local accounts, locked accounts, and users with "#nobot" in their bio are respected and excluded from being followed.
|
||||
* `Pleroma.Web.ActivityPub.MRF.AntiFollowbotPolicy`: Drops follow requests from followbots. Users can still allow bots to follow them by first following the bot.
|
||||
* `Pleroma.Web.ActivityPub.MRF.KeywordPolicy`: Rejects or removes from the federated timeline or replaces keywords. (See [`:mrf_keyword`](#mrf_keyword)).
|
||||
* `transparency`: Make the content of your Message Rewrite Facility settings public (via nodeinfo).
|
||||
* `transparency_exclusions`: Exclude specific instance names from MRF transparency. The use of the exclusions feature will be disclosed in nodeinfo as a boolean value.
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ defp score_displayname("federationbot"), do: 1.0
|
|||
defp score_displayname("fedibot"), do: 1.0
|
||||
defp score_displayname(_), do: 0.0
|
||||
|
||||
defp determine_if_followbot(%User{nickname: nickname, name: displayname}) do
|
||||
defp determine_if_followbot(%User{nickname: nickname, name: displayname, actor_type: actor_type}) do
|
||||
# nickname will be a binary string except when following a relay
|
||||
nick_score =
|
||||
if is_binary(nickname) do
|
||||
|
@ -45,19 +45,32 @@ defp determine_if_followbot(%User{nickname: nickname, name: displayname}) do
|
|||
0.0
|
||||
end
|
||||
|
||||
nick_score + name_score
|
||||
# actor_type "Service" is a Bot account
|
||||
actor_type_score =
|
||||
if actor_type == "Service" do
|
||||
1.0
|
||||
else
|
||||
0.0
|
||||
end
|
||||
|
||||
nick_score + name_score + actor_type_score
|
||||
end
|
||||
|
||||
defp determine_if_followbot(_), do: 0.0
|
||||
|
||||
defp bot_allowed?(%{"object" => target}, bot_actor) do
|
||||
%User{} = user = normalize_by_ap_id(target)
|
||||
|
||||
User.following?(user, bot_actor)
|
||||
end
|
||||
|
||||
@impl true
|
||||
def filter(%{"type" => "Follow", "actor" => actor_id} = message) do
|
||||
%User{} = actor = normalize_by_ap_id(actor_id)
|
||||
|
||||
score = determine_if_followbot(actor)
|
||||
|
||||
# TODO: scan biography data for keywords and score it somehow.
|
||||
if score < 0.8 do
|
||||
if score < 0.8 || bot_allowed?(message, actor) do
|
||||
{:ok, message}
|
||||
else
|
||||
{:reject, "[AntiFollowbotPolicy] Scored #{actor_id} as #{score}"}
|
||||
|
|
|
@ -6,6 +6,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.AntiFollowbotPolicyTest do
|
|||
use Pleroma.DataCase, async: true
|
||||
import Pleroma.Factory
|
||||
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.ActivityPub.MRF.AntiFollowbotPolicy
|
||||
|
||||
describe "blocking based on attributes" do
|
||||
|
@ -38,9 +39,25 @@ test "matches followbots by display name" do
|
|||
|
||||
assert {:reject, "[AntiFollowbotPolicy]" <> _} = AntiFollowbotPolicy.filter(message)
|
||||
end
|
||||
|
||||
test "matches followbots by actor_type" do
|
||||
actor = insert(:user, %{actor_type: "Service"})
|
||||
target = insert(:user)
|
||||
|
||||
message = %{
|
||||
"@context" => "https://www.w3.org/ns/activitystreams",
|
||||
"type" => "Follow",
|
||||
"actor" => actor.ap_id,
|
||||
"object" => target.ap_id,
|
||||
"id" => "https://example.com/activities/1234"
|
||||
}
|
||||
|
||||
assert {:reject, "[AntiFollowbotPolicy]" <> _} = AntiFollowbotPolicy.filter(message)
|
||||
end
|
||||
end
|
||||
|
||||
test "it allows non-followbots" do
|
||||
describe "it allows" do
|
||||
test "non-followbots" do
|
||||
actor = insert(:user)
|
||||
target = insert(:user)
|
||||
|
||||
|
@ -55,6 +72,24 @@ test "it allows non-followbots" do
|
|||
{:ok, _} = AntiFollowbotPolicy.filter(message)
|
||||
end
|
||||
|
||||
test "bots if the target follows the bots" do
|
||||
actor = insert(:user, %{actor_type: "Service"})
|
||||
target = insert(:user)
|
||||
|
||||
User.follow(target, actor)
|
||||
|
||||
message = %{
|
||||
"@context" => "https://www.w3.org/ns/activitystreams",
|
||||
"type" => "Follow",
|
||||
"actor" => actor.ap_id,
|
||||
"object" => target.ap_id,
|
||||
"id" => "https://example.com/activities/1234"
|
||||
}
|
||||
|
||||
{:ok, _} = AntiFollowbotPolicy.filter(message)
|
||||
end
|
||||
end
|
||||
|
||||
test "it gracefully handles nil display names" do
|
||||
actor = insert(:user, %{name: nil})
|
||||
target = insert(:user)
|
||||
|
|
Loading…
Reference in a new issue