Handle rejected follows

This commit is contained in:
Andrew Godwin 2022-12-21 16:11:58 +00:00
parent a7082decc8
commit 480fa70b1f
3 changed files with 27 additions and 5 deletions

View file

@ -16,11 +16,13 @@ class FollowStates(StateGraph):
undone = State(try_interval=60 * 60)
undone_remotely = State()
failed = State()
rejected = State()
unrequested.transitions_to(local_requested)
unrequested.transitions_to(remote_requested)
unrequested.times_out_to(failed, seconds=86400 * 7)
local_requested.transitions_to(accepted)
local_requested.transitions_to(rejected)
remote_requested.transitions_to(accepted)
accepted.transitions_to(undone)
undone.transitions_to(undone_remotely)
@ -279,3 +281,19 @@ class Follow(StatorModel):
raise ValueError("No Follow locally for incoming Undo", data)
# Delete the follow
follow.delete()
@classmethod
def handle_reject_ap(cls, data):
"""
Handles an incoming Follow Reject for one of our follows
"""
# Ensure the Accept actor is the Follow's object
if data["actor"] != data["object"]["object"]:
raise ValueError("Accept actor does not match its Follow object", data)
# Resolve source and target and see if a Follow exists (it really should)
try:
follow = cls.by_ap(data["object"])
except KeyError:
raise ValueError("No Follow locally for incoming Reject", data)
# Mark the follow rejected
follow.transition_perform(FollowStates.rejected)

View file

@ -69,6 +69,14 @@ class InboxMessageStates(StateGraph):
raise ValueError(
f"Cannot handle activity of type accept.{unknown}"
)
case "reject":
match instance.message_object_type:
case "follow":
await sync_to_async(Follow.handle_reject_ap)(instance.message)
case unknown:
raise ValueError(
f"Cannot handle activity of type reject.{unknown}"
)
case "undo":
match instance.message_object_type:
case "follow":

View file

@ -19,11 +19,7 @@ class IdentityService:
existing_follow = Follow.maybe_get(from_identity, self.identity)
if not existing_follow:
Follow.create_local(from_identity, self.identity)
elif existing_follow.state in [
FollowStates.undone,
FollowStates.undone_remotely,
FollowStates.failed,
]:
elif existing_follow.state not in FollowStates.group_active():
existing_follow.transition_perform(FollowStates.unrequested)
return cast(Follow, existing_follow)