summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--python-django-gdpr.spec651
-rw-r--r--sources1
3 files changed, 653 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index e69de29..fc9a6d6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+/django-GDPR-0.2.23.tar.gz
diff --git a/python-django-gdpr.spec b/python-django-gdpr.spec
new file mode 100644
index 0000000..a984308
--- /dev/null
+++ b/python-django-gdpr.spec
@@ -0,0 +1,651 @@
+%global _empty_manifest_terminate_build 0
+Name: python-django-GDPR
+Version: 0.2.23
+Release: 1
+Summary: Library for GDPR implementation
+License: MIT
+URL: https://github.com/druids/django-GDPR
+Source0: https://mirrors.nju.edu.cn/pypi/web/packages/26/4c/30ab7e7b9a91a31ccc0f82c7912579616149351f4d063267a8ca00006423/django-GDPR-0.2.23.tar.gz
+BuildArch: noarch
+
+
+%description
+# Django-GDPR [![Build Status](https://travis-ci.org/BrnoPCmaniak/django-GDPR.svg?branch=develop)](https://travis-ci.org/BrnoPCmaniak/django-GDPR)
+
+This library enables you to store user's consent for data retention easily
+and to anonymize/deanonymize user's data accordingly.
+
+For brief overview you can check example app in `tests` directory.
+
+# Quickstart
+
+Install django-gdpr with pip:
+
+```bash
+pip install django-gdpr
+```
+
+Add gdpr to your `INSTALLED_APPS`:
+
+```python
+INSTALLED_APPS = [
+ # Django apps...
+ 'gdpr',
+]
+```
+
+Imagine having a customer model:
+
+```python
+# app/models.py
+
+from django.db import models
+
+from gdpr.mixins import AnonymizationModel
+
+class Customer(AnonymizationModel):
+ # these fields will be used as basic keys for pseudoanonymization
+ first_name = models.CharField(max_length=256)
+ last_name = models.CharField(max_length=256)
+
+ birth_date = models.DateField(blank=True, null=True)
+ personal_id = models.CharField(max_length=10, blank=True, null=True)
+ phone_number = models.CharField(max_length=9, blank=True, null=True)
+ fb_id = models.CharField(max_length=256, blank=True, null=True)
+ last_login_ip = models.GenericIPAddressField(blank=True, null=True)
+```
+
+You may want a consent to store all user's data for two years and consent to store first and last name for 10 years.
+For that you can simply add new consent purposes like this.
+
+```python
+# app/purposes.py
+
+from dateutil.relativedelta import relativedelta
+
+from gdpr.purposes.default import AbstractPurpose
+
+GENERAL_PURPOSE_SLUG = "general"
+FIRST_AND_LAST_NAME_SLUG = "first_and_last"
+
+class GeneralPurpose(AbstractPurpose):
+ name = "Retain user data for 2 years"
+ slug = GENERAL_PURPOSE_SLUG
+ expiration_timedelta = relativedelta(years=2)
+ fields = "__ALL__" # Anonymize all fields defined in anonymizer
+
+class FirstAndLastNamePurpose(AbstractPurpose):
+ """Store First & Last name for 10 years."""
+ name = "retain due to internet archive"
+ slug = FIRST_AND_LAST_NAME_SLUG
+ expiration_timedelta = relativedelta(years=10)
+ fields = ("first_name", "last_name")
+```
+
+The field `fields` specify to which fields this consent applies to.
+
+Some more examples:
+```python
+fields = ("first_name", "last_name") # Anonymize only two fields
+
+# You can also add nested fields to anonymize fields on related objects.
+fields = (
+ "primary_email_address",
+ ("emails", (
+ "email",
+ )),
+)
+
+# Some more advanced configs may look like this:
+fields = (
+ "__ALL__",
+ ("addresses", "__ALL__"),
+ ("accounts", (
+ "__ALL__",
+ ("payments", (
+ "__ALL__",
+ ))
+ )),
+ ("emails", (
+ "email",
+ )),
+)
+
+```
+
+Now when we have the purpose(s) created we also have to make an _anonymizer_ so the library knows which fields to
+anonymize and how. This is fairly simple and is quite similar to Django forms.
+
+```python
+# app/anonymizers.py
+
+from gdpr import anonymizers
+from tests.models import Customer
+
+
+class CustomerAnonymizer(anonymizers.ModelAnonymizer):
+ first_name = anonymizers.MD5TextFieldAnonymizer()
+ last_name = anonymizers.MD5TextFieldAnonymizer()
+ primary_email_address = anonymizers.EmailFieldAnonymizer()
+
+ birth_date = anonymizers.DateFieldAnonymizer()
+ personal_id = anonymizers.PersonalIIDFieldAnonymizer()
+ phone_number = anonymizers.PhoneFieldAnonymizer()
+ fb_id = anonymizers.CharFieldAnonymizer()
+ last_login_ip = anonymizers.IPAddressFieldAnonymizer()
+
+ class Meta:
+ model = Customer
+```
+
+Now you can fully leverage the system:
+
+You can create/revoke consent:
+```python
+from gdpr.models import LegalReason
+
+from tests.models import Customer
+from tests.purposes import FIRST_AND_LAST_NAME_SLUG
+
+
+customer = Customer(first_name="John", last_name="Smith")
+customer.save()
+
+# Create consent
+LegalReason.objects.create_consent(FIRST_AND_LAST_NAME_SLUG, customer)
+
+# And now you can revoke it
+LegalReason.objects.deactivate_consent(FIRST_AND_LAST_NAME_SLUG, customer)
+```
+
+In case your model uses the `AnonymizationModelMixin` or `AnonymizationModel` you can create and revoke consents even
+easier.
+```python
+from tests.models import Customer
+from tests.purposes import FIRST_AND_LAST_NAME_SLUG
+
+
+customer = Customer(first_name="John", last_name="Smith")
+customer.save()
+
+# Create consent
+customer.create_consent(FIRST_AND_LAST_NAME_SLUG)
+
+# And now you can revoke it
+customer.deactivate_consent(FIRST_AND_LAST_NAME_SLUG)
+```
+
+
+Expired consents are revoked by running the following command. You should invoke it repeatedly, for example by cron.
+The invocation interval depends on your circumstances - how fast you want to expire consents after their revocation,
+the amount of consents to expire in the interval, server load, and last but not least, legal requirements.
+
+```python
+from gdpr.models import LegalReason
+
+LegalReason.objects.expire_old_consents()
+```
+
+## FieldAnonymizers
+
+* `FunctionAnonymizer` - in place lambda/function anonymization method (e.g. `secret_code = anonymizers.FunctionFieldAnonymizer(lambda x: x**2)`)
+* `DateFieldAnonymizer`
+* `CharFieldAnonymizer`
+* `DecimalFieldAnonymizer`
+* `IPAddressFieldAnonymizer`
+* `CzechAccountNumberFieldAnonymizer` - for czech bank account numbers
+* `IBANFieldAnonymizer`
+* `JSONFieldAnonymizer`
+* `EmailFieldAnonymizer`
+* `MD5TextFieldAnonymizer`
+* `SHA256TextFieldAnonymizer`
+* `HashTextFieldAnonymizer` - anonymization using given hash algorithm (e.g. `secret_code = anonymizers.HashTextFieldAnonymizer('sha512')`)
+* `StaticValueFieldAnonymizer` - anonymization by replacing with static value (e.g. `secret_code = anonymizers.StaticValueFieldAnonymizer(42)`)
+
+
+
+
+%package -n python3-django-GDPR
+Summary: Library for GDPR implementation
+Provides: python-django-GDPR
+BuildRequires: python3-devel
+BuildRequires: python3-setuptools
+BuildRequires: python3-pip
+%description -n python3-django-GDPR
+# Django-GDPR [![Build Status](https://travis-ci.org/BrnoPCmaniak/django-GDPR.svg?branch=develop)](https://travis-ci.org/BrnoPCmaniak/django-GDPR)
+
+This library enables you to store user's consent for data retention easily
+and to anonymize/deanonymize user's data accordingly.
+
+For brief overview you can check example app in `tests` directory.
+
+# Quickstart
+
+Install django-gdpr with pip:
+
+```bash
+pip install django-gdpr
+```
+
+Add gdpr to your `INSTALLED_APPS`:
+
+```python
+INSTALLED_APPS = [
+ # Django apps...
+ 'gdpr',
+]
+```
+
+Imagine having a customer model:
+
+```python
+# app/models.py
+
+from django.db import models
+
+from gdpr.mixins import AnonymizationModel
+
+class Customer(AnonymizationModel):
+ # these fields will be used as basic keys for pseudoanonymization
+ first_name = models.CharField(max_length=256)
+ last_name = models.CharField(max_length=256)
+
+ birth_date = models.DateField(blank=True, null=True)
+ personal_id = models.CharField(max_length=10, blank=True, null=True)
+ phone_number = models.CharField(max_length=9, blank=True, null=True)
+ fb_id = models.CharField(max_length=256, blank=True, null=True)
+ last_login_ip = models.GenericIPAddressField(blank=True, null=True)
+```
+
+You may want a consent to store all user's data for two years and consent to store first and last name for 10 years.
+For that you can simply add new consent purposes like this.
+
+```python
+# app/purposes.py
+
+from dateutil.relativedelta import relativedelta
+
+from gdpr.purposes.default import AbstractPurpose
+
+GENERAL_PURPOSE_SLUG = "general"
+FIRST_AND_LAST_NAME_SLUG = "first_and_last"
+
+class GeneralPurpose(AbstractPurpose):
+ name = "Retain user data for 2 years"
+ slug = GENERAL_PURPOSE_SLUG
+ expiration_timedelta = relativedelta(years=2)
+ fields = "__ALL__" # Anonymize all fields defined in anonymizer
+
+class FirstAndLastNamePurpose(AbstractPurpose):
+ """Store First & Last name for 10 years."""
+ name = "retain due to internet archive"
+ slug = FIRST_AND_LAST_NAME_SLUG
+ expiration_timedelta = relativedelta(years=10)
+ fields = ("first_name", "last_name")
+```
+
+The field `fields` specify to which fields this consent applies to.
+
+Some more examples:
+```python
+fields = ("first_name", "last_name") # Anonymize only two fields
+
+# You can also add nested fields to anonymize fields on related objects.
+fields = (
+ "primary_email_address",
+ ("emails", (
+ "email",
+ )),
+)
+
+# Some more advanced configs may look like this:
+fields = (
+ "__ALL__",
+ ("addresses", "__ALL__"),
+ ("accounts", (
+ "__ALL__",
+ ("payments", (
+ "__ALL__",
+ ))
+ )),
+ ("emails", (
+ "email",
+ )),
+)
+
+```
+
+Now when we have the purpose(s) created we also have to make an _anonymizer_ so the library knows which fields to
+anonymize and how. This is fairly simple and is quite similar to Django forms.
+
+```python
+# app/anonymizers.py
+
+from gdpr import anonymizers
+from tests.models import Customer
+
+
+class CustomerAnonymizer(anonymizers.ModelAnonymizer):
+ first_name = anonymizers.MD5TextFieldAnonymizer()
+ last_name = anonymizers.MD5TextFieldAnonymizer()
+ primary_email_address = anonymizers.EmailFieldAnonymizer()
+
+ birth_date = anonymizers.DateFieldAnonymizer()
+ personal_id = anonymizers.PersonalIIDFieldAnonymizer()
+ phone_number = anonymizers.PhoneFieldAnonymizer()
+ fb_id = anonymizers.CharFieldAnonymizer()
+ last_login_ip = anonymizers.IPAddressFieldAnonymizer()
+
+ class Meta:
+ model = Customer
+```
+
+Now you can fully leverage the system:
+
+You can create/revoke consent:
+```python
+from gdpr.models import LegalReason
+
+from tests.models import Customer
+from tests.purposes import FIRST_AND_LAST_NAME_SLUG
+
+
+customer = Customer(first_name="John", last_name="Smith")
+customer.save()
+
+# Create consent
+LegalReason.objects.create_consent(FIRST_AND_LAST_NAME_SLUG, customer)
+
+# And now you can revoke it
+LegalReason.objects.deactivate_consent(FIRST_AND_LAST_NAME_SLUG, customer)
+```
+
+In case your model uses the `AnonymizationModelMixin` or `AnonymizationModel` you can create and revoke consents even
+easier.
+```python
+from tests.models import Customer
+from tests.purposes import FIRST_AND_LAST_NAME_SLUG
+
+
+customer = Customer(first_name="John", last_name="Smith")
+customer.save()
+
+# Create consent
+customer.create_consent(FIRST_AND_LAST_NAME_SLUG)
+
+# And now you can revoke it
+customer.deactivate_consent(FIRST_AND_LAST_NAME_SLUG)
+```
+
+
+Expired consents are revoked by running the following command. You should invoke it repeatedly, for example by cron.
+The invocation interval depends on your circumstances - how fast you want to expire consents after their revocation,
+the amount of consents to expire in the interval, server load, and last but not least, legal requirements.
+
+```python
+from gdpr.models import LegalReason
+
+LegalReason.objects.expire_old_consents()
+```
+
+## FieldAnonymizers
+
+* `FunctionAnonymizer` - in place lambda/function anonymization method (e.g. `secret_code = anonymizers.FunctionFieldAnonymizer(lambda x: x**2)`)
+* `DateFieldAnonymizer`
+* `CharFieldAnonymizer`
+* `DecimalFieldAnonymizer`
+* `IPAddressFieldAnonymizer`
+* `CzechAccountNumberFieldAnonymizer` - for czech bank account numbers
+* `IBANFieldAnonymizer`
+* `JSONFieldAnonymizer`
+* `EmailFieldAnonymizer`
+* `MD5TextFieldAnonymizer`
+* `SHA256TextFieldAnonymizer`
+* `HashTextFieldAnonymizer` - anonymization using given hash algorithm (e.g. `secret_code = anonymizers.HashTextFieldAnonymizer('sha512')`)
+* `StaticValueFieldAnonymizer` - anonymization by replacing with static value (e.g. `secret_code = anonymizers.StaticValueFieldAnonymizer(42)`)
+
+
+
+
+%package help
+Summary: Development documents and examples for django-GDPR
+Provides: python3-django-GDPR-doc
+%description help
+# Django-GDPR [![Build Status](https://travis-ci.org/BrnoPCmaniak/django-GDPR.svg?branch=develop)](https://travis-ci.org/BrnoPCmaniak/django-GDPR)
+
+This library enables you to store user's consent for data retention easily
+and to anonymize/deanonymize user's data accordingly.
+
+For brief overview you can check example app in `tests` directory.
+
+# Quickstart
+
+Install django-gdpr with pip:
+
+```bash
+pip install django-gdpr
+```
+
+Add gdpr to your `INSTALLED_APPS`:
+
+```python
+INSTALLED_APPS = [
+ # Django apps...
+ 'gdpr',
+]
+```
+
+Imagine having a customer model:
+
+```python
+# app/models.py
+
+from django.db import models
+
+from gdpr.mixins import AnonymizationModel
+
+class Customer(AnonymizationModel):
+ # these fields will be used as basic keys for pseudoanonymization
+ first_name = models.CharField(max_length=256)
+ last_name = models.CharField(max_length=256)
+
+ birth_date = models.DateField(blank=True, null=True)
+ personal_id = models.CharField(max_length=10, blank=True, null=True)
+ phone_number = models.CharField(max_length=9, blank=True, null=True)
+ fb_id = models.CharField(max_length=256, blank=True, null=True)
+ last_login_ip = models.GenericIPAddressField(blank=True, null=True)
+```
+
+You may want a consent to store all user's data for two years and consent to store first and last name for 10 years.
+For that you can simply add new consent purposes like this.
+
+```python
+# app/purposes.py
+
+from dateutil.relativedelta import relativedelta
+
+from gdpr.purposes.default import AbstractPurpose
+
+GENERAL_PURPOSE_SLUG = "general"
+FIRST_AND_LAST_NAME_SLUG = "first_and_last"
+
+class GeneralPurpose(AbstractPurpose):
+ name = "Retain user data for 2 years"
+ slug = GENERAL_PURPOSE_SLUG
+ expiration_timedelta = relativedelta(years=2)
+ fields = "__ALL__" # Anonymize all fields defined in anonymizer
+
+class FirstAndLastNamePurpose(AbstractPurpose):
+ """Store First & Last name for 10 years."""
+ name = "retain due to internet archive"
+ slug = FIRST_AND_LAST_NAME_SLUG
+ expiration_timedelta = relativedelta(years=10)
+ fields = ("first_name", "last_name")
+```
+
+The field `fields` specify to which fields this consent applies to.
+
+Some more examples:
+```python
+fields = ("first_name", "last_name") # Anonymize only two fields
+
+# You can also add nested fields to anonymize fields on related objects.
+fields = (
+ "primary_email_address",
+ ("emails", (
+ "email",
+ )),
+)
+
+# Some more advanced configs may look like this:
+fields = (
+ "__ALL__",
+ ("addresses", "__ALL__"),
+ ("accounts", (
+ "__ALL__",
+ ("payments", (
+ "__ALL__",
+ ))
+ )),
+ ("emails", (
+ "email",
+ )),
+)
+
+```
+
+Now when we have the purpose(s) created we also have to make an _anonymizer_ so the library knows which fields to
+anonymize and how. This is fairly simple and is quite similar to Django forms.
+
+```python
+# app/anonymizers.py
+
+from gdpr import anonymizers
+from tests.models import Customer
+
+
+class CustomerAnonymizer(anonymizers.ModelAnonymizer):
+ first_name = anonymizers.MD5TextFieldAnonymizer()
+ last_name = anonymizers.MD5TextFieldAnonymizer()
+ primary_email_address = anonymizers.EmailFieldAnonymizer()
+
+ birth_date = anonymizers.DateFieldAnonymizer()
+ personal_id = anonymizers.PersonalIIDFieldAnonymizer()
+ phone_number = anonymizers.PhoneFieldAnonymizer()
+ fb_id = anonymizers.CharFieldAnonymizer()
+ last_login_ip = anonymizers.IPAddressFieldAnonymizer()
+
+ class Meta:
+ model = Customer
+```
+
+Now you can fully leverage the system:
+
+You can create/revoke consent:
+```python
+from gdpr.models import LegalReason
+
+from tests.models import Customer
+from tests.purposes import FIRST_AND_LAST_NAME_SLUG
+
+
+customer = Customer(first_name="John", last_name="Smith")
+customer.save()
+
+# Create consent
+LegalReason.objects.create_consent(FIRST_AND_LAST_NAME_SLUG, customer)
+
+# And now you can revoke it
+LegalReason.objects.deactivate_consent(FIRST_AND_LAST_NAME_SLUG, customer)
+```
+
+In case your model uses the `AnonymizationModelMixin` or `AnonymizationModel` you can create and revoke consents even
+easier.
+```python
+from tests.models import Customer
+from tests.purposes import FIRST_AND_LAST_NAME_SLUG
+
+
+customer = Customer(first_name="John", last_name="Smith")
+customer.save()
+
+# Create consent
+customer.create_consent(FIRST_AND_LAST_NAME_SLUG)
+
+# And now you can revoke it
+customer.deactivate_consent(FIRST_AND_LAST_NAME_SLUG)
+```
+
+
+Expired consents are revoked by running the following command. You should invoke it repeatedly, for example by cron.
+The invocation interval depends on your circumstances - how fast you want to expire consents after their revocation,
+the amount of consents to expire in the interval, server load, and last but not least, legal requirements.
+
+```python
+from gdpr.models import LegalReason
+
+LegalReason.objects.expire_old_consents()
+```
+
+## FieldAnonymizers
+
+* `FunctionAnonymizer` - in place lambda/function anonymization method (e.g. `secret_code = anonymizers.FunctionFieldAnonymizer(lambda x: x**2)`)
+* `DateFieldAnonymizer`
+* `CharFieldAnonymizer`
+* `DecimalFieldAnonymizer`
+* `IPAddressFieldAnonymizer`
+* `CzechAccountNumberFieldAnonymizer` - for czech bank account numbers
+* `IBANFieldAnonymizer`
+* `JSONFieldAnonymizer`
+* `EmailFieldAnonymizer`
+* `MD5TextFieldAnonymizer`
+* `SHA256TextFieldAnonymizer`
+* `HashTextFieldAnonymizer` - anonymization using given hash algorithm (e.g. `secret_code = anonymizers.HashTextFieldAnonymizer('sha512')`)
+* `StaticValueFieldAnonymizer` - anonymization by replacing with static value (e.g. `secret_code = anonymizers.StaticValueFieldAnonymizer(42)`)
+
+
+
+
+%prep
+%autosetup -n django-GDPR-0.2.23
+
+%build
+%py3_build
+
+%install
+%py3_install
+install -d -m755 %{buildroot}/%{_pkgdocdir}
+if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi
+if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi
+if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi
+if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi
+pushd %{buildroot}
+if [ -d usr/lib ]; then
+ find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/lib64 ]; then
+ find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/bin ]; then
+ find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/sbin ]; then
+ find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+touch doclist.lst
+if [ -d usr/share/man ]; then
+ find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst
+fi
+popd
+mv %{buildroot}/filelist.lst .
+mv %{buildroot}/doclist.lst .
+
+%files -n python3-django-GDPR -f filelist.lst
+%dir %{python3_sitelib}/*
+
+%files help -f doclist.lst
+%{_docdir}/*
+
+%changelog
+* Wed May 31 2023 Python_Bot <Python_Bot@openeuler.org> - 0.2.23-1
+- Package Spec generated
diff --git a/sources b/sources
new file mode 100644
index 0000000..a603225
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+f3afdcbab553e2db7be9feaef92a8557 django-GDPR-0.2.23.tar.gz