extend reject MRF to check if originating instance is blocked
[akkoma] / lib / pleroma / web / activity_pub / mrf / follow_bot_policy.ex
1 defmodule Pleroma.Web.ActivityPub.MRF.FollowBotPolicy do
2 @behaviour Pleroma.Web.ActivityPub.MRF.Policy
3 alias Pleroma.Config
4 alias Pleroma.User
5 alias Pleroma.Web.CommonAPI
6
7 require Logger
8
9 @impl true
10 def filter(message) do
11 with follower_nickname <- Config.get([:mrf_follow_bot, :follower_nickname]),
12 %User{actor_type: "Service"} = follower <-
13 User.get_cached_by_nickname(follower_nickname),
14 %{"type" => "Create", "object" => %{"type" => "Note"}} <- message do
15 try_follow(follower, message)
16 else
17 nil ->
18 Logger.warn(
19 "#{__MODULE__} skipped because of missing `:mrf_follow_bot, :follower_nickname` configuration, the :follower_nickname
20 account does not exist, or the account is not correctly configured as a bot."
21 )
22
23 {:ok, message}
24
25 _ ->
26 {:ok, message}
27 end
28 end
29
30 defp try_follow(follower, message) do
31 to = Map.get(message, "to", [])
32 cc = Map.get(message, "cc", [])
33 actor = [message["actor"]]
34
35 Enum.concat([to, cc, actor])
36 |> List.flatten()
37 |> Enum.uniq()
38 |> User.get_all_by_ap_id()
39 |> Enum.each(fn user ->
40 with false <- user.local,
41 false <- User.following?(follower, user),
42 false <- User.locked?(user),
43 false <- (user.bio || "") |> String.downcase() |> String.contains?("nobot") do
44 Logger.debug(
45 "#{__MODULE__}: Follow request from #{follower.nickname} to #{user.nickname}"
46 )
47
48 CommonAPI.follow(follower, user)
49 end
50 end)
51
52 {:ok, message}
53 end
54
55 @impl true
56 def describe do
57 {:ok, %{}}
58 end
59 end