Compare commits

...

4 commits

6 changed files with 169 additions and 53 deletions

1
.gitignore vendored
View file

@ -9,3 +9,4 @@ __pycache__/
!.static/.gitkeep
src/shared/static/bulma/bulma.css
src/shared/static/bulma/bulma.css.map
.credentials/KANIDM_AUTH_TOKEN

View file

@ -26,11 +26,19 @@ class CreateKanidmAccountForm(forms.Form):
displayname = CharField(label=_("Nom d'usage"))
mail = EmailField(
label=_("Adresse e-mail"),
help_text=_("De préférence l'adresse '@ens.psl.eu' (si en scola) ou '@normalesup.org' (si archikhûbe), sauf si exté (accord explicite du bureau nécessaire)."),
help_text=_(
"De préférence :<br>"
"- l'adresse <code>@ens.psl.eu</code> pour les personnes en scolarité ;<br>"
"- l'adresse <code>@normalesup.org</code> pour les personnes ayant fini leur scolarité ;<br>"
"<b>Pour les personnes extérieures, le bureau doit donner son accord.</b>"
),
)
active = BooleanField(
label=_("Membre actif"),
help_text=_("Si selectionné, la personne sera ajoutée au groupe dgnum_members. L'accord du bureau est nécessaire pour cette opération donnant des privilèges."),
help_text=_(
"Si selectionné, la personne sera ajoutée au groupe <code>dgnum_members</code>.<br>"
"<b>L'accord préalable du bureau est nécessaire !</b>"
),
required=False,
)

View file

@ -0,0 +1,25 @@
# Generated by Django 4.2.16 on 2024-10-12 20:04
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("dgsi", "0007_alter_user_accepted_bylaws_and_more"),
]
operations = [
migrations.AlterField(
model_name="user",
name="accepted_statutes",
field=models.ForeignKey(
default=None,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
to="dgsi.statutes",
verbose_name="Derniers Statuts acceptés",
),
),
]

View file

@ -3,6 +3,7 @@ from dataclasses import dataclass
from functools import cached_property
from typing import Optional, Self
from aiohttp.client_exceptions import ClientConnectorError
from allauth.socialaccount.models import SocialAccount
from asgiref.sync import async_to_sync
from django.contrib.auth.models import AbstractUser
@ -13,7 +14,6 @@ from django.http import HttpRequest
from django.utils.translation import gettext_lazy as _
from kanidm.exceptions import NoMatchingEntries
from kanidm.models.person import Person
from kanidm.radius import ClientConnectorError
from shared.kanidm import klient
@ -145,7 +145,7 @@ class User(AbstractUser):
on_delete=models.SET_NULL,
null=True,
default=None,
verbose_name=_("Derniers statuts acceptés"),
verbose_name=_("Derniers Statuts acceptés"),
)
accepted_bylaws = models.ForeignKey(
Bylaws,

View file

@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: dgsi.dgnum.eu\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-09-26 22:48+0200\n"
"PO-Revision-Date: 2024-09-26 22:49+0200\n"
"POT-Creation-Date: 2024-10-12 21:59+0200\n"
"PO-Revision-Date: 2024-10-12 22:04+0200\n"
"Last-Translator: Tom Hubrecht <tom.hubrecht@dgnum.eu>\n"
"Language-Team: French\n"
"Language: fr\n"
@ -18,10 +18,14 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n > 1)\n"
"X-Generator: Gtranslator 46.1\n"
#: app/settings.py:276
#: app/settings.py:321
msgid "Administration de DGSI"
msgstr "DGSI Administration"
#: dgsi/admin.py:51
msgid "Documents DGNum"
msgstr "DGNum Documents"
#: dgsi/forms.py:16
msgid "Identifiant déjà présent dans la base de données."
msgstr "Username already in the database."
@ -31,74 +35,97 @@ msgid "Identifiant"
msgstr "Username"
#: dgsi/forms.py:23
msgid "De préférence identique au login ENS de la personne concernée"
msgstr "Preferably identical to the ENS login of the person concerned"
msgid "De préférence identique au login ENS de la personne concernée."
msgstr "Preferably identical to the ENS login of the person concerned."
#: dgsi/forms.py:26 dgsi/forms.py:39
#: dgsi/forms.py:26 dgsi/forms.py:47
msgid "Nom d'usage"
msgstr "Name in use"
#: dgsi/forms.py:28 dgsi/forms.py:41
#: dgsi/forms.py:28 dgsi/forms.py:49
msgid "Adresse e-mail"
msgstr "E-mail address"
#: dgsi/forms.py:29 dgsi/forms.py:42
msgid "De préférence l'adresse '@ens.psl.eu'"
msgstr "Preferably the @ens.psl.eu address"
#: dgsi/forms.py:30
msgid ""
"De préférence :<br>- l'adresse <code>@ens.psl.eu</code> pour les personnes "
"en scolarité ;<br>- l'adresse <code>@normalesup.org</code> pour les "
"personnes ayant fini leur scolarité ;<br><b>Pour les personnes extérieures, "
"le bureau doit donner son accord.</b>"
msgstr ""
"Preferably:<br>- the <code>@ens.psl.eu</code> address for students;<br>- the "
"<code>@normalesup.org</code> address for people having finished their "
"studies;<br><b>For outsiders, the board must give its approval.</b>"
#: dgsi/forms.py:32
#: dgsi/forms.py:37
msgid "Membre actif"
msgstr "Active member"
#: dgsi/forms.py:33
msgid "Si selectionné, la personne sera ajoutée au groupe dgnum_members"
msgstr "If selected, the person will be added to the dgnum_members group."
#: dgsi/forms.py:39
msgid ""
"Si selectionné, la personne sera ajoutée au groupe <code>dgnum_members</"
"code>.<br><b>L'accord préalable du bureau est nécessaire !</b>"
msgstr ""
"If selected, the person will be added to the <code>dgnum_members</code> "
"group.<br><b>Prior approval from the board is required!</b>"
#: dgsi/models.py:22
#: dgsi/forms.py:50
msgid "De préférence l'adresse '@ens.psl.eu'"
msgstr "Preferably the @ens.psl.eu address"
#: dgsi/models.py:24
msgid "Nom du service proposé"
msgstr "Name of the proposed service"
#: dgsi/models.py:23
#: dgsi/models.py:25
msgid "Adresse du service"
msgstr "Address of the service"
#: dgsi/models.py:24
#: dgsi/models.py:26
msgid "Icône du service"
msgstr "Icon of the service"
#: dgsi/models.py:34
#: dgsi/models.py:36
msgid "Date du document"
msgstr "Document date"
#: dgsi/models.py:35
#: dgsi/models.py:37
msgid "Nom du document"
msgstr "Document name"
#: dgsi/models.py:36
#: dgsi/models.py:38
msgid "Fichier PDF"
msgstr "PDF file"
#: dgsi/models.py:58 dgsi/models.py:59
#: dgsi/models.py:60 dgsi/models.py:61
#: dgsi/templates/dgsi/legal_documents.html:26
msgid "Statuts"
msgstr "Statutes"
#: dgsi/models.py:71 dgsi/templates/dgsi/legal_documents.html:30
#: dgsi/models.py:73 dgsi/templates/dgsi/legal_documents.html:30
msgid "Règlement Intérieur"
msgstr "Bylaws"
#: dgsi/models.py:72
#: dgsi/models.py:74
msgid "Règlements Intérieurs"
msgstr "Bylaws"
#: dgsi/models.py:114
#: dgsi/models.py:116
msgid "Correspondance de login"
msgstr "Login mapping"
#: dgsi/models.py:115
#: dgsi/models.py:117
msgid "Correspondances de login"
msgstr "Login mappings"
#: dgsi/models.py:148
msgid "Derniers Statuts acceptés"
msgstr "Latest accepted Statutes"
#: dgsi/models.py:155
msgid "Dernier Règlement Intérieur accepté"
msgstr "Latest accepted Bylaws"
#: dgsi/templates/_legal_document.html:9
msgid ""
" En acceptant, vous assurez avoir lu ce document et en approuver le contenu."
@ -154,31 +181,43 @@ msgstr "Accept the bylaws"
msgid "Profil de %(displayname)s"
msgstr "Profile of %(displayname)s"
#: dgsi/templates/dgsi/profile.html:13
#: dgsi/templates/dgsi/profile.html:14
msgid "Mot de passe WiFi :"
msgstr "WiFi password:"
#: dgsi/templates/dgsi/profile.html:23
#: dgsi/templates/dgsi/profile.html:16
msgid "Êtes-vous sûr·e de vouloir réinitialiser votre mot de passe WiFi ?"
msgstr "Are you sure that you want to reset your WiFi password?"
#: dgsi/templates/dgsi/profile.html:19
msgid "Réinitialiser le mot de passe WiFi"
msgstr "Reset the WiFi password"
#: dgsi/templates/dgsi/profile.html:32
msgid "Générer un mot de passe WiFi"
msgstr "Generate a WiFi password:"
#: dgsi/templates/dgsi/profile.html:36
msgid "Adresse e-mail :"
msgstr "E-mail address:"
#: dgsi/templates/dgsi/profile.html:28
#: dgsi/templates/dgsi/profile.html:41
msgid "Informations techniques"
msgstr "Technical informations"
#: dgsi/templates/dgsi/profile.html:31
#: dgsi/templates/dgsi/profile.html:44
msgid "Identifiant unique :"
msgstr "Unique identifier:"
#: dgsi/templates/dgsi/profile.html:40
#: dgsi/templates/dgsi/profile.html:53
msgid "Membre des groupes suivants :"
msgstr "Member of the following groups:"
#: dgsi/templates/dgsi/profile.html:51
#: dgsi/templates/dgsi/profile.html:64
msgid "Pas de compte DGNum répertorié."
msgstr "No DGNum account found."
#: dgsi/templates/dgsi/profile.html:54
#: dgsi/templates/dgsi/profile.html:67
msgid "Créer un compte DGNum"
msgstr "Create a DGNum account"
@ -194,45 +233,49 @@ msgstr "My profile"
msgid "Documents Légaux"
msgstr "Legal Documents"
#: dgsi/views.py:35
msgid "Services proposés par la DGNum"
msgstr "Services offered by the DGNum"
#: dgsi/views.py:32
msgid "Services proposés"
msgstr "Services offered"
#: dgsi/views.py:44
msgid "Créer un nouveau compte Kanidm"
msgstr "Create a new Kanidm account"
#: dgsi/views.py:39
msgid "Créer un compte Kanidm"
msgstr "Create a Kanidm account"
#: dgsi/views.py:48
#: dgsi/views.py:43 shared/templates/_hero.html:76
msgid "Interface d'administration"
msgstr "Administration interface"
#: dgsi/views.py:83
#: dgsi/views.py:80
msgid "Compte DGNum inexistant."
msgstr "No existing DGNum account."
#: dgsi/views.py:97
msgid "Compte DGNum créé avec succès"
msgstr "DGNum account successfully created"
#: dgsi/views.py:99
#: dgsi/views.py:113
msgid "<b>Vous possédez déjà un compte DGNum !</b>"
msgstr "<b>You already have a DGNum account!</b>"
#: dgsi/views.py:111
#: dgsi/views.py:125
msgid "Vous devez accepter les Statuts et le Règlement Intérieur."
msgstr "You must accept the Statutes and the Bylaws."
#: dgsi/views.py:190
#: dgsi/views.py:204
#, python-format
msgid "Type de document invalide : %(kind)s"
msgstr "Invalid document type: %(kind)s"
#: dgsi/views.py:220
#: dgsi/views.py:234
#, python-format
msgid "Compte DGNum pour %(displayname)s [%(name)s] créé."
msgstr "DGNum account for %(displayname)s [%(name)s] created."
#: shared/account.py:37
#: shared/account.py:40
msgid "Catégorie de compte ENS interdite."
msgstr "ENS account category not permitted."
#: shared/account.py:53
#: shared/account.py:57
msgid "Méthode de connexion invalide."
msgstr "Invalid connection method."
@ -242,18 +285,30 @@ msgid ""
msgstr ""
"Software developed for and by the <a href=https://dgnum.eu>DGNum</a>."
#: shared/templates/_hero.html:18
#: shared/templates/_hero.html:18 shared/templates/account/logout.html:6
msgid "Déconnexion"
msgstr "Logout"
#: shared/templates/_hero.html:27
#: shared/templates/_hero.html:27 shared/templates/socialaccount/login.html:6
msgid "Connexion"
msgstr "Login"
#: shared/templates/_hero.html:41
#: shared/templates/_hero.html:40
msgid "Choix de la langue"
msgstr "Language selection"
#: shared/templates/account/login.html:7
msgid "Connexion via un compte tiers"
msgstr "Connection via a third-party account"
#: shared/templates/account/logout.html:10
msgid "Êtes vous certain·e de vouloir vous déconnecter ?"
msgstr "Are you sure you want to log out?"
#: shared/templates/account/logout.html:16
msgid "Se déconnecter"
msgstr "Log out"
#: shared/templates/accounts/forbidden_category.html:6
msgid "Connexion impossible"
msgstr "Unable to connect"
@ -267,3 +322,30 @@ msgstr ""
"Your details do not allow the DGNum to authenticate you.<br>If you think "
"this is a mistake, please contact us at: <a href=\"mailto:contact@dgnum."
"eu\">contact@dgnum.eu</a>"
#: shared/templates/socialaccount/authentication_error.html:7
msgid "Erreur lors de la connexion"
msgstr "Error during login"
#: shared/templates/socialaccount/authentication_error.html:11
msgid ""
"Une erreur est survenue lors de votre tentative de connexion avec un compte "
"tiers."
msgstr ""
"An error has occurred while trying to login with a third-party account."
#: shared/templates/socialaccount/login.html:11
#, python-format
msgid "Se connecter via un compte <b>%(provider)s</b>"
msgstr "Log in with a <b>%(provider)s</b> account"
#: shared/templates/socialaccount/login.html:16
#, python-format
msgid ""
"Vous vous apprêtez à vous connecter à l'aide d'un compte tiers provenant de "
"%(provider)s."
msgstr "You are about to log in using a third-party account from %(provider)s."
#: shared/templates/socialaccount/login.html:21
msgid "Continuer"
msgstr "Continue"