mirror of
https://github.com/Southampton-RSG/breccia-mapper.git
synced 2026-03-03 03:17:07 +00:00
feat: add consent form for data processing
This commit is contained in:
15
breccia_mapper/forms.py
Normal file
15
breccia_mapper/forms.py
Normal 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',
|
||||||
|
}
|
||||||
@@ -327,7 +327,7 @@ LOGGING = {
|
|||||||
|
|
||||||
LOGGING_CONFIG = None
|
LOGGING_CONFIG = None
|
||||||
logging.config.dictConfig(LOGGING)
|
logging.config.dictConfig(LOGGING)
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__) # pylint: disable=invalid-name
|
||||||
|
|
||||||
# Admin panel variables
|
# 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.')),
|
'Text to be displayed in a notice banner at the top of every page.')),
|
||||||
('NOTICE_CLASS', ('alert-warning',
|
('NOTICE_CLASS', ('alert-warning',
|
||||||
'CSS class to use for background of notice banner.')),
|
'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 = {
|
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'
|
CONSTANCE_BACKEND = 'constance.backends.database.DatabaseBackend'
|
||||||
@@ -379,12 +386,10 @@ else:
|
|||||||
default=(EMAIL_PORT == 465),
|
default=(EMAIL_PORT == 465),
|
||||||
cast=bool)
|
cast=bool)
|
||||||
|
|
||||||
|
|
||||||
# Upstream API keys
|
# Upstream API keys
|
||||||
|
|
||||||
GOOGLE_MAPS_API_KEY = config('GOOGLE_MAPS_API_KEY', default=None)
|
GOOGLE_MAPS_API_KEY = config('GOOGLE_MAPS_API_KEY', default=None)
|
||||||
|
|
||||||
|
|
||||||
# Import customisation app settings if present
|
# Import customisation app settings if present
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -156,6 +156,15 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% 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 %}
|
{% block before_content %}{% endblock %}
|
||||||
|
|
||||||
<main class="container">
|
<main class="container">
|
||||||
|
|||||||
21
breccia_mapper/templates/consent.html
Normal file
21
breccia_mapper/templates/consent.html
Normal 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 %}
|
||||||
@@ -32,6 +32,10 @@ urlpatterns = [
|
|||||||
views.IndexView.as_view(),
|
views.IndexView.as_view(),
|
||||||
name='index'),
|
name='index'),
|
||||||
|
|
||||||
|
path('consent',
|
||||||
|
views.ConsentTextView.as_view(),
|
||||||
|
name='consent'),
|
||||||
|
|
||||||
path('',
|
path('',
|
||||||
include('export.urls')),
|
include('export.urls')),
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
These views don't represent any of the models in the apps.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.conf import settings
|
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 import TemplateView
|
||||||
|
from django.views.generic.edit import UpdateView
|
||||||
|
|
||||||
|
from . import forms
|
||||||
|
|
||||||
|
User = get_user_model() # pylint: disable=invalid-name
|
||||||
|
|
||||||
|
|
||||||
class IndexView(TemplateView):
|
class IndexView(TemplateView):
|
||||||
# Template set in Django settings file - may be customised by a customisation app
|
# Template set in Django settings file - may be customised by a customisation app
|
||||||
template_name = settings.TEMPLATE_NAME_INDEX
|
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
|
||||||
|
|||||||
18
people/migrations/0030_user_consent_given.py
Normal file
18
people/migrations/0030_user_consent_given.py
Normal 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),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -32,6 +32,9 @@ class User(AbstractUser):
|
|||||||
"""
|
"""
|
||||||
email = models.EmailField(_('email address'), blank=False, null=False)
|
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:
|
def has_person(self) -> bool:
|
||||||
"""
|
"""
|
||||||
Does this user have a linked :class:`Person` record?
|
Does this user have a linked :class:`Person` record?
|
||||||
|
|||||||
Reference in New Issue
Block a user