mirror of
https://code.eliotberriot.com/funkwhale/funkwhale.git
synced 2025-10-04 17:19:16 +02:00
See #852: improved routing logic for federation messages (support multiple objects types for one route)
This commit is contained in:
parent
1aa3f3f340
commit
9f3182caf7
19 changed files with 561 additions and 54 deletions
58
api/funkwhale_api/users/tasks.py
Normal file
58
api/funkwhale_api/users/tasks.py
Normal file
|
@ -0,0 +1,58 @@
|
|||
import logging
|
||||
|
||||
from django.db.models.deletion import Collector
|
||||
|
||||
from funkwhale_api.federation import routes
|
||||
from funkwhale_api.taskapp import celery
|
||||
|
||||
from . import models
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@celery.app.task(name="users.delete_account")
|
||||
@celery.require_instance(models.User.objects.select_related("actor"), "user")
|
||||
def delete_account(user):
|
||||
logger.info("Starting deletion of account %s…", user.username)
|
||||
actor = user.actor
|
||||
# we start by deleting the user obj, which will cascade deletion
|
||||
# to any other object
|
||||
user.delete()
|
||||
logger.info("Deleted user object")
|
||||
|
||||
# Then we broadcast the info over federation. We do this *before* deleting objects
|
||||
# associated with the actor, otherwise follows are removed and we don't know where
|
||||
# to broadcast
|
||||
logger.info("Broadcasting deletion to federation…")
|
||||
routes.outbox.dispatch(
|
||||
{"type": "Delete", "object": {"type": actor.type}}, context={"actor": actor}
|
||||
)
|
||||
|
||||
# then we delete any object associated with the actor object, but *not* the actor
|
||||
# itself. We keep it for auditability and sending the Delete ActivityPub message
|
||||
collector = Collector(using="default")
|
||||
logger.info(
|
||||
"Prepare deletion of objects associated with account %s…", user.username
|
||||
)
|
||||
collector.collect([actor])
|
||||
|
||||
for model, instances in collector.data.items():
|
||||
if issubclass(model, actor.__class__):
|
||||
# we skip deletion of the actor itself
|
||||
continue
|
||||
|
||||
logger.info(
|
||||
"Deleting %s objects associated with account %s…",
|
||||
len(instances),
|
||||
user.username,
|
||||
)
|
||||
to_delete = model.objects.filter(pk__in=[instance.pk for instance in instances])
|
||||
to_delete.delete()
|
||||
|
||||
# Finally, we update the actor itself and mark it as removed
|
||||
logger.info("Marking actor as Tombsone…")
|
||||
actor.type = "Tombstone"
|
||||
actor.name = None
|
||||
actor.summary = None
|
||||
actor.save(update_fields=["type", "name", "summary"])
|
||||
logger.info("Deletion of account done %s!", user.username)
|
Loading…
Add table
Add a link
Reference in a new issue