2019-06-05 04:06:45 -06:00
|
|
|
# Pleroma: A lightweight social networking server
|
2021-01-12 23:49:20 -07:00
|
|
|
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
2019-06-05 04:06:45 -06:00
|
|
|
# SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
|
|
|
defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do
|
2023-08-01 04:43:50 -06:00
|
|
|
use Pleroma.DataCase, async: false
|
2019-06-05 04:06:45 -06:00
|
|
|
alias Pleroma.Activity
|
2020-06-04 11:22:49 -06:00
|
|
|
alias Pleroma.Notification
|
2019-06-05 04:06:45 -06:00
|
|
|
alias Pleroma.Repo
|
|
|
|
alias Pleroma.User
|
|
|
|
alias Pleroma.Web.ActivityPub.Transmogrifier
|
|
|
|
alias Pleroma.Web.ActivityPub.Utils
|
|
|
|
|
|
|
|
import Pleroma.Factory
|
|
|
|
import Ecto.Query
|
2020-06-05 04:26:07 -06:00
|
|
|
import Mock
|
2019-06-05 04:06:45 -06:00
|
|
|
|
|
|
|
setup_all do
|
|
|
|
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
|
|
|
:ok
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "handle_incoming" do
|
2020-03-20 09:33:00 -06:00
|
|
|
setup do: clear_config([:user, :deny_follow_blocked])
|
2020-02-13 11:55:47 -07:00
|
|
|
|
2019-08-26 13:34:52 -06:00
|
|
|
test "it works for osada follow request" do
|
|
|
|
user = insert(:user)
|
|
|
|
|
|
|
|
data =
|
|
|
|
File.read!("test/fixtures/osada-follow-activity.json")
|
2020-11-23 12:28:55 -07:00
|
|
|
|> Jason.decode!()
|
2019-08-26 13:34:52 -06:00
|
|
|
|> Map.put("object", user.ap_id)
|
|
|
|
|
|
|
|
{:ok, %Activity{data: data, local: false} = activity} = Transmogrifier.handle_incoming(data)
|
|
|
|
|
|
|
|
assert data["actor"] == "https://apfed.club/channel/indio"
|
|
|
|
assert data["type"] == "Follow"
|
|
|
|
assert data["id"] == "https://apfed.club/follow/9"
|
|
|
|
|
|
|
|
activity = Repo.get(Activity, activity.id)
|
|
|
|
assert activity.data["state"] == "accept"
|
|
|
|
assert User.following?(User.get_cached_by_ap_id(data["actor"]), user)
|
|
|
|
end
|
|
|
|
|
2019-06-05 04:06:45 -06:00
|
|
|
test "it works for incoming follow requests" do
|
|
|
|
user = insert(:user)
|
|
|
|
|
|
|
|
data =
|
|
|
|
File.read!("test/fixtures/mastodon-follow-activity.json")
|
2020-11-23 12:28:55 -07:00
|
|
|
|> Jason.decode!()
|
2019-06-05 04:06:45 -06:00
|
|
|
|> Map.put("object", user.ap_id)
|
|
|
|
|
2019-06-05 06:10:46 -06:00
|
|
|
{:ok, %Activity{data: data, local: false} = activity} = Transmogrifier.handle_incoming(data)
|
2019-06-05 04:06:45 -06:00
|
|
|
|
|
|
|
assert data["actor"] == "http://mastodon.example.org/users/admin"
|
|
|
|
assert data["type"] == "Follow"
|
|
|
|
assert data["id"] == "http://mastodon.example.org/users/admin#follows/2"
|
2019-06-05 06:10:46 -06:00
|
|
|
|
|
|
|
activity = Repo.get(Activity, activity.id)
|
|
|
|
assert activity.data["state"] == "accept"
|
2019-06-05 04:06:45 -06:00
|
|
|
assert User.following?(User.get_cached_by_ap_id(data["actor"]), user)
|
2020-06-04 11:22:49 -06:00
|
|
|
|
|
|
|
[notification] = Notification.for_user(user)
|
|
|
|
assert notification.type == "follow"
|
2019-06-05 04:06:45 -06:00
|
|
|
end
|
|
|
|
|
2020-06-04 11:22:49 -06:00
|
|
|
test "with locked accounts, it does create a Follow, but not an Accept" do
|
2020-10-13 08:31:13 -06:00
|
|
|
user = insert(:user, is_locked: true)
|
2019-06-05 06:10:46 -06:00
|
|
|
|
|
|
|
data =
|
|
|
|
File.read!("test/fixtures/mastodon-follow-activity.json")
|
2020-11-23 12:28:55 -07:00
|
|
|
|> Jason.decode!()
|
2019-06-05 06:10:46 -06:00
|
|
|
|> Map.put("object", user.ap_id)
|
|
|
|
|
|
|
|
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
|
|
|
|
|
|
|
|
assert data["state"] == "pending"
|
|
|
|
|
|
|
|
refute User.following?(User.get_cached_by_ap_id(data["actor"]), user)
|
|
|
|
|
|
|
|
accepts =
|
|
|
|
from(
|
|
|
|
a in Activity,
|
|
|
|
where: fragment("?->>'type' = ?", a.data, "Accept")
|
|
|
|
)
|
|
|
|
|> Repo.all()
|
|
|
|
|
2020-01-20 03:53:14 -07:00
|
|
|
assert Enum.empty?(accepts)
|
2020-06-04 11:22:49 -06:00
|
|
|
|
|
|
|
[notification] = Notification.for_user(user)
|
|
|
|
assert notification.type == "follow_request"
|
2019-06-05 06:10:46 -06:00
|
|
|
end
|
|
|
|
|
2019-06-05 04:06:45 -06:00
|
|
|
test "it works for follow requests when you are already followed, creating a new accept activity" do
|
2019-06-05 04:45:28 -06:00
|
|
|
# This is important because the remote might have the wrong idea about the
|
|
|
|
# current follow status. This can lead to instance A thinking that x@A is
|
|
|
|
# followed by y@B, but B thinks they are not. In this case, the follow can
|
|
|
|
# never go through again because it will never get an Accept.
|
2019-06-05 04:06:45 -06:00
|
|
|
user = insert(:user)
|
|
|
|
|
|
|
|
data =
|
|
|
|
File.read!("test/fixtures/mastodon-follow-activity.json")
|
2020-11-23 12:28:55 -07:00
|
|
|
|> Jason.decode!()
|
2019-06-05 04:06:45 -06:00
|
|
|
|> Map.put("object", user.ap_id)
|
|
|
|
|
|
|
|
{:ok, %Activity{local: false}} = Transmogrifier.handle_incoming(data)
|
|
|
|
|
|
|
|
accepts =
|
|
|
|
from(
|
|
|
|
a in Activity,
|
|
|
|
where: fragment("?->>'type' = ?", a.data, "Accept")
|
|
|
|
)
|
|
|
|
|> Repo.all()
|
|
|
|
|
|
|
|
assert length(accepts) == 1
|
|
|
|
|
|
|
|
data =
|
|
|
|
File.read!("test/fixtures/mastodon-follow-activity.json")
|
2020-11-23 12:28:55 -07:00
|
|
|
|> Jason.decode!()
|
2019-06-05 04:06:45 -06:00
|
|
|
|> Map.put("id", String.replace(data["id"], "2", "3"))
|
|
|
|
|> Map.put("object", user.ap_id)
|
|
|
|
|
|
|
|
{:ok, %Activity{local: false}} = Transmogrifier.handle_incoming(data)
|
|
|
|
|
|
|
|
accepts =
|
|
|
|
from(
|
|
|
|
a in Activity,
|
|
|
|
where: fragment("?->>'type' = ?", a.data, "Accept")
|
|
|
|
)
|
|
|
|
|> Repo.all()
|
|
|
|
|
|
|
|
assert length(accepts) == 2
|
|
|
|
end
|
|
|
|
|
|
|
|
test "it rejects incoming follow requests from blocked users when deny_follow_blocked is enabled" do
|
2021-01-26 10:58:43 -07:00
|
|
|
clear_config([:user, :deny_follow_blocked], true)
|
2019-06-05 04:06:45 -06:00
|
|
|
|
|
|
|
user = insert(:user)
|
|
|
|
{:ok, target} = User.get_or_fetch("http://mastodon.example.org/users/admin")
|
|
|
|
|
2019-11-19 13:22:10 -07:00
|
|
|
{:ok, _user_relationship} = User.block(user, target)
|
2019-06-05 04:06:45 -06:00
|
|
|
|
|
|
|
data =
|
|
|
|
File.read!("test/fixtures/mastodon-follow-activity.json")
|
2020-11-23 12:28:55 -07:00
|
|
|
|> Jason.decode!()
|
2019-06-05 04:06:45 -06:00
|
|
|
|> Map.put("object", user.ap_id)
|
|
|
|
|
|
|
|
{:ok, %Activity{data: %{"id" => id}}} = Transmogrifier.handle_incoming(data)
|
|
|
|
|
|
|
|
%Activity{} = activity = Activity.get_by_ap_id(id)
|
|
|
|
|
|
|
|
assert activity.data["state"] == "reject"
|
|
|
|
end
|
|
|
|
|
2020-06-05 04:26:07 -06:00
|
|
|
test "it rejects incoming follow requests if the following errors for some reason" do
|
|
|
|
user = insert(:user)
|
|
|
|
|
|
|
|
data =
|
|
|
|
File.read!("test/fixtures/mastodon-follow-activity.json")
|
2020-11-23 12:28:55 -07:00
|
|
|
|> Jason.decode!()
|
2020-06-05 04:26:07 -06:00
|
|
|
|> Map.put("object", user.ap_id)
|
|
|
|
|
2020-07-08 06:30:53 -06:00
|
|
|
with_mock Pleroma.User, [:passthrough], follow: fn _, _, _ -> {:error, :testing} end do
|
2020-06-05 04:26:07 -06:00
|
|
|
{:ok, %Activity{data: %{"id" => id}}} = Transmogrifier.handle_incoming(data)
|
|
|
|
|
|
|
|
%Activity{} = activity = Activity.get_by_ap_id(id)
|
|
|
|
|
|
|
|
assert activity.data["state"] == "reject"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-06-05 04:06:45 -06:00
|
|
|
test "it works for incoming follow requests from hubzilla" do
|
|
|
|
user = insert(:user)
|
|
|
|
|
|
|
|
data =
|
|
|
|
File.read!("test/fixtures/hubzilla-follow-activity.json")
|
2020-11-23 12:28:55 -07:00
|
|
|
|> Jason.decode!()
|
2019-06-05 04:06:45 -06:00
|
|
|
|> Map.put("object", user.ap_id)
|
|
|
|
|> Utils.normalize_params()
|
|
|
|
|
|
|
|
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
|
|
|
|
|
|
|
|
assert data["actor"] == "https://hubzilla.example.org/channel/kaniini"
|
|
|
|
assert data["type"] == "Follow"
|
|
|
|
assert data["id"] == "https://hubzilla.example.org/channel/kaniini#follows/2"
|
|
|
|
assert User.following?(User.get_cached_by_ap_id(data["actor"]), user)
|
|
|
|
end
|
2020-08-12 05:39:54 -06:00
|
|
|
|
|
|
|
test "it works for incoming follows to locked account" do
|
|
|
|
pending_follower = insert(:user, ap_id: "http://mastodon.example.org/users/admin")
|
2020-10-13 08:31:13 -06:00
|
|
|
user = insert(:user, is_locked: true)
|
2020-08-12 05:39:54 -06:00
|
|
|
|
|
|
|
data =
|
|
|
|
File.read!("test/fixtures/mastodon-follow-activity.json")
|
2020-11-23 12:28:55 -07:00
|
|
|
|> Jason.decode!()
|
2020-08-12 05:39:54 -06:00
|
|
|
|> Map.put("object", user.ap_id)
|
|
|
|
|
|
|
|
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
|
|
|
|
|
|
|
|
assert data["type"] == "Follow"
|
|
|
|
assert data["object"] == user.ap_id
|
|
|
|
assert data["state"] == "pending"
|
|
|
|
assert data["actor"] == "http://mastodon.example.org/users/admin"
|
|
|
|
|
|
|
|
assert [^pending_follower] = User.get_follow_requests(user)
|
|
|
|
end
|
2019-06-05 04:06:45 -06:00
|
|
|
end
|
|
|
|
end
|