diff --git a/src/c3nav/settings.py b/src/c3nav/settings.py index 0b35f2dd..2a6280f6 100644 --- a/src/c3nav/settings.py +++ b/src/c3nav/settings.py @@ -185,6 +185,8 @@ CACHE_TILES = config.getboolean('c3nav', 'cache_tiles', fallback=not DEBUG) CACHE_PREVIEWS = config.getboolean('c3nav', 'cache_previews', fallback=not DEBUG) CACHE_RESOLUTION = config.getint('c3nav', 'cache_resolution', fallback=4) +COMPLIANCE_CHECKBOX = config.getboolean('c3nav', 'compliance_checkbox', fallback=False) + IMPRINT_LINK = config.get('c3nav', 'imprint_link', fallback=None) IMPRINT_PATRONS = config.get('c3nav', 'imprint_patrons', fallback=None) IMPRINT_TEAM = config.get('c3nav', 'imprint_team', fallback=None) diff --git a/src/c3nav/site/compliance.py b/src/c3nav/site/compliance.py new file mode 100644 index 00000000..b15d0b5c --- /dev/null +++ b/src/c3nav/site/compliance.py @@ -0,0 +1,44 @@ +import random + +from django.forms.fields import BooleanField +from django.utils.translation import gettext_lazy as _ + +from django.conf import settings + + +login_options = ( + _('I do not read fefe or i only read the sports section.'), + _('I am not affiliated with Automattic in any way, financially or otherwise.'), + _('I am not Anish Kapoor, i am in no way affiliated to Anish Kapoor, I am not signing in on behalf of ' + 'Anish Kapoor or an associate of Anish Kapoor. To the best of my knowledge, information and belief, this account ' + 'will not make its way into the hands of Anish Kapoor.'), + _('I do not use generative AI to create cheap assets for my talk slides.'), + _('I have not checked this checkbox.'), + _('I will not harm any human being, catgirl or similar creature nor through inaction permit any such creature ' + 'to be harmed.'), + _('I am not a robot or i am at least a cute one.'), + _('I am a robot.'), + _('Trans rights!'), + _('Be excellent to each other.'), + _('I acknowledge that any checkboxes shown under this form are optional, non-mandatory serving suggestions.'), + _('Chaos™ is a registered trademark of Chaos Computer Club Veranstaltungsgesellschaft mbH.'), + _('We and our %d partners value your privacy.'), +) + + +def get_random_checkbox_message() -> str: + msg: str = random.choice(login_options) + msg = msg.replace('%d', str(random.randint(1000, 3000))) + return msg + + +def add_compliance_checkbox(form): + if settings.COMPLIANCE_CHECKBOX: + form.fields["check"] = BooleanField(required=False, label=get_random_checkbox_message(), + help_text=_('If you do not like this checkbox, reload to get another one.')) + + +class ComplianceCheckboxFormMixin: + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + add_compliance_checkbox(self) \ No newline at end of file diff --git a/src/c3nav/site/forms.py b/src/c3nav/site/forms.py index 13cb032b..fc51eeb2 100644 --- a/src/c3nav/site/forms.py +++ b/src/c3nav/site/forms.py @@ -13,9 +13,10 @@ from c3nav.api.models import Secret from c3nav.mapdata.forms import I18nModelFormMixin from c3nav.mapdata.models.locations import Position, LocationGroup from c3nav.mapdata.models.report import Report, ReportUpdate +from c3nav.site.compliance import ComplianceCheckboxFormMixin -class ReportIssueForm(I18nModelFormMixin, ModelForm): +class ReportIssueForm(ComplianceCheckboxFormMixin, I18nModelFormMixin, ModelForm): class Meta: model = Report fields = ['title', 'description'] diff --git a/src/c3nav/site/views.py b/src/c3nav/site/views.py index 8f56dffa..b46983fb 100644 --- a/src/c3nav/site/views.py +++ b/src/c3nav/site/views.py @@ -1,5 +1,4 @@ import json -import random from itertools import chain from typing import Optional from urllib.parse import urlparse @@ -15,7 +14,6 @@ from django.core.exceptions import ObjectDoesNotExist, SuspiciousOperation, Vali from django.core.paginator import Paginator from django.core.serializers.json import DjangoJSONEncoder from django.db import transaction -from django.forms.fields import BooleanField from django.http import Http404, HttpResponse, HttpResponseBadRequest, QueryDict from django.middleware import csrf from django.shortcuts import get_object_or_404, redirect, render @@ -46,6 +44,7 @@ from c3nav.mapdata.utils.locations import (get_location_by_id_for_request, get_l from c3nav.mapdata.utils.user import can_access_editor, get_user_data from c3nav.mapdata.views import set_tile_access_cookie from c3nav.routing.models import RouteOptions +from c3nav.site.compliance import add_compliance_checkbox from c3nav.site.forms import APISecretForm, DeleteAccountForm, PositionForm, PositionSetForm, ReportUpdateForm from c3nav.site.models import Announcement, SiteUpdate @@ -293,31 +292,6 @@ def migrate_access_permissions_after_login(request): transaction.on_commit(lambda: cache.delete(AccessPermission.request_access_permission_key(request))) -login_options = ( - _('I do not read fefe or i only read the sports section.'), - _('I am not affiliated with Automattic in any way, financially or otherwise.'), - _('I am not Anish Kapoor, i am in no way affiliated to Anish Kapoor, I am not signing in on behalf of ' - 'Anish Kapoor or an associate of Anish Kapoor. To the best of my knowledge, information and belief, this account ' - 'will not make its way into the hands of Anish Kapoor.'), - _('I do not use generative AI to create cheap assets for my talk slides.'), - _('I have not checked this checkbox.'), - _('I will not harm any human being, catgirl or similar creature nor through inaction permit any such creature ' - 'to be harmed.'), - _('I am not a robot or i am at least a cute one.'), - _('I am a robot.'), - _('Trans rights!'), - _('Be excellent to each other.'), - _('I acknowledge that any checkboxes shown under this form are optional, non-mandatory serving suggestions.'), - _('Chaos™ is a registered trademark of Chaos Computer Club Veranstaltungsgesellschaft mbH.'), - _('We and our %d partners value your privacy.'), -) - -def get_random_checkbox_message() -> str: - msg: str = random.choice(login_options) - msg = msg.replace('%d', str(random.randint(1000, 3000))) - return msg - - @never_cache def login_view(request): if request.user.is_authenticated: @@ -332,8 +306,7 @@ def login_view(request): else: form = AuthenticationForm(request) - form.fields["check"] = BooleanField(required=False, label=get_random_checkbox_message(), - help_text=_('If you do not like this checkbox, reload to get another one.')) + add_compliance_checkbox(form) redirect_path = request.GET.get(REDIRECT_FIELD_NAME, '/account/') if referer := request.headers.get('Referer', None): @@ -387,6 +360,8 @@ def register_view(request): else: form = UserCreationForm() + add_compliance_checkbox(form) + form.fields['username'].max_length = 20 for field in form.fields.values(): field.help_text = None