2021-02-10 10:06:09 +00:00
import os
import random
import string
from random import randint
2018-11-04 16:26:04 +00:00
from django . core . management . base import BaseCommand
2021-02-10 10:06:09 +00:00
from django . db . models import F , Q , Value
2018-11-04 16:26:04 +00:00
from django . db . models . functions import Concat
2021-02-10 10:06:09 +00:00
from reversion . models import Revision
2018-11-04 16:26:04 +00:00
2021-02-10 10:06:09 +00:00
from machines . models import Domain , Machine
2018-11-04 17:09:24 +00:00
from re2o . login import hashNT , makeSecret
2021-02-10 10:06:09 +00:00
from users . models import Adherent , Club , School , User
2018-11-04 17:09:24 +00:00
2019-11-04 16:55:03 +00:00
2018-11-04 16:26:04 +00:00
class Command ( BaseCommand ) :
2019-11-16 14:11:57 +00:00
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. \n Optional argument: { id|id|id|...} to exclude users from anonymisation. "
2018-11-04 16:26:04 +00:00
2018-12-10 20:50:48 +00:00
def add_arguments ( self , parser ) :
2019-11-04 16:55:03 +00:00
parser . add_argument ( " user_id " , nargs = " + " , type = int , help = " User ID " )
2018-11-04 16:26:04 +00:00
2018-12-10 20:50:48 +00:00
def handle ( self , * args , * * kwargs ) :
2019-11-04 16:55:03 +00:00
users_ids = kwargs [ " user_id " ]
2018-12-10 20:50:48 +00:00
for user_id in users_ids :
2019-11-04 16:55:03 +00:00
self . stdout . write (
2019-11-16 14:11:57 +00:00
" User: {} will not be anonymised. " . format (
2019-11-04 16:55:03 +00:00
User . objects . filter ( id = user_id ) . get ( ) . name
)
)
self . stdout . write (
self . style . WARNING (
2019-11-16 14:11:57 +00:00
" \n DISCLAIMER \n This function will make your database unusable for production. Are you sure you want to run this? (doit): "
2019-11-04 16:55:03 +00:00
)
)
if input ( ) == " doit " :
2018-12-10 20:50:48 +00:00
total = Adherent . objects . count ( )
self . stdout . write ( " Starting anonymizing the {} users data. " . format ( total ) )
2019-11-04 16:55:03 +00:00
2018-12-10 20:50:48 +00:00
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 ) )
2019-11-16 14:11:57 +00:00
self . stdout . write ( " Deletion of the school... " )
2018-12-10 20:50:48 +00:00
# Create a fake School to put everyone in it.
2019-11-16 14:11:57 +00:00
ecole = School ( name = " Ninja School " )
2018-12-10 20:50:48 +00:00
ecole . save ( )
u . update ( school = ecole )
2019-11-16 14:11:57 +00:00
self . stdout . write ( self . style . SUCCESS ( " Done... " ) )
2018-12-10 20:50:48 +00:00
2019-11-16 14:11:57 +00:00
self . stdout . write ( " Deletion of rooms... " )
2018-12-10 20:50:48 +00:00
a . update ( room = None )
c . update ( room = None )
2019-11-16 14:11:57 +00:00
self . stdout . write ( self . style . SUCCESS ( " Done... " ) )
2019-11-04 16:55:03 +00:00
2019-11-16 14:11:57 +00:00
self . stdout . write ( " Deletion of email addresses... " )
2019-11-04 16:55:03 +00:00
u . update (
email = " example@example.org " ,
local_email_redirect = False ,
local_email_enabled = False ,
)
2019-11-16 14:11:57 +00:00
self . stdout . write ( self . style . SUCCESS ( " Done... " ) )
2019-11-04 16:55:03 +00:00
self . stdout . write (
2019-11-16 14:11:57 +00:00
" Deletion of first names, surnames, usernames, telephone numbers, comments... "
2019-11-04 16:55:03 +00:00
)
2019-11-16 14:11:57 +00:00
a . update ( name = Concat ( Value ( " First name of " ) , " id " ) )
self . stdout . write ( self . style . SUCCESS ( " Done for first names... " ) )
2019-11-04 16:55:03 +00:00
2019-11-16 14:11:57 +00:00
a . update ( surname = Concat ( Value ( " Surname of " ) , " id " ) )
self . stdout . write ( self . style . SUCCESS ( " Done for surnames... " ) )
2019-11-04 16:55:03 +00:00
u . update ( pseudo = F ( " id " ) )
2019-11-16 14:11:57 +00:00
self . stdout . write ( self . style . SUCCESS ( " Done for usernames... " ) )
2019-11-04 16:55:03 +00:00
2019-11-16 14:11:57 +00:00
a . update ( telephone = Concat ( Value ( " Telephone number of " ) , " id " ) )
self . stdout . write ( self . style . SUCCESS ( " Done for telephone numbers... " ) )
2019-11-04 16:55:03 +00:00
2019-11-16 14:11:57 +00:00
a . update ( comment = Concat ( Value ( " Comment of " ) , " id " ) )
self . stdout . write ( self . style . SUCCESS ( " Done for comments... " ) )
2019-11-04 16:55:03 +00:00
2019-11-16 14:11:57 +00:00
self . stdout . write ( " Renaming of machines... " )
2019-11-04 16:55:03 +00:00
m . update (
name = Concat ( Value ( " Machine " ) , F ( " id " ) , Value ( " of " ) , F ( " user_id " ) )
)
2019-11-16 14:11:57 +00:00
d . update ( name = Concat ( Value ( " Domain id " ) , F ( " id " ) ) )
self . stdout . write ( self . style . SUCCESS ( " Done... " ) )
2019-11-04 16:55:03 +00:00
2019-11-16 14:11:57 +00:00
self . stdout . write ( " Unification of the password... " )
2018-12-10 20:50:48 +00:00
# Define the password
2019-11-04 16:55:03 +00:00
chars = string . ascii_letters + string . digits + " !@#$ % ^&*() "
2018-12-10 20:50:48 +00:00
taille = 20
2019-11-04 16:55:03 +00:00
random . seed = os . urandom ( 1024 )
2018-12-10 20:50:48 +00:00
password = " "
for i in range ( taille ) :
2019-11-04 16:55:03 +00:00
password + = random . choice ( chars )
2018-12-10 20:50:48 +00:00
2019-11-04 16:55:03 +00:00
self . stdout . write (
self . style . HTTP_NOT_MODIFIED (
2019-11-16 14:11:57 +00:00
" The password will be: {} . " . format ( password )
2019-11-04 16:55:03 +00:00
)
)
2018-12-10 20:50:48 +00:00
2019-11-04 16:55:03 +00:00
u . update ( pwd_ntlm = hashNT ( password ) )
u . update ( password = makeSecret ( password ) )
2019-11-16 14:11:57 +00:00
self . stdout . write ( self . style . SUCCESS ( " Done... " ) )
2018-12-10 20:50:48 +00:00
2019-11-16 14:11:57 +00:00
self . stdout . write ( " Deletion of the history (this may take some time)... " )
2019-01-09 18:14:06 +00:00
Revision . objects . all ( ) . delete ( )
2019-11-16 14:11:57 +00:00
self . stdout . write ( self . style . SUCCESS ( " Done... " ) )
2019-01-09 18:14:06 +00:00
2019-11-16 14:11:57 +00:00
self . stdout . write ( " Data anonymised! " )
2018-12-10 20:50:48 +00:00
else :
2019-11-16 14:11:57 +00:00
self . stdout . write ( " Anonymisation aborted! " )