diff options
-rw-r--r-- | config/config.exs | 2 | ||||
-rw-r--r-- | lib/pleroma/user.ex | 35 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/transmogrifier.ex | 9 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/utils.ex | 18 | ||||
-rw-r--r-- | test/user_test.exs | 9 |
5 files changed, 52 insertions, 21 deletions
diff --git a/config/config.exs b/config/config.exs index d3f9cf6e4..826dd07b7 100644 --- a/config/config.exs +++ b/config/config.exs @@ -56,6 +56,8 @@ config :pleroma, :instance, rewrite_policy: Pleroma.Web.ActivityPub.MRF.NoOpPolicy, public: true +config :pleroma, :activitypub, accept_blocks: true + config :pleroma, :mrf_simple, media_removal: [], media_nsfw: [], diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index e4fb57308..75e173d0c 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -200,25 +200,30 @@ defmodule Pleroma.User do def follow(%User{} = follower, %User{info: info} = followed) do ap_followers = followed.follower_address - if following?(follower, followed) or info["deactivated"] do - {:error, "Could not follow user: #{followed.nickname} is already on your list."} - else - if !followed.local && follower.local && !ap_enabled?(followed) do - Websub.subscribe(follower, followed) - end + cond do + following?(follower, followed) or info["deactivated"] -> + {:error, "Could not follow user: #{followed.nickname} is already on your list."} - following = - [ap_followers | follower.following] - |> Enum.uniq() + blocks?(followed, follower) -> + {:error, "Could not follow user: #{followed.nickname} blocked you."} - follower = - follower - |> follow_changeset(%{following: following}) - |> update_and_set_cache + true -> + if !followed.local && follower.local && !ap_enabled?(followed) do + Websub.subscribe(follower, followed) + end - {:ok, _} = update_follower_count(followed) + following = + [ap_followers | follower.following] + |> Enum.uniq() - follower + follower = + follower + |> follow_changeset(%{following: following}) + |> update_and_set_cache + + {:ok, _} = update_follower_count(followed) + + follower end end diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 62667daa2..3c9377be9 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -328,6 +328,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do end end + @ap_config Application.get_env(:pleroma, :activitypub) + @accept_blocks Keyword.get(@ap_config, :accept_blocks) + def handle_incoming( %{ "type" => "Undo", @@ -336,7 +339,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do "id" => id } = _data ) do - with %User{local: true} = blocked <- User.get_cached_by_ap_id(blocked), + with true <- @accept_blocks, + %User{local: true} = blocked <- User.get_cached_by_ap_id(blocked), %User{} = blocker <- User.get_or_fetch_by_ap_id(blocker), {:ok, activity} <- ActivityPub.unblock(blocker, blocked, id, false) do User.unblock(blocker, blocked) @@ -349,7 +353,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do def handle_incoming( %{"type" => "Block", "object" => blocked, "actor" => blocker, "id" => id} = data ) do - with %User{local: true} = blocked = User.get_cached_by_ap_id(blocked), + with true <- @accept_blocks, + %User{local: true} = blocked = User.get_cached_by_ap_id(blocked), %User{} = blocker = User.get_or_fetch_by_ap_id(blocker), {:ok, activity} <- ActivityPub.block(blocker, blocked, id, false) do User.unfollow(blocker, blocked) diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 7362a3ccf..56b80a8db 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -237,11 +237,16 @@ defmodule Pleroma.Web.ActivityPub.Utils do activity in Activity, where: fragment( + "? ->> 'type' = 'Follow'", + activity.data + ), + where: activity.actor == ^follower_id, + where: + fragment( "? @> ?", activity.data, - ^%{type: "Follow", object: followed_id} + ^%{object: followed_id} ), - where: activity.actor == ^follower_id, order_by: [desc: :id], limit: 1 ) @@ -362,11 +367,16 @@ defmodule Pleroma.Web.ActivityPub.Utils do activity in Activity, where: fragment( + "? ->> 'type' = 'Block'", + activity.data + ), + where: activity.actor == ^blocker_id, + where: + fragment( "? @> ?", activity.data, - ^%{type: "Block", object: blocked_id} + ^%{object: blocked_id} ), - where: activity.actor == ^blocker_id, order_by: [desc: :id], limit: 1 ) diff --git a/test/user_test.exs b/test/user_test.exs index 9506b58fa..8c8cfd673 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -46,6 +46,15 @@ defmodule Pleroma.UserTest do {:error, _} = User.follow(user, followed) end + test "can't follow a user who blocked us" do + blocker = insert(:user) + blockee = insert(:user) + + {:ok, blocker} = User.block(blocker, blockee) + + {:error, _} = User.follow(blockee, blocker) + end + # This is a somewhat useless test. # test "following a remote user will ensure a websub subscription is present" do # user = insert(:user) |