feat: add consent form for data processing

This commit is contained in:
James Graham
2021-01-20 11:53:08 +00:00
parent f2e945c67f
commit 6dc4bd770f
8 changed files with 99 additions and 6 deletions

15
breccia_mapper/forms.py Normal file
View File

@@ -0,0 +1,15 @@
from django import forms
from django.contrib.auth import get_user_model
User = get_user_model() # pylint: disable=invalid-name
class ConsentForm(forms.ModelForm):
"""Form used to collect user consent for data collection / processing."""
class Meta:
model = User
fields = ['consent_given']
labels = {
'consent_given':
'I have read and understood this information and consent to my data being used in this way',
}

View File

@@ -327,7 +327,7 @@ LOGGING = {
LOGGING_CONFIG = None
logging.config.dictConfig(LOGGING)
logger = logging.getLogger(__name__)
logger = logging.getLogger(__name__) # pylint: disable=invalid-name
# Admin panel variables
@@ -337,10 +337,17 @@ CONSTANCE_CONFIG = collections.OrderedDict([
'Text to be displayed in a notice banner at the top of every page.')),
('NOTICE_CLASS', ('alert-warning',
'CSS class to use for background of notice banner.')),
('CONSENT_TEXT',
('This is template consent text and should have been replaced. Please contact an admin.',
'Text to be displayed to ask for consent for data collection.'))
])
CONSTANCE_CONFIG_FIELDSETS = {
'Notice Banner': ('NOTICE_TEXT', 'NOTICE_CLASS'),
'Notice Banner': (
'NOTICE_TEXT',
'NOTICE_CLASS',
),
'Data Collection': ('CONSENT_TEXT', ),
}
CONSTANCE_BACKEND = 'constance.backends.database.DatabaseBackend'
@@ -379,12 +386,10 @@ else:
default=(EMAIL_PORT == 465),
cast=bool)
# Upstream API keys
GOOGLE_MAPS_API_KEY = config('GOOGLE_MAPS_API_KEY', default=None)
# Import customisation app settings if present
try:

View File

@@ -156,6 +156,15 @@
</div>
{% endif %}
{% if request.user.is_authenticated and not request.user.consent_given %}
<div class="alert alert-warning rounded-0" role="alert">
<p class="text-center mb-0">
You have not yet given consent for your data to be collected and processed.
Please read and accept the <a href="{% url 'consent' %}">consent text</a>.
</p>
</div>
{% endif %}
{% block before_content %}{% endblock %}
<main class="container">

View File

@@ -0,0 +1,21 @@
{% extends 'base.html' %}
{% block content %}
<h2>Consent</h2>
<p>
{{ config.CONSENT_TEXT|linebreaks }}
</p>
<form class="form"
method="POST">
{% csrf_token %}
{% load bootstrap4 %}
{% bootstrap_form form %}
{% buttons %}
<button class="btn btn-success" type="submit">Submit</button>
{% endbuttons %}
</form>
{% endblock %}

View File

@@ -32,6 +32,10 @@ urlpatterns = [
views.IndexView.as_view(),
name='index'),
path('consent',
views.ConsentTextView.as_view(),
name='consent'),
path('',
include('export.urls')),

View File

@@ -1,13 +1,31 @@
"""
Views belonging to the core of the project.
"""Views belonging to the core of the project.
These views don't represent any of the models in the apps.
"""
from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy
from django.views.generic import TemplateView
from django.views.generic.edit import UpdateView
from . import forms
User = get_user_model() # pylint: disable=invalid-name
class IndexView(TemplateView):
# Template set in Django settings file - may be customised by a customisation app
template_name = settings.TEMPLATE_NAME_INDEX
class ConsentTextView(LoginRequiredMixin, UpdateView):
"""View with consent text and form for users to indicate consent."""
model = User
form_class = forms.ConsentForm
template_name = 'consent.html'
success_url = reverse_lazy('index')
def get_object(self, *args, **kwargs) -> User:
return self.request.user

View File

@@ -0,0 +1,18 @@
# Generated by Django 2.2.10 on 2021-01-20 11:25
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('people', '0029_organisation_location_fields'),
]
operations = [
migrations.AddField(
model_name='user',
name='consent_given',
field=models.BooleanField(default=False),
),
]

View File

@@ -32,6 +32,9 @@ class User(AbstractUser):
"""
email = models.EmailField(_('email address'), blank=False, null=False)
#: Have they given consent to collect and store their data?
consent_given = models.BooleanField(default=False)
def has_person(self) -> bool:
"""
Does this user have a linked :class:`Person` record?