force CGU/EULA approval on account creation

This commit is contained in:
imperosol
2026-09-16 09:59:23 +02:00
parent 246909376f
commit 8dbb472865
12 changed files with 79 additions and 63 deletions
@@ -0,0 +1,15 @@
# Generated by Django 5.2.17 on 2026-09-15 11:02
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [("core", "0050_alter_sithfile_moderator")]
operations = [
migrations.AddField(
model_name="user",
name="cgu_approved",
field=models.BooleanField(default=False, verbose_name="EULA approved"),
),
]
+1
View File
@@ -291,6 +291,7 @@ class User(AbstractUser):
),
blank=True,
)
cgu_approved = models.BooleanField(_("EULA approved"), default=False)
godfathers = models.ManyToManyField("User", related_name="godchildren", blank=True)
objects = CustomUserManager()
+7 -45
View File
@@ -49,67 +49,29 @@ body {
max-width: 500px;
margin-top: 20px;
>p,
>div {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
input[type="submit"] {
width: 100%;
max-width: 300px;
margin: 0;
>label {
width: 100%;
@media (min-width: 500px) {
width: 300px;
}
}
}
>input,
>p>input,
>div>input {
box-sizing: border-box;
width: 100%;
max-width: 500px;
@media (min-width: 500px) {
max-width: 300px;
}
}
>.errorlist {
.errorlist {
color: red;
text-align: center;
margin: 10px 0 0 0;
list-style-type: none;
}
>.required>.helptext {
text-align: center;
font-style: italic;
}
>.required:last-of-type {
box-sizing: border-box;
div, fieldset {
max-width: 300px;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
>label {
width: 100%;
}
}
.captcha {
box-sizing: border-box;
>img {
width: 70px;
object-fit: contain;
}
>input {
width: 200px;
}
}
}
}
+4 -5
View File
@@ -50,13 +50,12 @@
<input type="hidden" name="next" value="{{ next }}">
<input type="submit" value="{% trans %}Login{% endtrans %}">
{# Assumes you setup the password_reset view in your URLconf #}
<p>
<div>
<a href="{{ url('core:password_reset') }}">{% trans %}Lost password?{% endtrans %}</a>
&nbsp;&nbsp;
</div>
<div>
<a href="{{ url('core:register') }}">{% trans %}Create account{% endtrans %}</a>
</p>
</div>
</form>
{% endblock %}
+12 -2
View File
@@ -18,7 +18,17 @@
<form action="{{ url('core:register') }}" method="post">
{% csrf_token %}
{% render_honeypot_field %}
{{ form.as_p() }}
<input type="submit" value="{% trans %}Register{% endtrans %}" />
{% for field in form %}
{% if field.name not in ["cgu_approved", "captcha"] %}
<div>{{ field.as_field_group() }}</div>
{% endif %}
{% endfor %}
<div class="captcha">{{ form.captcha.as_field_group() }}</div>
<fieldset>
{{ form.cgu_approved.errors }}
{{ form.cgu_approved }}
{{ form.cgu_approved.label_tag() }}
</fieldset>
<input type="submit" class="btn btn-blue" value="{% trans %}Register{% endtrans %}" />
</form>
{% endblock %}
+2
View File
@@ -55,6 +55,7 @@ class TestUserRegistration:
"password2": "plop",
"captcha_0": "dummy-value",
"captcha_1": "PASSED",
"cgu_approved": True,
}
@pytest.fixture()
@@ -92,6 +93,7 @@ class TestUserRegistration:
({"first_name": ""}, "Ce champ est obligatoire."),
({"last_name": ""}, "Ce champ est obligatoire."),
({"captcha_1": "WRONG_CAPTCHA"}, "CAPTCHA invalide"),
({"cgu_approved": ""}, "Ce champ est obligatoire."),
],
)
def test_register_user_form_fail(
+19 -1
View File
@@ -42,6 +42,8 @@ from django.forms import (
TextInput,
Widget,
)
from django.urls import reverse
from django.utils.safestring import mark_safe
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _
from phonenumber_field.widgets import RegionalPhoneNumberWidget
@@ -146,9 +148,25 @@ class RegisteringForm(UserCreationForm):
class Meta:
model = User
fields = ("first_name", "last_name", "email")
fields = ("first_name", "last_name", "email", "cgu_approved")
field_classes = {"email": AntiSpamEmailField}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["cgu_approved"].required = True
self.fields["cgu_approved"].label_suffix = ""
self.fields["cgu_approved"].label = mark_safe(
_(
"I have read and I approve the "
'<a href="%(url)s" target="_blank">End User License Agreement</a>'
)
% {
"url": reverse(
"core:download", kwargs={"file_id": settings.SITH_CGU_FILE_ID}
)
}
)
class UserProfileForm(forms.ModelForm):
"""Form handling the user profile, managing the files"""