Skip to content

Commit

Permalink
feat(accounts,ToU): disable revocation and rename to accept
Browse files Browse the repository at this point in the history
Signed-off-by: David Wallace <[email protected]>
  • Loading branch information
MyPyDavid committed Feb 3, 2025
1 parent 0d694f7 commit e52f940
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 67 deletions.
29 changes: 14 additions & 15 deletions rdmo/accounts/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ class UpdateConsentForm(forms.Form):

consent = forms.BooleanField(
label="I agree to the terms of use",
required=False, # not required because it won't be submitted during a delete
required=True,
)

def __init__(self, *args, user=None, **kwargs):
Expand All @@ -104,20 +104,19 @@ def __init__(self, *args, user=None, **kwargs):
raise ValueError("A user instance is required to initialize the form.")

# pre-fill the 'consent' field based on the user's existing consent
self.fields["consent"].initial = ConsentFieldValue.objects.filter(
user=self.user
).exists()
# Ensure the user cannot uncheck the consent
has_consented = ConsentFieldValue.objects.filter(user=self.user).exists()
if has_consented:
self.fields["consent"].disabled = True # Disable field after acceptance
self.fields["consent"].initial = True
else:
self.fields["consent"].initial = False

def save(self) -> bool:
if not ConsentFieldValue.objects.filter(user=self.user).exists():
if self.cleaned_data.get("consent"):
ConsentFieldValue.objects.create(user=self.user, consent=True)
# session consent is updated in the view
return True # consent accepted

if "delete" in self.data:
ConsentFieldValue.objects.filter(user=self.user).delete()
return False # consent was revoked

if self.cleaned_data.get("consent"):
ConsentFieldValue.objects.update_or_create(
user=self.user, defaults={"consent": True}
)
return True # consent was accepted

return False
return False # No changes made
11 changes: 3 additions & 8 deletions rdmo/accounts/middleware.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
"""Terms and Conditions Middleware"""
# ref: https://github.com/cyface/django-termsandconditions/blob/main/termsandconditions/middleware.py
import logging

from django.conf import settings
from django.http import HttpResponseRedirect
from django.urls import reverse

from .utils import user_has_accepted_terms

LOGGER = logging.getLogger(__name__)

ACCEPT_TERMS_PATH = getattr(settings, "ACCEPT_TERMS_PATH", reverse("terms_of_use_update"))
TERMS_EXCLUDE_URL_PREFIX_LIST = getattr(
settings,
"TERMS_EXCLUDE_URL_PREFIX_LIST",
Expand All @@ -36,12 +32,14 @@ def __call__(self, request):
return self.get_response(request)

# check if the current path is protected
accept_terms_path = reverse("terms_of_use_accept")
if (
request.user.is_authenticated
and not request.path.startswith(accept_terms_path)
and self.is_path_protected(request.path)
and not user_has_accepted_terms(request.user, request.session)
):
return HttpResponseRedirect(ACCEPT_TERMS_PATH)
return HttpResponseRedirect(accept_terms_path)

# Proceed with the response for non-protected paths or accepted terms
return self.get_response(request)
Expand All @@ -66,7 +64,4 @@ def is_path_protected(path):
if path in TERMS_EXCLUDE_URL_LIST:
return False

if path.startswith(ACCEPT_TERMS_PATH):
return False

return True
38 changes: 38 additions & 0 deletions rdmo/accounts/templates/account/terms_of_use_accept_form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{% extends 'core/page.html' %}
{% load i18n %}

{% block page %}

<h2>{% trans 'Terms of use' %}</h2>

<p>
{% get_current_language as lang %}
{% if lang == 'en' %}
{% include 'account/terms_of_use_en.html' %}
{% elif lang == 'de' %}
{% include 'account/terms_of_use_de.html' %}
{% endif %}
</p>

<div>
{% if not has_consented %}
<form method="post">
{% csrf_token %}
<div class="form-group">
<label>
<input type="checkbox" name="consent" required>
{% trans "I agree to the terms of use." %}
</label>
</div>
<button type="submit" class="btn btn-primary terms-of-use-accept">
{% trans "I accept" %}
</button>
</form>
{% else %}
<p>
{% trans "You have accepted the terms of use." %}
</p>
{% endif %}
</div>

{% endblock %}
33 changes: 0 additions & 33 deletions rdmo/accounts/templates/account/terms_of_use_update_form.html

This file was deleted.

6 changes: 3 additions & 3 deletions rdmo/accounts/urls/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
shibboleth_login,
shibboleth_logout,
terms_of_use,
terms_of_use_update,
terms_of_use_accept,
token,
)

Expand All @@ -18,10 +18,10 @@
re_path('^remove', remove_user, name='profile_remove'),
]

if settings.ACCOUNT_TERMS_OF_USE is True:
if settings.ACCOUNT_TERMS_OF_USE:
urlpatterns += [
re_path('^terms-of-use/accept/$', terms_of_use_accept, name='terms_of_use_accept'),
re_path('^terms-of-use/$', terms_of_use, name='terms_of_use'),
re_path('^terms-of-use/update/$', terms_of_use_update, name='terms_of_use_update'),
]

if settings.SHIBBOLETH:
Expand Down
13 changes: 5 additions & 8 deletions rdmo/accounts/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def shibboleth_logout(request):
return HttpResponseRedirect(logout_url)


def terms_of_use_update(request):
def terms_of_use_accept(request):

if not request.user.is_authenticated:
return redirect("account_login")
Expand All @@ -121,19 +121,16 @@ def terms_of_use_update(request):
# Use the form to handle both update and delete actions
form = UpdateConsentForm(request.POST, user=request.user)
if form.is_valid():
consent_status = form.save()
request.session[CONSENT_SESSION_KEY] = consent_status
# Update the session to reflect the new consent status
# update the session to reflect the new consent status
request.session[CONSENT_SESSION_KEY] = form.save()
return redirect("home")

elif request.method == "GET":
# Render the consent update form
form = UpdateConsentForm(user=request.user)
has_consented = ConsentFieldValue.objects.filter(user=request.user).exists()
return render(
request,
"account/terms_of_use_update_form.html",
{"form": form, "has_consented": has_consented},
"account/terms_of_use_accept_form.html",
{"has_consented": has_consented},
)

return HttpResponseNotAllowed(["GET", "POST"])

0 comments on commit e52f940

Please sign in to comment.