Mastodon's "remove follower" does not properly propagate
Environment
- Installation type (OTP or From Source): OTP
- Pleroma version (could be found in the "Version" tab of settings in Pleroma-FE): https://lily.kazv.moe/infra/pleroma/-/commit/d7fe6967
- Elixir version (
elixir -v
for from source installations, N/A for OTP): N/A - Operating system: Docker image on Ubuntu 20.04
- PostgreSQL version (
psql -V
): 13.3
Bug description
Reproducing steps
- I followed
tusooa@t.tusooa.xyz
fromtestuser@lm.kazv.moe
. - On
tusooa@t.tusooa.xyz
, I removed the followertestuser@lm.kazv.moe
. -
GET https://lm.kazv.moe/api/v1/accounts/relationships/?id=ABH0GcHwNlq0ueR0t6
(ABH0GcHwNlq0ueR0t6
is the account id fortusooa@t.tusooa.xyz
).
Expected behaviour
In (2) the following
property should be false.
Actual behaviour
In (2) the following
property is true.
Some analysis
Firstly, UserRelationship.view_relationships_option(user, targets)
yields no relationship between the two.
In Pleroma.Web.MastodonAPI.AccountView.render("relationship.json", ...)
, there is
follow_state =
if following_relationships do
user_to_target_following_relation =
FollowingRelationship.find(following_relationships, reading_user, target)
User.get_follow_state(reading_user, target, user_to_target_following_relation)
else
User.get_follow_state(reading_user, target)
end
I checked it, following_relationships
is []
; user_to_target_following_relation
gives nil
; and User.get_follow_state(reading_user, target, user_to_target_following_relation)
is to be executed, as []
is true.
Now
def get_follow_state(
%User{} = follower,
%User{} = following,
following_relationship
) do
case {following_relationship, following.local} do
{nil, false} ->
case Utils.fetch_latest_follow(follower, following) do
%Activity{data: %{"state" => state}} when state in ["pending", "accept"] ->
FollowingRelationship.state_to_enum(state)
_ ->
nil
end
{%{state: state}, _} ->
state
{nil, _} ->
nil
end
end
As here following_relationship
is nil
, and following
is a remote user, {nil, false}
branch will be executed. Utils.fetch_latest_follow(follower, following)
does give us the follow activity, whose state is indeed accept
. Thus we have the problem described above.
Tracing
/opt/pleroma/bin/pleroma remote
:
> testuser = Pleroma.User.get_by_nickname("testuser")
> tusooa = Pleroma.User.get_by_nickname("tusooa@t.tusooa.xyz")
iex(pleroma@127.0.0.1)3> Pleroma.Web.MastodonAPI.AccountView.render("relationships.json", user: testuser, targets: [tusooa])
16:16:07.418 [debug] QUERY OK source="user_relationships" db=2.9ms queue=0.1ms idle=545.4ms
SELECT u0."relationship_type", u0."source_id", u0."target_id" FROM "user_relationships" AS u0 WHERE ((source_id = ANY($1) AND target_id = ANY($2) AND relationship_type = ANY($3)) OR (source_id = ANY($4) AND target_id = ANY($5) AND relationship_type = ANY($6))) [[<<0, 0, 1, 123, 184, 19, 217, 197, 204, 50, 165, 136, 249, 221, 0, 0>>], [<<0, 0, 1, 123, 216, 31, 91, 244, 191, 161, 230, 249, 45, 181, 0, 0>>], [1, 2, 4, 3], [<<0, 0, 1, 123, 216, 31, 91, 244, 191, 161, 230, 249, 45, 181, 0, 0>>], [<<0, 0, 1, 123, 184, 19, 217, 197, 204, 50, 165, 136, 249, 221, 0, 0>>], [1, 5]]
16:16:07.422 [debug] QUERY OK source="following_relationships" db=1.8ms idle=524.0ms
SELECT f0."id", f0."state", f0."follower_id", f0."following_id", f0."inserted_at", f0."updated_at" FROM "following_relationships" AS f0 WHERE ((follower_id = ANY($1) AND following_id = ANY($2)) OR (follower_id = ANY($3) AND following_id = ANY($4))) [[<<0, 0, 1, 123, 184, 19, 217, 197, 204, 50, 165, 136, 249, 221, 0, 0>>], [<<0, 0, 1, 123, 216, 31, 91, 244, 191, 161, 230, 249, 45, 181, 0, 0>>], [<<0, 0, 1, 123, 216, 31, 91, 244, 191, 161, 230, 249, 45, 181, 0, 0>>], [<<0, 0, 1, 123, 184, 19, 217, 197, 204, 50, 165, 136, 249, 221, 0, 0>>]]
16:16:07.426 [debug] QUERY OK source="activities" db=2.7ms queue=0.1ms idle=438.2ms
SELECT a0."id", a0."data", a0."local", a0."actor", a0."recipients", a0."inserted_at", a0."updated_at" FROM "activities" AS a0 WHERE ((a0."data")->>'type' = $1) AND (a0."actor" = $2) AND (coalesce((a0."data")->'object'->>'id', (a0."data")->>'object') = $3) ORDER BY a0."id" desc nulls last LIMIT 1 ["Follow", "https://lm.kazv.moe/users/testuser", "https://t.tusooa.xyz/users/tusooa"]
[
%{
blocked_by: false,
blocking: false,
domain_blocking: false,
endorsed: false,
followed_by: false,
following: true,
id: "ABH0GcHwNlq0ueR0t6",
muting: false,
muting_notifications: false,
requested: false,
showing_reblogs: true,
subscribing: false
}
]
iex(pleroma@127.0.0.1)4> Pleroma.UserRelationship.view_relationships_option(testuser, [tusooa])
16:17:09.604 [debug] QUERY OK source="user_relationships" db=2.6ms queue=0.1ms idle=642.0ms
SELECT u0."relationship_type", u0."source_id", u0."target_id" FROM "user_relationships" AS u0 WHERE ((source_id = ANY($1) AND target_id = ANY($2) AND relationship_type = ANY($3)) OR (source_id = ANY($4) AND target_id = ANY($5) AND relationship_type = ANY($6))) [[<<0, 0, 1, 123, 184, 19, 217, 197, 204, 50, 165, 136, 249, 221, 0, 0>>], [<<0, 0, 1, 123, 216, 31, 91, 244, 191, 161, 230, 249, 45, 181, 0, 0>>], [1, 2, 4, 3], [<<0, 0, 1, 123, 216, 31, 91, 244, 191, 161, 230, 249, 45, 181, 0, 0>>], [<<0, 0, 1, 123, 184, 19, 217, 197, 204, 50, 165, 136, 249, 221, 0, 0>>], [1, 5]]
16:17:09.607 [debug] QUERY OK source="following_relationships" db=2.2ms idle=546.3ms
SELECT f0."id", f0."state", f0."follower_id", f0."following_id", f0."inserted_at", f0."updated_at" FROM "following_relationships" AS f0 WHERE ((follower_id = ANY($1) AND following_id = ANY($2)) OR (follower_id = ANY($3) AND following_id = ANY($4))) [[<<0, 0, 1, 123, 184, 19, 217, 197, 204, 50, 165, 136, 249, 221, 0, 0>>], [<<0, 0, 1, 123, 216, 31, 91, 244, 191, 161, 230, 249, 45, 181, 0, 0>>], [<<0, 0, 1, 123, 216, 31, 91, 244, 191, 161, 230, 249, 45, 181, 0, 0>>], [<<0, 0, 1, 123, 184, 19, 217, 197, 204, 50, 165, 136, 249, 221, 0, 0>>]]
%{following_relationships: [], user_relationships: []}