Merge branch 'bugfix/block-follow-relationships' into 'develop'

fix follow relationship leaks when blocked

See merge request pleroma/pleroma!230
This commit is contained in:
lambda 2018-06-19 09:42:45 +00:00
commit be800d7936
4 changed files with 110 additions and 6 deletions

View file

@ -505,15 +505,33 @@ def search(query, resolve) do
Repo.all(q) Repo.all(q)
end end
def block(user, %{ap_id: ap_id}) do def block(blocker, %User{ap_id: ap_id} = blocked) do
blocks = user.info["blocks"] || [] # sever any follow relationships to prevent leaks per activitypub (Pleroma issue #213)
new_blocks = Enum.uniq([ap_id | blocks]) blocker =
new_info = Map.put(user.info, "blocks", new_blocks) if following?(blocker, blocked) do
{:ok, blocker, _} = unfollow(blocker, blocked)
blocker
else
blocker
end
cs = User.info_changeset(user, %{info: new_info}) if following?(blocked, blocker) do
unfollow(blocked, blocker)
end
blocks = blocker.info["blocks"] || []
new_blocks = Enum.uniq([ap_id | blocks])
new_info = Map.put(blocker.info, "blocks", new_blocks)
cs = User.info_changeset(blocker, %{info: new_info})
update_and_set_cache(cs) update_and_set_cache(cs)
end end
# helper to handle the block given only an actor's AP id
def block(blocker, %{ap_id: ap_id}) do
block(blocker, User.get_by_ap_id(ap_id))
end
def unblock(user, %{ap_id: ap_id}) do def unblock(user, %{ap_id: ap_id}) do
blocks = user.info["blocks"] || [] blocks = user.info["blocks"] || []
new_blocks = List.delete(blocks, ap_id) new_blocks = List.delete(blocks, ap_id)

View file

@ -359,6 +359,61 @@ test "it unblocks users" do
refute User.blocks?(user, blocked_user) refute User.blocks?(user, blocked_user)
end end
test "blocks tear down cyclical follow relationships" do
blocker = insert(:user)
blocked = insert(:user)
{:ok, blocker} = User.follow(blocker, blocked)
{:ok, blocked} = User.follow(blocked, blocker)
assert User.following?(blocker, blocked)
assert User.following?(blocked, blocker)
{:ok, blocker} = User.block(blocker, blocked)
blocked = Repo.get(User, blocked.id)
assert User.blocks?(blocker, blocked)
refute User.following?(blocker, blocked)
refute User.following?(blocked, blocker)
end
test "blocks tear down blocker->blocked follow relationships" do
blocker = insert(:user)
blocked = insert(:user)
{:ok, blocker} = User.follow(blocker, blocked)
assert User.following?(blocker, blocked)
refute User.following?(blocked, blocker)
{:ok, blocker} = User.block(blocker, blocked)
blocked = Repo.get(User, blocked.id)
assert User.blocks?(blocker, blocked)
refute User.following?(blocker, blocked)
refute User.following?(blocked, blocker)
end
test "blocks tear down blocked->blocker follow relationships" do
blocker = insert(:user)
blocked = insert(:user)
{:ok, blocked} = User.follow(blocked, blocker)
refute User.following?(blocker, blocked)
assert User.following?(blocked, blocker)
{:ok, blocker} = User.block(blocker, blocked)
blocked = Repo.get(User, blocked.id)
assert User.blocks?(blocker, blocked)
refute User.following?(blocker, blocked)
refute User.following?(blocked, blocker)
end
end end
describe "domain blocking" do describe "domain blocking" do

View file

@ -392,6 +392,37 @@ test "it works for incoming blocks" do
assert User.blocks?(blocker, user) assert User.blocks?(blocker, user)
end end
test "incoming blocks successfully tear down any follow relationship" do
blocker = insert(:user)
blocked = insert(:user)
data =
File.read!("test/fixtures/mastodon-block-activity.json")
|> Poison.decode!()
|> Map.put("object", blocked.ap_id)
|> Map.put("actor", blocker.ap_id)
{:ok, blocker} = User.follow(blocker, blocked)
{:ok, blocked} = User.follow(blocked, blocker)
assert User.following?(blocker, blocked)
assert User.following?(blocked, blocker)
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
assert data["type"] == "Block"
assert data["object"] == blocked.ap_id
assert data["actor"] == blocker.ap_id
blocker = User.get_by_ap_id(data["actor"])
blocked = User.get_by_ap_id(data["object"])
assert User.blocks?(blocker, blocked)
refute User.following?(blocker, blocked)
refute User.following?(blocked, blocker)
end
test "it works for incoming unblocks with an existing block" do test "it works for incoming unblocks with an existing block" do
user = insert(:user) user = insert(:user)

View file

@ -60,7 +60,7 @@ test "represent a relationship" do
expected = %{ expected = %{
id: to_string(other_user.id), id: to_string(other_user.id),
following: true, following: false,
followed_by: false, followed_by: false,
blocking: true, blocking: true,
muting: false, muting: false,