Add a new module for better ensuring privacy of user data.
Review Request #9893 — Created April 25, 2018 and submitted
This introduces
djblets.privacy
, a new module designed for more easily
ensuring protection of private user data, helping Django applications to
meet GDPR compliance and to otherwise help with the management and
safe-keeping of user data.This initial version of the module focuses on consent tracking, giving
users control over operations or processing of data. It's designed to
allow applications (and even extensions) to dynamically register things
that require consent, to check if the user granted/denied that consent,
to (later) present options for consent, and to keep an audit log for
later proof. For now, only the backend is in place, with UI helpers
coming later.This lives almost exclusively within the
djblets.privacy.consent
module (with models living indjblets.privacy.models
). There are a few
components:
-
Consent
: An enum containing values to represent whether
consent was given or denied, or simply not set yet. -
ConsentRequirement
: Represents a part of a product that requires
consent. This can be instantiated with a unique ID, displayable name
and description, and an optional URL for learning more about the
requirement (useful for linking to privacy policies or documentation). -
ConsentRequirementsRegistry
: Used to register, track, and look up
ConsentRequirement
instances. -
ConsentData
: An object for store consent and consent-related
information (timestamp, source of where the consent was given, and
additional data to include), for serializing or deserializing. -
BaseConsentTracker
/DatabaseConsentTracker
: Used to record if
consent was given or denied for a requirement, check that consent on
demand, and for keeping an audit log for helping to later document and
prove when users set, denied, or revoked consent. By default,
DatabaseConsentTracker
(which stores the data in the database) is
used, but projects can make use of custom ones for storing the audit
data in other locations outside the database.
With this module, it will be very easy to start enforcing user control
of the processing of data without a lot of additional work.
Future changes will build on this to offer standard UI for consent
management and redacting of personal information before sending to
services.
Unit tests pass.
Built the docs and checked for build and generation errors.
Description | From | Last Updated |
---|---|---|
E501 line too long (80 > 79 characters) |
reviewbot | |
F401 'datetime.datetime' imported but unused |
reviewbot | |
F401 'django.contrib.auth.models.User' imported but unused |
reviewbot | |
F401 'django.test.utils.override_settings' imported but unused |
reviewbot | |
F401 'django.utils.timezone' imported but unused |
reviewbot | |
F401 'kgb.SpyAgency' imported but unused |
reviewbot | |
F401 'djblets.privacy.consent.Consent' imported but unused |
reviewbot | |
F401 'djblets.privacy.consent.BaseConsentTracker' imported but unused |
reviewbot | |
F401 'djblets.privacy.consent.ConsentData' imported but unused |
reviewbot | |
F401 'djblets.privacy.consent.errors.ConsentRequirementNotFoundError' imported but unused |
reviewbot | |
F401 'djblets.registries.errors.RegistrationError' imported but unused |
reviewbot | |
On Python2, UNSET will literally be 0, but using enum, it will be a Consent object with a value attribute … |
brennie | |
Instead of doing this pattern (which I know I started), should we do the following? CONSENT_REQUIREMENT_DEFAULT_ERRORS = dict(DEFAULT_ERRORS, **{ 'key': … |
brennie | |
Is it cool that we use PII here? Should this be hash(email)? |
brennie | |
Needs a module docstring. |
david | |
Let's say "EU" residents instead of "European" |
david |
- Change Summary:
-
- Fixed a line length issue.
- Removed unused imports.
- Commit:
-
3158ef09187aaf9e46a240c5dd13def116bdd4872fffbd9b800829829715e3e16db4f3f93af45fb3
- Diff:
-
Revision 2 (+1090)
Checks run (2 succeeded)
-
-
On Python2,
UNSET
will literally be 0, but usingenum
, it will be aConsent
object with avalue
attribute = 0.Is this difference in behaviour going to cause issues?
enum.Enum
also provides default__str__
etc impls, which this will lack. -
Instead of doing this pattern (which I know I started), should we do the following?
CONSENT_REQUIREMENT_DEFAULT_ERRORS = dict(DEFAULT_ERRORS, **{ 'key': 'value', })
Also, should we just have this defined on the class (as
default_errors
)? -
- Change Summary:
-
- Switched to inline error definitions for the registry.
- Switched audit identification storage to use a SHA256 hash of an e-mail address.
- Removed the "memo" field for consent data and switched to allow JSON-serializable data instead.
- Commit:
-
2fffbd9b800829829715e3e16db4f3f93af45fb33f034ef971aceec1a2f402abecad3e4fa558a719
- Diff:
-
Revision 3 (+1122)
Checks run (2 succeeded)
- Change Summary:
-
- Added a missing module docstring.
- Added a guide on using this module. This will be expanded as new changes are up for review.
- Commit:
-
3f034ef971aceec1a2f402abecad3e4fa558a719652836a1734b442a5b6ed48ce103f7d7defd221e
- Diff:
-
Revision 4 (+1304)
Checks run (2 succeeded)
- Change Summary:
-
Added a glossary term for GDPR, and referenced that.
- Commit:
-
652836a1734b442a5b6ed48ce103f7d7defd221ee04b09ac2e76deeef08c80c1965324dbef1a6df2
- Diff:
-
Revision 5 (+1309)
Checks run (2 succeeded)
- Change Summary:
-
- Split "description" into "intent_description" and "data_use_description".
- Added support for data processor icons.
- Updated docs and unit tests appropriately.
- Commit:
-
e04b09ac2e76deeef08c80c1965324dbef1a6df20f5c4fa83225fc660c0026a3d67224c7a0440366
- Diff:
-
Revision 6 (+1342)