from datetime import timedelta from typing import List from unittest import skipIf from django.contrib.auth.models import User from django.core.files.base import ContentFile from django.test import TestCase from gdpr.anonymizers import ModelAnonymizer from gdpr.loading import anonymizer_register from gdpr.utils import is_reversion_installed, get_reversion_local_field_dict from tests.anonymizers import ContactFormAnonymizer, ChildEAnonymizer from tests.models import Account, Address, ContactForm, Customer, Email, Note, Payment, Avatar, ChildE from .data import ( ACCOUNT__IBAN, ACCOUNT__NUMBER, ACCOUNT__OWNER, ACCOUNT__SWIFT, ADDRESS__CITY, ADDRESS__HOUSE_NUMBER, ADDRESS__POST_CODE, ADDRESS__STREET, CUSTOMER__BIRTH_DATE, CUSTOMER__EMAIL, CUSTOMER__EMAIL2, CUSTOMER__EMAIL3, CUSTOMER__FACEBOOK_ID, CUSTOMER__FIRST_NAME, CUSTOMER__IP, CUSTOMER__KWARGS, CUSTOMER__LAST_NAME, CUSTOMER__PERSONAL_ID, CUSTOMER__PHONE_NUMBER, PAYMENT__VALUE) from .utils import AnonymizedDataMixin, NotImplementedMixin class TestModelAnonymization(AnonymizedDataMixin, NotImplementedMixin, TestCase): @classmethod def setUpTestData(cls): cls.customer: Customer = Customer(**CUSTOMER__KWARGS) cls.customer.save() cls.base_encryption_key = 'LoremIpsum' def test_anonymize_customer(self): self.customer._anonymize_obj() anon_customer: Customer = Customer.objects.get(pk=self.customer.pk) self.assertNotEqual(anon_customer.first_name, CUSTOMER__FIRST_NAME) self.assertAnonymizedDataExists(anon_customer, 'first_name') self.assertNotEqual(anon_customer.last_name, CUSTOMER__LAST_NAME) self.assertAnonymizedDataExists(anon_customer, 'last_name') self.assertNotEqual(anon_customer.full_name, '%s %s' % (CUSTOMER__FIRST_NAME, CUSTOMER__LAST_NAME)) self.assertAnonymizedDataExists(anon_customer, 'full_name') self.assertNotEqual(anon_customer.primary_email_address, CUSTOMER__EMAIL) self.assertAnonymizedDataExists(anon_customer, 'primary_email_address') self.assertNotEqual(anon_customer.personal_id, CUSTOMER__PERSONAL_ID) self.assertAnonymizedDataExists(anon_customer, 'personal_id') self.assertNotEqual(anon_customer.phone_number, CUSTOMER__PHONE_NUMBER) self.assertAnonymizedDataExists(anon_customer, 'phone_number') self.assertNotEquals(anon_customer.birth_date, CUSTOMER__BIRTH_DATE) self.assertAnonymizedDataExists(anon_customer, 'first_name') self.assertNotEquals(anon_customer.facebook_id, CUSTOMER__FACEBOOK_ID) self.assertAnonymizedDataExists(anon_customer, 'first_name') self.assertNotEqual(str(anon_customer.last_login_ip), CUSTOMER__IP) self.assertAnonymizedDataExists(anon_customer, 'first_name') def test_email(self): self.email: Email = Email(customer=self.customer, email=CUSTOMER__EMAIL) self.email.save() self.email._anonymize_obj(base_encryption_key=self.base_encryption_key) anon_email: Email = Email.objects.get(pk=self.email.pk) self.assertNotEqual(anon_email.email, CUSTOMER__EMAIL) def test_address(self): self.address: Address = Address( customer=self.customer, street=ADDRESS__STREET, house_number=ADDRESS__HOUSE_NUMBER, city=ADDRESS__CITY, post_code=ADDRESS__POST_CODE, ) self.address.save() self.address._anonymize_obj(base_encryption_key=self.base_encryption_key) anon_address: Address = Address.objects.get(pk=self.address.pk) self.assertNotEqual(anon_address.street, ADDRESS__STREET) self.assertAnonymizedDataExists(anon_address, 'street') self.assertEqual(anon_address.house_number, ADDRESS__HOUSE_NUMBER) self.assertEqual(anon_address.city, ADDRESS__CITY) self.assertEqual(anon_address.post_code, ADDRESS__POST_CODE) def test_account(self): self.account: Account = Account( customer=self.customer, number=ACCOUNT__NUMBER, owner=ACCOUNT__OWNER, IBAN=ACCOUNT__IBAN, swift=ACCOUNT__SWIFT, ) self.account.save() self.account._anonymize_obj(base_encryption_key=self.base_encryption_key) anon_account: Account = Account.objects.get(pk=self.account.pk) self.assertNotEqual(anon_account.number, ACCOUNT__NUMBER) self.assertAnonymizedDataExists(anon_account, 'number') self.assertNotEqual(anon_account.owner, ACCOUNT__OWNER) self.assertAnonymizedDataExists(anon_account, 'owner') self.assertNotEqual(anon_account.IBAN, ACCOUNT__IBAN) self.assertAnonymizedDataExists(anon_account, 'IBAN') def test_payment(self): self.account: Account = Account( customer=self.customer, number=ACCOUNT__NUMBER, owner=ACCOUNT__OWNER, IBAN=ACCOUNT__IBAN, swift=ACCOUNT__SWIFT, ) self.account.save() self.payment: Payment = Payment( account=self.account, value=PAYMENT__VALUE, ) self.payment.save() payment_date = self.payment.date self.payment._anonymize_obj(base_encryption_key=self.base_encryption_key) anon_payment: Payment = Payment.objects.get(pk=self.payment.pk) self.assertNotEquals(anon_payment.value, PAYMENT__VALUE) self.assertAnonymizedDataExists(anon_payment, 'value') self.assertNotEquals(anon_payment.date, payment_date) self.assertAnonymizedDataExists(anon_payment, 'date') def test_contact_form(self): FULL_NAME = '%s %s' % (CUSTOMER__FIRST_NAME, CUSTOMER__LAST_NAME) self.contact_form: ContactForm = ContactForm( email=CUSTOMER__EMAIL, full_name=FULL_NAME ) self.contact_form.save() self.contact_form._anonymize_obj() anon_contact_form: ContactForm = ContactForm.objects.get(pk=self.contact_form.pk) self.assertNotEqual(anon_contact_form.email, CUSTOMER__EMAIL) self.assertAnonymizedDataExists(anon_contact_form, 'email') self.assertNotEqual(anon_contact_form.full_name, FULL_NAME) self.assertAnonymizedDataExists(anon_contact_form, 'full_name') def test_anonymization_of_anonymized_data(self): '''Test that anonymized data are not anonymized again.''' self.customer._anonymize_obj() anon_customer: Customer = Customer.objects.get(pk=self.customer.pk) self.assertNotEqual(anon_customer.first_name, CUSTOMER__FIRST_NAME) self.assertAnonymizedDataExists(anon_customer, 'first_name') anon_customer._anonymize_obj() anon_customer2: Customer = Customer.objects.get(pk=self.customer.pk) self.assertEqual(anon_customer2.first_name, anon_customer.first_name) self.assertNotEqual(anon_customer2.first_name, CUSTOMER__FIRST_NAME) def test_anonymization_field_matrix(self): self.customer._anonymize_obj(fields=('first_name',)) anon_customer: Customer = Customer.objects.get(pk=self.customer.pk) self.assertNotEqual(anon_customer.first_name, CUSTOMER__FIRST_NAME) self.assertAnonymizedDataExists(anon_customer, 'first_name') self.assertEqual(anon_customer.last_name, CUSTOMER__LAST_NAME) self.assertAnonymizedDataNotExists(anon_customer, 'last_name') def test_anonymization_field_matrix_related(self): related_email: Email = Email(customer=self.customer, email=CUSTOMER__EMAIL) related_email.save() self.customer._anonymize_obj(fields=('first_name', ('emails', ('email',)))) anon_customer: Customer = Customer.objects.get(pk=self.customer.pk) self.assertNotEqual(anon_customer.first_name, CUSTOMER__FIRST_NAME) self.assertAnonymizedDataExists(anon_customer, 'first_name') self.assertEqual(anon_customer.last_name, CUSTOMER__LAST_NAME) self.assertAnonymizedDataNotExists(anon_customer, 'last_name') anon_related_email: Email = Email.objects.get(pk=related_email.pk) self.assertNotEqual(anon_related_email.email, CUSTOMER__EMAIL) self.assertAnonymizedDataExists(anon_related_email, 'email') def test_anonymization_field_matrix_related_all(self): related_email: Email = Email(customer=self.customer, email=CUSTOMER__EMAIL) related_email.save() self.customer._anonymize_obj(fields=('first_name', ('emails', '__ALL__'))) anon_customer: Customer = Customer.objects.get(pk=self.customer.pk) self.assertNotEqual(anon_customer.first_name, CUSTOMER__FIRST_NAME) self.assertAnonymizedDataExists(anon_customer, 'first_name') self.assertEqual(anon_customer.last_name, CUSTOMER__LAST_NAME) self.assertAnonymizedDataNotExists(anon_customer, 'last_name') anon_related_email: Email = Email.objects.get(pk=related_email.pk) self.assertNotEqual(anon_related_email.email, CUSTOMER__EMAIL) self.assertAnonymizedDataExists(anon_related_email, 'email') def test_reverse_generic_relation(self): note: Note = Note(note='Test message') note.content_object = self.customer note.save() self.customer._anonymize_obj(fields=(('notes', '__ALL__'),)) anon_note: Note = Note.objects.get(pk=note.pk) self.assertNotEqual(anon_note.note, note.note) self.assertAnonymizedDataExists(note, 'note') self.customer._deanonymize_obj(fields=(('notes', '__ALL__'),)) anon_note2: Note = Note.objects.get(pk=note.pk) self.assertEqual(anon_note2.note, note.note) self.assertAnonymizedDataNotExists(note, 'note') def test_irreversible_deanonymization(self): contact_form: ContactForm = ContactForm(email=CUSTOMER__EMAIL, full_name=CUSTOMER__LAST_NAME) contact_form.save() contact_form._anonymize_obj(fields=('__ALL__',)) self.assertRaises(ModelAnonymizer.IrreversibleAnonymizerException, contact_form._deanonymize_obj, fields=('__ALL__',)) def test_generic_relation_anonymizer(self): contact_form: ContactForm = ContactForm(email=CUSTOMER__EMAIL, full_name=CUSTOMER__LAST_NAME) contact_form.save() note: Note = Note(note='Test message') note.content_object = contact_form note.save() note._anonymize_obj(fields=(('contact_form', '__ALL__'),), base_encryption_key=self.base_encryption_key) anon_contact_form: ContactForm = ContactForm.objects.get(pk=contact_form.pk) self.assertNotEqual(anon_contact_form.email, CUSTOMER__EMAIL) self.assertAnonymizedDataExists(anon_contact_form, 'email') self.assertNotEqual(anon_contact_form.full_name, CUSTOMER__LAST_NAME) self.assertAnonymizedDataExists(anon_contact_form, 'full_name') @skipIf(not is_reversion_installed(), 'Django-reversion is not installed.') def test_reversion_anonymization(self): from reversion import revisions as reversion from reversion.models import Version from gdpr.utils import get_reversion_versions anon = ContactFormAnonymizer() anon.Meta.anonymize_reversion = True anon.Meta.reversible_anonymization = True user = User(username='test_username') user.save() with reversion.create_revision(): form = ContactForm() form.email = CUSTOMER__EMAIL form.full_name = CUSTOMER__LAST_NAME form.save() reversion.set_user(user) with reversion.create_revision(): form.email = CUSTOMER__EMAIL2 form.save() reversion.set_user(user) with reversion.create_revision(): form.email = CUSTOMER__EMAIL3 form.save() reversion.set_user(user) versions: List[Version] = get_reversion_versions(form) self.assertEqual(versions[0].field_dict['email'], CUSTOMER__EMAIL) self.assertEqual(versions[1].field_dict['email'], CUSTOMER__EMAIL2) self.assertEqual(versions[2].field_dict['email'], CUSTOMER__EMAIL3) anon.anonymize_obj(form, base_encryption_key=self.base_encryption_key) anon_versions: List[Version] = get_reversion_versions(form) anon_form = ContactForm.objects.get(pk=form.pk) self.assertNotEqual(anon_versions[0].field_dict['email'], CUSTOMER__EMAIL) self.assertNotEqual(anon_versions[1].field_dict['email'], CUSTOMER__EMAIL2) self.assertNotEqual(anon_versions[2].field_dict['email'], CUSTOMER__EMAIL3) self.assertNotEqual(anon_form.email, CUSTOMER__EMAIL3) anon.deanonymize_obj(anon_form, base_encryption_key=self.base_encryption_key) deanon_versions: List[Version] = get_reversion_versions(form) deanon_form = ContactForm.objects.get(pk=form.pk) self.assertEqual(deanon_versions[0].field_dict['email'], CUSTOMER__EMAIL) self.assertEqual(deanon_versions[1].field_dict['email'], CUSTOMER__EMAIL2) self.assertEqual(deanon_versions[2].field_dict['email'], CUSTOMER__EMAIL3) self.assertEqual(deanon_form.email, CUSTOMER__EMAIL3) self.assertDictEqual(versions[0].field_dict, deanon_versions[0].field_dict) self.assertDictEqual(versions[1].field_dict, deanon_versions[1].field_dict) self.assertDictEqual(versions[2].field_dict, deanon_versions[2].field_dict) @skipIf(not is_reversion_installed(), 'Django-reversion is not installed.') def test_reversion_anonymization_parents(self): from reversion import revisions as reversion from reversion.models import Version from gdpr.utils import get_reversion_versions anon = ChildEAnonymizer() user = User(username='testing_username') user.save() with reversion.create_revision(): e = ChildE() e.name = 'Lorem' e.first_name = 'Ipsum' e.last_name = 'Dolor' e.birth_date = CUSTOMER__BIRTH_DATE e.note = 'sit Amet' e.save() reversion.set_user(user) with reversion.create_revision(): e.name = 'LOREM' e.first_name = 'IPSUM' e.last_name = 'DOLOR' e.birth_date = CUSTOMER__BIRTH_DATE + timedelta(days=2) e.note = 'SIT AMET' e.save() reversion.set_user(user) versions_a: List[Version] = get_reversion_versions(e.topparenta_ptr) versions_b: List[Version] = get_reversion_versions(e.parentb_ptr) versions_c: List[Version] = get_reversion_versions(e.parentc_ptr) versions_d: List[Version] = get_reversion_versions(e.extraparentd_ptr) versions_e: List[Version] = get_reversion_versions(e) self.assertEqual(get_reversion_local_field_dict(versions_a[0])['name'], 'Lorem') self.assertEqual(get_reversion_local_field_dict(versions_a[1])['name'], 'LOREM') self.assertEqual(get_reversion_local_field_dict(versions_b[0])['birth_date'], CUSTOMER__BIRTH_DATE) self.assertEqual(get_reversion_local_field_dict(versions_b[1])['birth_date'], CUSTOMER__BIRTH_DATE + timedelta(days=2)) self.assertEqual(get_reversion_local_field_dict(versions_c[0])['first_name'], 'Ipsum') self.assertEqual(get_reversion_local_field_dict(versions_c[1])['first_name'], 'IPSUM') self.assertEqual(get_reversion_local_field_dict(versions_d[0])['note'], 'sit Amet') self.assertEqual(get_reversion_local_field_dict(versions_d[1])['note'], 'SIT AMET') self.assertEqual(get_reversion_local_field_dict(versions_e[0])['last_name'], 'Dolor') self.assertEqual(get_reversion_local_field_dict(versions_e[1])['last_name'], 'DOLOR') anon.anonymize_obj(e, base_encryption_key=self.base_encryption_key) anon_versions_a: List[Version] = get_reversion_versions(e.topparenta_ptr) anon_versions_b: List[Version] = get_reversion_versions(e.parentb_ptr) anon_versions_c: List[Version] = get_reversion_versions(e.parentc_ptr) anon_versions_d: List[Version] = get_reversion_versions(e.extraparentd_ptr) anon_versions_e: List[Version] = get_reversion_versions(e) anon_e = ChildE.objects.get(pk=e.pk) self.assertNotEqual(get_reversion_local_field_dict(anon_versions_a[0])['name'], 'Lorem') self.assertNotEqual(get_reversion_local_field_dict(anon_versions_a[1])['name'], 'LOREM') self.assertNotEqual(get_reversion_local_field_dict(anon_versions_b[0])['birth_date'], CUSTOMER__BIRTH_DATE) self.assertNotEqual(get_reversion_local_field_dict(anon_versions_b[1])['birth_date'], CUSTOMER__BIRTH_DATE + timedelta(days=2)) self.assertNotEqual(get_reversion_local_field_dict(anon_versions_c[0])['first_name'], 'Ipsum') self.assertNotEqual(get_reversion_local_field_dict(anon_versions_c[1])['first_name'], 'IPSUM') self.assertNotEqual(get_reversion_local_field_dict(anon_versions_d[0])['note'], 'sit Amet') self.assertNotEqual(get_reversion_local_field_dict(anon_versions_d[1])['note'], 'SIT AMET') self.assertNotEqual(get_reversion_local_field_dict(anon_versions_e[0])['last_name'], 'Dolor') self.assertNotEqual(get_reversion_local_field_dict(anon_versions_e[1])['last_name'], 'DOLOR') anon.deanonymize_obj(anon_e, base_encryption_key=self.base_encryption_key) deanon_versions_a: List[Version] = get_reversion_versions(e.topparenta_ptr) deanon_versions_b: List[Version] = get_reversion_versions(e.parentb_ptr) deanon_versions_c: List[Version] = get_reversion_versions(e.parentc_ptr) deanon_versions_d: List[Version] = get_reversion_versions(e.extraparentd_ptr) deanon_versions_e: List[Version] = get_reversion_versions(e) self.assertEqual(get_reversion_local_field_dict(deanon_versions_a[0])['name'], 'Lorem') self.assertEqual(get_reversion_local_field_dict(deanon_versions_a[1])['name'], 'LOREM') self.assertEqual(get_reversion_local_field_dict(deanon_versions_b[0])['birth_date'], CUSTOMER__BIRTH_DATE) self.assertEqual(get_reversion_local_field_dict(deanon_versions_b[1])['birth_date'], CUSTOMER__BIRTH_DATE + timedelta(days=2)) self.assertEqual(get_reversion_local_field_dict(deanon_versions_c[0])['first_name'], 'Ipsum') self.assertEqual(get_reversion_local_field_dict(deanon_versions_c[1])['first_name'], 'IPSUM') self.assertEqual(get_reversion_local_field_dict(deanon_versions_d[0])['note'], 'sit Amet') self.assertEqual(get_reversion_local_field_dict(deanon_versions_d[1])['note'], 'SIT AMET') self.assertEqual(get_reversion_local_field_dict(deanon_versions_e[0])['last_name'], 'Dolor') self.assertEqual(get_reversion_local_field_dict(deanon_versions_e[1])['last_name'], 'DOLOR') class TestFileFieldAnonymizer(TestCase): def test_file_field(self): customer = Customer(**CUSTOMER__KWARGS) customer.save() avatar = Avatar() avatar.customer = customer avatar.image.save('test_file_secret_data', ContentFile('Super secret data'), save=False) avatar.save() avatar_2: Avatar = Avatar.objects.last() self.assertEqual(avatar_2.image.read(), b'Super secret data') avatar_2._anonymize_obj(base_encryption_key='LoremIpsumDolorSitAmet') avatar_3: Avatar = Avatar.objects.last() self.assertNotEqual(avatar_3.image.read(), b'Super secret data') # Cleanup avatar_3.image.delete() avatar_3.delete() def test_file_field_real_file(self): anonymizer = anonymizer_register[Avatar] anonymizer.image.replacement_file = 'test_file' customer = Customer(**CUSTOMER__KWARGS) customer.save() avatar = Avatar() avatar.customer = customer avatar.image.save('test_file_real', ContentFile('Super secret data')) avatar_2: Avatar = Avatar.objects.last() self.assertEqual(avatar_2.image.read(), b'Super secret data') avatar_2._anonymize_obj(base_encryption_key='LoremIpsumDolorSitAmet') avatar_3: Avatar = Avatar.objects.last() self.assertNotEqual(avatar_3.image.read(), b'Super secret data') anonymizer.image.replacement_file = None # Cleanup avatar_3.image.delete() avatar_3.delete()