in src/olympia/users/models.py [0:0]
def ban_and_disable_related_content(self, *, skip_activity_log=False):
"""Admin method to ban multiple users and disable the content they
produced.
Similar to deletion, except that the content produced by the user is
forcibly soft-disabled instead of being deleted where possible, and the
user is not anonymized: we keep their data until hard-deletion kicks in
(see clear_old_user_data), including fxa_id and email so that they are
never able to log back in.
"""
from olympia.addons.models import Addon, AddonUser
from olympia.addons.tasks import index_addons
from olympia.bandwagon.models import Collection
from olympia.ratings.models import Rating
from olympia.users.tasks import delete_photo
users = self.all()
BannedUserContent.objects.bulk_create(
[BannedUserContent(user=user) for user in users], ignore_conflicts=True
)
# Collect affected addons
addon_ids = set(
Addon.unfiltered.exclude(
status__in=(amo.STATUS_DELETED, amo.STATUS_DISABLED)
)
.filter(addonuser__user__in=users)
.values_list('id', flat=True)
)
# First addons who have other authors we aren't banning - we are
# keeping the add-ons up, but soft-deleting the relationships.
addon_joint_ids = set(
AddonUser.objects.filter(addon_id__in=addon_ids)
.exclude(user__in=users)
.values_list('addon_id', flat=True)
)
joint_addonusers_qs = AddonUser.objects.filter(
user__in=users, addon_id__in=addon_joint_ids
)
# Keep track of the AddonUser we are (soft-)deleting.
BannedAddonsUsersModel = BannedUserContent.addons_users.through
BannedAddonsUsersModel.objects.bulk_create(
[
BannedAddonsUsersModel(
bannedusercontent_id=val['user'], addonuser_id=val['pk']
)
for val in joint_addonusers_qs.values('user', 'pk')
]
)
# (Soft-)delete them.
joint_addonusers_qs.delete()
# Then deal with users who are the sole author - we are disabling them.
addons_sole = Addon.unfiltered.filter(id__in=addon_ids - addon_joint_ids)
# set the status to disabled - using the manager update() method
addons_sole.update(status=amo.STATUS_DISABLED)
# disable Files in bulk that need to be disabled now the addons are disabled
Addon.disable_all_files(addons_sole, File.STATUS_DISABLED_REASONS.ADDON_DISABLE)
# Keep track of the Addons and the relevant user.
sole_addonusers_qs = AddonUser.objects.filter(
user__in=users, addon__in=addons_sole
)
BannedAddonsModel = BannedUserContent.addons.through
BannedAddonsModel.objects.bulk_create(
[
BannedAddonsModel(
bannedusercontent_id=val['user'], addon_id=val['addon']
)
for val in sole_addonusers_qs.values('user', 'addon')
]
)
# Finally run Addon.force_disable to add the logging; update versions.
addons_sole_ids = []
for addon in addons_sole:
addons_sole_ids.append(addon.pk)
addon.force_disable()
index_addons.delay(addons_sole_ids)
# Soft-delete the other content associated with the user: Ratings and
# Collections.
# Keep track of the Collections
collections_qs = Collection.objects.filter(author__in=users)
BannedCollectionsModel = BannedUserContent.collections.through
BannedCollectionsModel.objects.bulk_create(
[
BannedCollectionsModel(
bannedusercontent_id=val['author'], collection_id=val['pk']
)
for val in collections_qs.values('author', 'pk')
]
)
# Soft-delete them (keeping their slug - will be restored if unbanned).
collections_qs.delete()
# Keep track of the Ratings
ratings_qs = Rating.objects.filter(user__in=users)
BannedRatingsModel = BannedUserContent.ratings.through
BannedRatingsModel.objects.bulk_create(
[
BannedRatingsModel(
bannedusercontent_id=val['user'], rating_id=val['pk']
)
for val in ratings_qs.values('user', 'pk')
]
)
# Soft-delete them
ratings_qs.delete()
# And then ban the users.
for user in users:
if not skip_activity_log:
activity.log_create(amo.LOG.ADMIN_USER_BANNED, user)
log.info(
'User (%s: <%s>) is being banned.',
user,
user.email,
extra={'sensitive': True},
)
user.banned = user.modified = datetime.now()
user.deleted = True
# To delete their photo, avoid delete_picture() that updates
# picture_type immediately.
delete_photo.delay(user.pk, banned=user.banned)
return self.bulk_update(users, fields=('banned', 'deleted', 'modified'))