8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-12-04 18:42:25 +00:00
re2o/users/management/commands/anonymise.py

118 lines
4.6 KiB
Python

import os
import random
import string
from random import randint
from django.core.management.base import BaseCommand
from django.db.models import F, Q, Value
from django.db.models.functions import Concat
from reversion.models import Revision
from machines.models import Domain, Machine
from re2o.login import hashNT, makeSecret
from users.models import Adherent, Club, School, User
class Command(BaseCommand):
help = "Anonymise the data in the database in order to use them on critical servers (dev, personal...). Every information will be overwritten using non-personal information. This script must follow any modification of the database.\nOptional argument: {id|id|id|...} to exclude users from anonymisation."
def add_arguments(self, parser):
parser.add_argument("user_id", nargs="+", type=int, help="User ID")
def handle(self, *args, **kwargs):
users_ids = kwargs["user_id"]
for user_id in users_ids:
self.stdout.write(
"User: {} will not be anonymised.".format(
User.objects.filter(id=user_id).get().name
)
)
self.stdout.write(
self.style.WARNING(
"\nDISCLAIMER\nThis function will make your database unusable for production. Are you sure you want to run this? (doit): "
)
)
if input() == "doit":
total = Adherent.objects.count()
self.stdout.write("Starting anonymizing the {} users data.".format(total))
u = User.objects.filter(~Q(id__in=users_ids))
a = Adherent.objects.filter(~Q(id__in=users_ids))
c = Club.objects.filter(~Q(id__in=users_ids))
d = Domain.objects.all()
m = Machine.objects.filter(~Q(user_id__in=users_ids))
self.stdout.write("Deletion of the school...")
# Create a fake School to put everyone in it.
ecole = School(name="Ninja School")
ecole.save()
u.update(school=ecole)
self.stdout.write(self.style.SUCCESS("Done..."))
self.stdout.write("Deletion of rooms...")
a.update(room=None)
c.update(room=None)
self.stdout.write(self.style.SUCCESS("Done..."))
self.stdout.write("Deletion of email addresses...")
u.update(
email="example@example.org",
local_email_redirect=False,
local_email_enabled=False,
)
self.stdout.write(self.style.SUCCESS("Done..."))
self.stdout.write(
"Deletion of first names, surnames, usernames, telephone numbers, comments..."
)
a.update(name=Concat(Value("First name of "), "id"))
self.stdout.write(self.style.SUCCESS("Done for first names..."))
a.update(surname=Concat(Value("Surname of "), "id"))
self.stdout.write(self.style.SUCCESS("Done for surnames..."))
u.update(pseudo=F("id"))
self.stdout.write(self.style.SUCCESS("Done for usernames..."))
a.update(telephone=Concat(Value("Telephone number of "), "id"))
self.stdout.write(self.style.SUCCESS("Done for telephone numbers..."))
a.update(comment=Concat(Value("Comment of "), "id"))
self.stdout.write(self.style.SUCCESS("Done for comments..."))
self.stdout.write("Renaming of machines...")
m.update(
name=Concat(Value("Machine "), F("id"), Value(" of "), F("user_id"))
)
d.update(name=Concat(Value("Domain id "), F("id")))
self.stdout.write(self.style.SUCCESS("Done..."))
self.stdout.write("Unification of the password...")
# Define the password
chars = string.ascii_letters + string.digits + "!@#$%^&*()"
taille = 20
random.seed = os.urandom(1024)
password = ""
for i in range(taille):
password += random.choice(chars)
self.stdout.write(
self.style.HTTP_NOT_MODIFIED(
"The password will be: {}.".format(password)
)
)
u.update(pwd_ntlm=hashNT(password))
u.update(password=makeSecret(password))
self.stdout.write(self.style.SUCCESS("Done..."))
self.stdout.write("Deletion of the history (this may take some time)...")
Revision.objects.all().delete()
self.stdout.write(self.style.SUCCESS("Done..."))
self.stdout.write("Data anonymised!")
else:
self.stdout.write("Anonymisation aborted!")