From e9f18c3ed9956bec07d6b71e391f7e275534663b Mon Sep 17 00:00:00 2001 From: bleizi Date: Wed, 24 Jan 2024 19:18:02 +0100 Subject: [PATCH 01/33] migrate to django 4.2 (LTS), change requirement and tests. remove depreciated ifnotequal --- .gitlab-ci.yml | 34 +++++++++--------- apps/note/templates/note/amount_input.html | 2 +- note_kfet/templates/autocomplete_model.html | 2 +- requirements.txt | 38 ++++++++++----------- tox.ini | 6 ++-- 5 files changed, 42 insertions(+), 40 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 97110ecd..98fbac88 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,21 +7,6 @@ stages: variables: GIT_SUBMODULE_STRATEGY: recursive -# Debian Buster -py37-django22: - stage: test - image: debian:buster-backports - before_script: - - > - apt-get update && - apt-get install --no-install-recommends -t buster-backports -y - python3-django python3-django-crispy-forms - python3-django-extensions python3-django-filters python3-django-polymorphic - python3-djangorestframework python3-django-oauth-toolkit python3-psycopg2 python3-pil - python3-babel python3-lockfile python3-pip python3-phonenumbers python3-memcache - python3-bs4 python3-setuptools tox texlive-xetex - script: tox -e py37-django22 - # Ubuntu 20.04 py38-django22: stage: test @@ -54,9 +39,26 @@ py39-django22: python3-bs4 python3-setuptools tox texlive-xetex script: tox -e py39-django22 +# Debian Bookworm +py311-django42: + stage: test + image: debian:bookworm + before_script: + - > + apt-get update && + apt-get install --no-install-recommends -y + python3-django python3-django-crispy-forms + python3-django-extensions python3-django-filters python3-django-polymorphic + python3-djangorestframework python3-django-oauth-toolkit python3-psycopg2 python3-pil + python3-babel python3-lockfile python3-pip python3-phonenumbers python3-memcache + python3-bs4 python3-setuptools tox texlive-xetex + script: tox -e py311-django42 + + + linters: stage: quality-assurance - image: debian:buster-backports + image: debian:bookworm before_script: - apt-get update && apt-get install -y tox script: tox -e linters diff --git a/apps/note/templates/note/amount_input.html b/apps/note/templates/note/amount_input.html index d4873115..cbe9d160 100644 --- a/apps/note/templates/note/amount_input.html +++ b/apps/note/templates/note/amount_input.html @@ -9,7 +9,7 @@ SPDX-License-Identifier: GPL-3.0-or-later name="{{ widget.name }}" {# Other attributes are loaded #} {% for name, value in widget.attrs.items %} - {% ifnotequal value False %}{{ name }}{% ifnotequal value True %}="{{ value|stringformat:'s' }}"{% endifnotequal %}{% endifnotequal %} + {% if value is not False %}{{ name }}{% if value is not True %}="{{ value|stringformat:'s' }}"{% endif %}{% endif %} {% endfor %}>
diff --git a/note_kfet/templates/autocomplete_model.html b/note_kfet/templates/autocomplete_model.html index fa24213f..5ffe971d 100644 --- a/note_kfet/templates/autocomplete_model.html +++ b/note_kfet/templates/autocomplete_model.html @@ -8,7 +8,7 @@ SPDX-License-Identifier: GPL-3.0-or-later {% if widget.value != None and widget.value != "" %}value="{{ widget.value }}"{% endif %} name="{{ widget.name }}_name" autocomplete="off" {% for name, value in widget.attrs.items %} - {% ifnotequal value False %}{{ name }}{% ifnotequal value True %}="{{ value|stringformat:'s' }}"{% endifnotequal %}{% endifnotequal %} + {% if value is not False %}{{ name }}{% if value is not True %}="{{ value|stringformat:'s' }}"{% endif %}{% endif %} {% endfor %} aria-describedby="{{widget.attrs.id}}_tooltip"> {% if widget.resetable %} diff --git a/requirements.txt b/requirements.txt index f4ece220..5548fd4b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,19 +1,19 @@ -beautifulsoup4~=4.7.1 -Django~=2.2.15 -django-bootstrap-datepicker-plus~=3.0.5 -django-cas-server~=1.2.0 -django-colorfield~=0.3.2 -django-crispy-forms~=1.7.2 -django-extensions>=2.1.4 -django-filter~=2.1 -django-htcpcp-tea~=0.3.1 -django-mailer~=2.0.1 -django-oauth-toolkit~=1.3.3 -django-phonenumber-field~=5.0.0 -django-polymorphic>=2.0.3,<3.0.0 -djangorestframework>=3.9.0,<3.13.0 -django-rest-polymorphic~=0.1.9 -django-tables2~=2.3.1 -python-memcached~=1.59 -phonenumbers~=8.9.10 -Pillow>=5.4.1 +beautifulsoup4~=4.12.3 +Django~=4.2.9 +django-bootstrap-datepicker-plus~=5.0.5 +django-cas-server~=2.0.0 +django-colorfield~=0.11.0 +django-crispy-forms~=2.1.0 +django-extensions>=3.2.3 +django-filter~=23.5 +django-htcpcp-tea~=0.8.1 +django-mailer~=2.3.1 +django-oauth-toolkit~=2.3.0 +django-phonenumber-field~=7.3.0 +django-polymorphic~=3.1.0 +djangorestframework~=3.14.0 +django-rest-polymorphic~=0.1.10 +django-tables2~=2.7.0 +python-memcached~=1.62 +phonenumbers~=8.13.28 +Pillow>=10.2.0 diff --git a/tox.ini b/tox.ini index ad3c6798..0526236f 100644 --- a/tox.ini +++ b/tox.ini @@ -1,14 +1,14 @@ [tox] envlist = - # Debian Buster Python - py37-django22 - # Ubuntu 20.04 Python py38-django22 # Debian Bullseye Python py39-django22 + # Debian Bookworm Python + py311-django42 + linters skipsdist = True From 2f8c9b54e7c42bbd62dca80d658832c77f36f992 Mon Sep 17 00:00:00 2001 From: bleizi Date: Wed, 24 Jan 2024 19:58:55 +0100 Subject: [PATCH 02/33] Remove importation of django-cas-server which is not compatible with django 4.2 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 5548fd4b..7af89d9f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ beautifulsoup4~=4.12.3 Django~=4.2.9 django-bootstrap-datepicker-plus~=5.0.5 -django-cas-server~=2.0.0 +#django-cas-server~=2.0.0 django-colorfield~=0.11.0 django-crispy-forms~=2.1.0 django-extensions>=3.2.3 From 516a7f4be57360e917143c35abd7b21996999e6d Mon Sep 17 00:00:00 2001 From: bleizi Date: Wed, 24 Jan 2024 20:14:32 +0100 Subject: [PATCH 03/33] Remove importation of django-htcpcp-tea which is not compatible with django 4.2 --- note_kfet/settings/base.py | 2 +- note_kfet/urls.py | 8 +++++--- requirements.txt | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/note_kfet/settings/base.py b/note_kfet/settings/base.py index f3c23f4d..1e9e0752 100644 --- a/note_kfet/settings/base.py +++ b/note_kfet/settings/base.py @@ -41,7 +41,7 @@ INSTALLED_APPS = [ 'bootstrap_datepicker_plus', 'colorfield', 'crispy_forms', - 'django_htcpcp_tea', +# 'django_htcpcp_tea', 'django_tables2', 'mailer', 'phonenumber_field', diff --git a/note_kfet/urls.py b/note_kfet/urls.py index 7fc37fa7..72be36ea 100644 --- a/note_kfet/urls.py +++ b/note_kfet/urls.py @@ -30,9 +30,6 @@ urlpatterns = [ path('accounts/', include('django.contrib.auth.urls')), path('api/', include('api.urls')), path('permission/', include('permission.urls')), - - # Make coffee - path('coffee/', include('django_htcpcp_tea.urls')), ] # During development, serve static and media files @@ -57,6 +54,11 @@ if "debug_toolbar" in settings.INSTALLED_APPS: path('__debug__/', include(debug_toolbar.urls)), ] + urlpatterns +if "django_htcpcp_tea" in settings.INSTALLED_APPS: + # Make coffee + urlpatterns.append( + path('coffee/', include('django_htcpcp_tea.urls')) + ) handler400 = bad_request handler403 = permission_denied diff --git a/requirements.txt b/requirements.txt index 7af89d9f..1750cd66 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,7 @@ django-colorfield~=0.11.0 django-crispy-forms~=2.1.0 django-extensions>=3.2.3 django-filter~=23.5 -django-htcpcp-tea~=0.8.1 +#django-htcpcp-tea~=0.8.1 django-mailer~=2.3.1 django-oauth-toolkit~=2.3.0 django-phonenumber-field~=7.3.0 From d228dbf225767303e98f08660abfd66ef332b1e1 Mon Sep 17 00:00:00 2001 From: bleizi Date: Wed, 7 Feb 2024 18:02:56 +0100 Subject: [PATCH 04/33] fix some breaking changes and linters --- apps/member/views.py | 2 +- apps/note/api/views.py | 2 +- apps/note/tests/test_transactions.py | 2 +- apps/permission/scopes.py | 2 ++ apps/treasury/api/views.py | 2 +- apps/treasury/urls.py | 4 ++-- note_kfet/admin.py | 4 ++-- note_kfet/settings/base.py | 3 +++ 8 files changed, 13 insertions(+), 8 deletions(-) diff --git a/apps/member/views.py b/apps/member/views.py index 066a7ef3..e56ed7b2 100644 --- a/apps/member/views.py +++ b/apps/member/views.py @@ -26,7 +26,7 @@ from permission.backends import PermissionBackend from permission.models import Role from permission.views import ProtectQuerysetMixin, ProtectedCreateView -from .forms import UserForm, ProfileForm, ImageForm, ClubForm, MembershipForm,\ +from .forms import UserForm, ProfileForm, ImageForm, ClubForm, MembershipForm, \ CustomAuthenticationForm, MembershipRolesForm from .models import Club, Membership from .tables import ClubTable, UserTable, MembershipTable, ClubManagerTable diff --git a/apps/note/api/views.py b/apps/note/api/views.py index 34ffaf2d..bc4f99ef 100644 --- a/apps/note/api/views.py +++ b/apps/note/api/views.py @@ -13,7 +13,7 @@ from rest_framework import status from api.viewsets import ReadProtectedModelViewSet, ReadOnlyProtectedModelViewSet from permission.backends import PermissionBackend -from .serializers import NotePolymorphicSerializer, AliasSerializer, ConsumerSerializer,\ +from .serializers import NotePolymorphicSerializer, AliasSerializer, ConsumerSerializer, \ TemplateCategorySerializer, TransactionTemplateSerializer, TransactionPolymorphicSerializer, \ TrustSerializer from ..models.notes import Note, Alias, NoteUser, NoteClub, NoteSpecial, Trust diff --git a/apps/note/tests/test_transactions.py b/apps/note/tests/test_transactions.py index 4f5dd6c5..1f0920ec 100644 --- a/apps/note/tests/test_transactions.py +++ b/apps/note/tests/test_transactions.py @@ -10,7 +10,7 @@ from django.urls import reverse from django.utils import timezone from permission.models import Role -from ..api.views import AliasViewSet, ConsumerViewSet, NotePolymorphicViewSet, TemplateCategoryViewSet,\ +from ..api.views import AliasViewSet, ConsumerViewSet, NotePolymorphicViewSet, TemplateCategoryViewSet, \ TransactionTemplateViewSet, TransactionViewSet from ..models import NoteUser, Transaction, TemplateCategory, TransactionTemplate, RecurrentTransaction, \ MembershipTransaction, SpecialTransaction, NoteSpecial, Alias, Note diff --git a/apps/permission/scopes.py b/apps/permission/scopes.py index 65242804..f8fd7687 100644 --- a/apps/permission/scopes.py +++ b/apps/permission/scopes.py @@ -44,6 +44,8 @@ class PermissionOAuth2Validator(OAuth2Validator): subset of permissions. """ + oidc_claim_scope = None # fix breaking change of django-oauth-toolkit 2.0.0 + valid_scopes = set() for t in Permission.PERMISSION_TYPES: diff --git a/apps/treasury/api/views.py b/apps/treasury/api/views.py index e6ba9ced..36388279 100644 --- a/apps/treasury/api/views.py +++ b/apps/treasury/api/views.py @@ -5,7 +5,7 @@ from django_filters.rest_framework import DjangoFilterBackend from rest_framework.filters import SearchFilter from api.viewsets import ReadProtectedModelViewSet -from .serializers import InvoiceSerializer, ProductSerializer, RemittanceTypeSerializer, RemittanceSerializer,\ +from .serializers import InvoiceSerializer, ProductSerializer, RemittanceTypeSerializer, RemittanceSerializer, \ SogeCreditSerializer from ..models import Invoice, Product, RemittanceType, Remittance, SogeCredit diff --git a/apps/treasury/urls.py b/apps/treasury/urls.py index 4fe87924..144ae296 100644 --- a/apps/treasury/urls.py +++ b/apps/treasury/urls.py @@ -3,8 +3,8 @@ from django.urls import path -from .views import InvoiceCreateView, InvoiceListView, InvoiceUpdateView, InvoiceDeleteView, InvoiceRenderView,\ - RemittanceListView, RemittanceCreateView, RemittanceUpdateView, LinkTransactionToRemittanceView,\ +from .views import InvoiceCreateView, InvoiceListView, InvoiceUpdateView, InvoiceDeleteView, InvoiceRenderView, \ + RemittanceListView, RemittanceCreateView, RemittanceUpdateView, LinkTransactionToRemittanceView, \ UnlinkTransactionToRemittanceView, SogeCreditListView, SogeCreditManageView app_name = 'treasury' diff --git a/note_kfet/admin.py b/note_kfet/admin.py index dc209c67..1f26f559 100644 --- a/note_kfet/admin.py +++ b/note_kfet/admin.py @@ -25,8 +25,8 @@ admin_site.register(Site, SiteAdmin) # Add external apps model if "oauth2_provider" in settings.INSTALLED_APPS: - from oauth2_provider.admin import Application, ApplicationAdmin, Grant, \ - GrantAdmin, AccessToken, AccessTokenAdmin, RefreshToken, RefreshTokenAdmin + from oauth2_provider.admin import ApplicationAdmin, GrantAdmin, AccessTokenAdmin, RefreshTokenAdmin + from oauth2_provider.model import Application, Grant, AccessToken, RefreshToken admin_site.register(Application, ApplicationAdmin) admin_site.register(Grant, GrantAdmin) admin_site.register(AccessToken, AccessTokenAdmin) diff --git a/note_kfet/settings/base.py b/note_kfet/settings/base.py index 1e9e0752..fe466b1e 100644 --- a/note_kfet/settings/base.py +++ b/note_kfet/settings/base.py @@ -263,6 +263,9 @@ OAUTH2_PROVIDER = { 'REFRESH_TOKEN_EXPIRE_SECONDS': timedelta(days=14), } +# PKCE (fix a breaking change of django-oauth-toolkit 2.0.0) +PKCE_REQUIRED = False + # Take control on how widget templates are sourced # See https://docs.djangoproject.com/en/2.2/ref/forms/renderers/#templatessetting FORM_RENDERER = 'django.forms.renderers.TemplatesSetting' From b6b81a8b8f1d1b9d3d388abb0f698550b19f96fb Mon Sep 17 00:00:00 2001 From: bleizi Date: Wed, 7 Feb 2024 18:05:32 +0100 Subject: [PATCH 05/33] typo --- note_kfet/admin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/note_kfet/admin.py b/note_kfet/admin.py index 1f26f559..62d2c688 100644 --- a/note_kfet/admin.py +++ b/note_kfet/admin.py @@ -26,7 +26,7 @@ admin_site.register(Site, SiteAdmin) # Add external apps model if "oauth2_provider" in settings.INSTALLED_APPS: from oauth2_provider.admin import ApplicationAdmin, GrantAdmin, AccessTokenAdmin, RefreshTokenAdmin - from oauth2_provider.model import Application, Grant, AccessToken, RefreshToken + from oauth2_provider.models import Application, Grant, AccessToken, RefreshToken admin_site.register(Application, ApplicationAdmin) admin_site.register(Grant, GrantAdmin) admin_site.register(AccessToken, AccessTokenAdmin) From abc88d0118c7f3bbc060058cc5a50a45da3e9f6e Mon Sep 17 00:00:00 2001 From: bleizi Date: Wed, 7 Feb 2024 18:21:08 +0100 Subject: [PATCH 06/33] replace url from django.conf.urls by re_path from django.urls --- apps/api/urls.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/apps/api/urls.py b/apps/api/urls.py index 5d8b8b98..cb342b1c 100644 --- a/apps/api/urls.py +++ b/apps/api/urls.py @@ -2,7 +2,8 @@ # SPDX-License-Identifier: GPL-3.0-or-later from django.conf import settings -from django.conf.urls import url, include +from django.conf.urls import include +from django.urls import re_path from rest_framework import routers from .views import UserInformationView @@ -47,7 +48,7 @@ app_name = 'api' # Wire up our API using automatic URL routing. # Additionally, we include login URLs for the browsable API. urlpatterns = [ - url('^', include(router.urls)), - url('^me/', UserInformationView.as_view()), - url('^api-auth/', include('rest_framework.urls', namespace='rest_framework')), + re_path('^', include(router.urls)), + re_path('^me/', UserInformationView.as_view()), + re_path('^api-auth/', include('rest_framework.urls', namespace='rest_framework')), ] From 82fea65b5edbf58b6bd469cdfef63dab037adef1 Mon Sep 17 00:00:00 2001 From: bleizi Date: Wed, 7 Feb 2024 20:00:58 +0100 Subject: [PATCH 07/33] django_htcpcp_tea in middleware only if in apps --- apps/api/urls.py | 2 +- note_kfet/settings/base.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/api/urls.py b/apps/api/urls.py index cb342b1c..4cb8085e 100644 --- a/apps/api/urls.py +++ b/apps/api/urls.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later from django.conf import settings -from django.conf.urls import include +from django.conf.urls import include from django.urls import re_path from rest_framework import routers diff --git a/note_kfet/settings/base.py b/note_kfet/settings/base.py index fe466b1e..d653dfc6 100644 --- a/note_kfet/settings/base.py +++ b/note_kfet/settings/base.py @@ -90,12 +90,14 @@ MIDDLEWARE = [ 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.locale.LocaleMiddleware', 'django.contrib.sites.middleware.CurrentSiteMiddleware', - 'django_htcpcp_tea.middleware.HTCPCPTeaMiddleware', 'note_kfet.middlewares.SessionMiddleware', 'note_kfet.middlewares.LoginByIPMiddleware', 'note_kfet.middlewares.TurbolinksMiddleware', 'note_kfet.middlewares.ClacksMiddleware', ] +if "django_htcpcp_tea" in INSTALLED_APPS: + MIDDLEWARE.append('django_htcpcp_tea.middleware.HTCPCPTeaMiddleware') + ROOT_URLCONF = 'note_kfet.urls' From 399a32bece44af5b322d3089eb09a9dc31928393 Mon Sep 17 00:00:00 2001 From: bleizi Date: Sun, 11 Feb 2024 16:51:48 +0100 Subject: [PATCH 08/33] default auto field --- note_kfet/settings/base.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/note_kfet/settings/base.py b/note_kfet/settings/base.py index d653dfc6..9ba5bb34 100644 --- a/note_kfet/settings/base.py +++ b/note_kfet/settings/base.py @@ -300,3 +300,6 @@ PHONENUMBER_DEFAULT_REGION = 'FR' # We add custom information to CAS, in order to give a normalized name to other services CAS_AUTH_CLASS = 'member.auth.CustomAuthUser' + +# Default field for primary key +DEFAULT_AUTO_FIELD = "django.db.models.AutoField" From fb3337966e029a1d69f5e25f1c5d5e588ec3af11 Mon Sep 17 00:00:00 2001 From: bleizi Date: Sun, 11 Feb 2024 22:24:37 +0100 Subject: [PATCH 09/33] bootstrap4 is now a standalone package from crispy-forms --- note_kfet/settings/base.py | 2 ++ requirements.txt | 1 + 2 files changed, 3 insertions(+) diff --git a/note_kfet/settings/base.py b/note_kfet/settings/base.py index 9ba5bb34..44c34020 100644 --- a/note_kfet/settings/base.py +++ b/note_kfet/settings/base.py @@ -40,6 +40,7 @@ INSTALLED_APPS = [ # External apps 'bootstrap_datepicker_plus', 'colorfield', + 'crispy_bootstrap4', 'crispy_forms', # 'django_htcpcp_tea', 'django_tables2', @@ -279,6 +280,7 @@ LOGIN_REDIRECT_URL = '/' SESSION_COOKIE_AGE = 60 * 60 * 3 # Use Crispy Bootstrap4 theme +CRISPY_ALLOWED_TEMPLATE_PACKS = 'bootstrap4' CRISPY_TEMPLATE_PACK = 'bootstrap4' # Use Django Table2 Bootstrap4 theme diff --git a/requirements.txt b/requirements.txt index 1750cd66..f4a32c97 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ beautifulsoup4~=4.12.3 +crispy-bootstrap4~=2023.1 Django~=4.2.9 django-bootstrap-datepicker-plus~=5.0.5 #django-cas-server~=2.0.0 From 2ee7f41dfebdc53de4a4b3341bc05977c2050ebb Mon Sep 17 00:00:00 2001 From: bleizi Date: Mon, 12 Feb 2024 21:25:07 +0100 Subject: [PATCH 10/33] tests with ubuntu 22.04, django-bootstrap-datepicker-plus is a standalone package and fix encoding in tests --- .gitlab-ci.yml | 38 ++-- apps/activity/forms.py | 3 +- apps/member/forms.py | 5 +- apps/note/forms.py | 3 +- apps/wei/forms/registration.py | 3 +- apps/wei/tests/test_wei_registration.py | 4 +- note_kfet/inputs.py | 261 ------------------------ tox.ini | 8 +- 8 files changed, 34 insertions(+), 291 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 98fbac88..23ba25aa 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,25 +7,8 @@ stages: variables: GIT_SUBMODULE_STRATEGY: recursive -# Ubuntu 20.04 -py38-django22: - stage: test - image: ubuntu:20.04 - before_script: - # Fix tzdata prompt - - ln -sf /usr/share/zoneinfo/Europe/Paris /etc/localtime && echo Europe/Paris > /etc/timezone - - > - apt-get update && - apt-get install --no-install-recommends -y - python3-django python3-django-crispy-forms - python3-django-extensions python3-django-filters python3-django-polymorphic - python3-djangorestframework python3-django-oauth-toolkit python3-psycopg2 python3-pil - python3-babel python3-lockfile python3-pip python3-phonenumbers python3-memcache - python3-bs4 python3-setuptools tox texlive-xetex - script: tox -e py38-django22 - # Debian Bullseye -py39-django22: +py39-django42: stage: test image: debian:bullseye before_script: @@ -37,7 +20,24 @@ py39-django22: python3-djangorestframework python3-django-oauth-toolkit python3-psycopg2 python3-pil python3-babel python3-lockfile python3-pip python3-phonenumbers python3-memcache python3-bs4 python3-setuptools tox texlive-xetex - script: tox -e py39-django22 + script: tox -e py39-django42 + +# Ubuntu 22.04 +py310-django42: + stage: test + image: ubuntu:22.04 + before_script: + # Fix tzdata prompt + - ln -sf /usr/share/zoneinfo/Europe/Paris /etc/localtime && echo Europe/Paris > /etc/timezone + - > + apt-get update && + apt-get install --no-install-recommends -y + python3-django python3-django-crispy-forms + python3-django-extensions python3-django-filters python3-django-polymorphic + python3-djangorestframework python3-django-oauth-toolkit python3-psycopg2 python3-pil + python3-babel python3-lockfile python3-pip python3-phonenumbers python3-memcache + python3-bs4 python3-setuptools tox texlive-xetex + script: tox -e py38-django42 # Debian Bookworm py311-django42: diff --git a/apps/activity/forms.py b/apps/activity/forms.py index 1ca98cef..f8744f14 100644 --- a/apps/activity/forms.py +++ b/apps/activity/forms.py @@ -4,13 +4,14 @@ from datetime import timedelta from random import shuffle +from bootstrap_datepicker_plus.widgets import DateTimePickerInput from django import forms from django.contrib.contenttypes.models import ContentType from django.utils import timezone from django.utils.translation import gettext_lazy as _ from member.models import Club from note.models import Note, NoteUser -from note_kfet.inputs import Autocomplete, DateTimePickerInput +from note_kfet.inputs import Autocomplete from note_kfet.middlewares import get_current_request from permission.backends import PermissionBackend diff --git a/apps/member/forms.py b/apps/member/forms.py index 527816cb..420b35a4 100644 --- a/apps/member/forms.py +++ b/apps/member/forms.py @@ -3,7 +3,7 @@ import io -from PIL import Image, ImageSequence +from bootstrap_datepicker_plus.widgets import DatePickerInput from django import forms from django.conf import settings from django.contrib.auth.forms import AuthenticationForm @@ -13,8 +13,9 @@ from django.forms import CheckboxSelectMultiple from django.utils import timezone from django.utils.translation import gettext_lazy as _ from note.models import NoteSpecial, Alias -from note_kfet.inputs import Autocomplete, AmountInput, DatePickerInput +from note_kfet.inputs import Autocomplete, AmountInput from permission.models import PermissionMask, Role +from PIL import Image, ImageSequence from .models import Profile, Club, Membership diff --git a/apps/note/forms.py b/apps/note/forms.py index 791abb51..f496843a 100644 --- a/apps/note/forms.py +++ b/apps/note/forms.py @@ -2,12 +2,13 @@ # SPDX-License-Identifier: GPL-3.0-or-later from datetime import datetime +from bootstrap_datepicker_plus.widgets import DateTimePickerInput from django import forms from django.contrib.contenttypes.models import ContentType from django.forms import CheckboxSelectMultiple from django.utils.timezone import make_aware from django.utils.translation import gettext_lazy as _ -from note_kfet.inputs import Autocomplete, AmountInput, DateTimePickerInput +from note_kfet.inputs import Autocomplete, AmountInput from .models import TransactionTemplate, NoteClub, Alias diff --git a/apps/wei/forms/registration.py b/apps/wei/forms/registration.py index 408071f4..65a98bfe 100644 --- a/apps/wei/forms/registration.py +++ b/apps/wei/forms/registration.py @@ -1,13 +1,14 @@ # Copyright (C) 2018-2023 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later +from bootstrap_datepicker_plus.widgets import DatePickerInput from django import forms from django.contrib.auth.models import User from django.db.models import Q from django.forms import CheckboxSelectMultiple from django.utils.translation import gettext_lazy as _ from note.models import NoteSpecial, NoteUser -from note_kfet.inputs import AmountInput, DatePickerInput, Autocomplete, ColorWidget +from note_kfet.inputs import AmountInput, Autocomplete, ColorWidget from ..models import WEIClub, WEIRegistration, Bus, BusTeam, WEIMembership, WEIRole diff --git a/apps/wei/tests/test_wei_registration.py b/apps/wei/tests/test_wei_registration.py index 86dd4cfd..2ca28e43 100644 --- a/apps/wei/tests/test_wei_registration.py +++ b/apps/wei/tests/test_wei_registration.py @@ -439,7 +439,7 @@ class TestWEIRegistration(TestCase): emergency_contact_phone='+33123456789', )) self.assertEqual(response.status_code, 200) - self.assertTrue("This user can't be in her/his first year since he/she has already participated to a WEI." + self.assertTrue("This user can't be in her/his first year since he/she has already participated to a WEI." in str(response.context["form"].errors)) # Check that if the WEI is started, we can't register anyone @@ -635,7 +635,7 @@ class TestWEIRegistration(TestCase): )) self.assertEqual(response.status_code, 200) self.assertFalse(response.context["form"].is_valid()) - self.assertTrue("This team doesn't belong to the given bus." in str(response.context["form"].errors)) + self.assertTrue("This team doesn't belong to the given bus." in str(response.context["form"].errors)) response = self.client.post(reverse("wei:validate_registration", kwargs=dict(pk=self.registration.pk)), dict( roles=[WEIRole.objects.get(name="GC WEI").id], diff --git a/note_kfet/inputs.py b/note_kfet/inputs.py index 6e729c47..e6e7f8f9 100644 --- a/note_kfet/inputs.py +++ b/note_kfet/inputs.py @@ -68,264 +68,3 @@ class ColorWidget(Widget): def value_from_datadict(self, data, files, name): val = super().value_from_datadict(data, files, name) return int(val[1:], 16) - - -""" -The remaining of this file comes from the project `django-bootstrap-datepicker-plus` available on Github: -https://github.com/monim67/django-bootstrap-datepicker-plus -This is distributed under Apache License 2.0. - -This adds datetime pickers with bootstrap. -""" - -"""Contains Base Date-Picker input class for widgets of this package.""" - - -class DatePickerDictionary: - """Keeps track of all date-picker input classes.""" - - _i = 0 - items = dict() - - @classmethod - def generate_id(cls): - """Return a unique ID for each date-picker input class.""" - cls._i += 1 - return 'dp_%s' % cls._i - - -class BasePickerInput(DateTimeBaseInput): - """Base Date-Picker input class for widgets of this package.""" - - template_name = 'bootstrap_datepicker_plus/date-picker.html' - picker_type = 'DATE' - format = '%Y-%m-%d' - config = {} - _default_config = { - 'id': None, - 'picker_type': None, - 'linked_to': None, - 'options': {} # final merged options - } - options = {} # options extended by user - options_param = {} # options passed as parameter - _default_options = { - 'showClose': True, - 'showClear': True, - 'showTodayButton': True, - "locale": "fr", - } - - # source: https://github.com/tutorcruncher/django-bootstrap3-datetimepicker - # file: /blob/31fbb09/bootstrap3_datetime/widgets.py#L33 - format_map = ( - ('DDD', r'%j'), - ('DD', r'%d'), - ('MMMM', r'%B'), - ('MMM', r'%b'), - ('MM', r'%m'), - ('YYYY', r'%Y'), - ('YY', r'%y'), - ('HH', r'%H'), - ('hh', r'%I'), - ('mm', r'%M'), - ('ss', r'%S'), - ('a', r'%p'), - ('ZZ', r'%z'), - ) - - class Media: - """JS/CSS resources needed to render the date-picker calendar.""" - - js = ( - 'https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/' - 'moment-with-locales.min.js', - 'https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/' - '4.17.47/js/bootstrap-datetimepicker.min.js', - 'bootstrap_datepicker_plus/js/datepicker-widget.js' - ) - css = {'all': ( - 'https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/' - '4.17.47/css/bootstrap-datetimepicker.css', - 'bootstrap_datepicker_plus/css/datepicker-widget.css' - ), } - - @classmethod - def format_py2js(cls, datetime_format): - """Convert python datetime format to moment datetime format.""" - for js_format, py_format in cls.format_map: - datetime_format = datetime_format.replace(py_format, js_format) - return datetime_format - - @classmethod - def format_js2py(cls, datetime_format): - """Convert moment datetime format to python datetime format.""" - for js_format, py_format in cls.format_map: - datetime_format = datetime_format.replace(js_format, py_format) - return datetime_format - - def __init__(self, attrs=None, format=None, options=None): - """Initialize the Date-picker widget.""" - self.format_param = format - self.options_param = options if options else {} - self.config = self._default_config.copy() - self.config['id'] = DatePickerDictionary.generate_id() - self.config['picker_type'] = self.picker_type - self.config['options'] = self._calculate_options() - attrs = attrs if attrs else {} - if 'class' not in attrs: - attrs['class'] = 'form-control' - super().__init__(attrs, self._calculate_format()) - - def _calculate_options(self): - """Calculate and Return the options.""" - _options = self._default_options.copy() - _options.update(self.options) - if self.options_param: - _options.update(self.options_param) - return _options - - def _calculate_format(self): - """Calculate and Return the datetime format.""" - _format = self.format_param if self.format_param else self.format - if self.config['options'].get('format'): - _format = self.format_js2py(self.config['options'].get('format')) - else: - self.config['options']['format'] = self.format_py2js(_format) - return _format - - def get_context(self, name, value, attrs): - """Return widget context dictionary.""" - context = super().get_context( - name, value, attrs) - context['widget']['attrs']['dp_config'] = json_dumps(self.config) - return context - - def start_of(self, event_id): - """ - Set Date-Picker as the start-date of a date-range. - - Args: - - event_id (string): User-defined unique id for linking two fields - """ - DatePickerDictionary.items[str(event_id)] = self - return self - - def end_of(self, event_id, import_options=True): - """ - Set Date-Picker as the end-date of a date-range. - - Args: - - event_id (string): User-defined unique id for linking two fields - - import_options (bool): inherit options from start-date input, - default: TRUE - """ - event_id = str(event_id) - if event_id in DatePickerDictionary.items: - linked_picker = DatePickerDictionary.items[event_id] - self.config['linked_to'] = linked_picker.config['id'] - if import_options: - backup_moment_format = self.config['options']['format'] - self.config['options'].update(linked_picker.config['options']) - self.config['options'].update(self.options_param) - if self.format_param or 'format' in self.options_param: - self.config['options']['format'] = backup_moment_format - else: - self.format = linked_picker.format - # Setting useCurrent is necessary, see following issue - # https://github.com/Eonasdan/bootstrap-datetimepicker/issues/1075 - self.config['options']['useCurrent'] = False - self._link_to(linked_picker) - else: - raise KeyError( - 'start-date not specified for event_id "%s"' % event_id) - return self - - def _link_to(self, linked_picker): - """ - Executed when two date-inputs are linked together. - - This method for sub-classes to override to customize the linking. - """ - pass - - -class DatePickerInput(BasePickerInput): - """ - Widget to display a Date-Picker Calendar on a DateField property. - - Args: - - attrs (dict): HTML attributes of rendered HTML input - - format (string): Python DateTime format eg. "%Y-%m-%d" - - options (dict): Options to customize the widget, see README - """ - - picker_type = 'DATE' - format = '%Y-%m-%d' - format_key = 'DATE_INPUT_FORMATS' - - -class TimePickerInput(BasePickerInput): - """ - Widget to display a Time-Picker Calendar on a TimeField property. - - Args: - - attrs (dict): HTML attributes of rendered HTML input - - format (string): Python DateTime format eg. "%Y-%m-%d" - - options (dict): Options to customize the widget, see README - """ - - picker_type = 'TIME' - format = '%H:%M' - format_key = 'TIME_INPUT_FORMATS' - template_name = 'bootstrap_datepicker_plus/time_picker.html' - - -class DateTimePickerInput(BasePickerInput): - """ - Widget to display a DateTime-Picker Calendar on a DateTimeField property. - - Args: - - attrs (dict): HTML attributes of rendered HTML input - - format (string): Python DateTime format eg. "%Y-%m-%d" - - options (dict): Options to customize the widget, see README - """ - - picker_type = 'DATETIME' - format = '%Y-%m-%d %H:%M' - format_key = 'DATETIME_INPUT_FORMATS' - - -class MonthPickerInput(BasePickerInput): - """ - Widget to display a Month-Picker Calendar on a DateField property. - - Args: - - attrs (dict): HTML attributes of rendered HTML input - - format (string): Python DateTime format eg. "%Y-%m-%d" - - options (dict): Options to customize the widget, see README - """ - - picker_type = 'MONTH' - format = '01/%m/%Y' - format_key = 'DATE_INPUT_FORMATS' - - -class YearPickerInput(BasePickerInput): - """ - Widget to display a Year-Picker Calendar on a DateField property. - - Args: - - attrs (dict): HTML attributes of rendered HTML input - - format (string): Python DateTime format eg. "%Y-%m-%d" - - options (dict): Options to customize the widget, see README - """ - - picker_type = 'YEAR' - format = '01/01/%Y' - format_key = 'DATE_INPUT_FORMATS' - - def _link_to(self, linked_picker): - """Customize the options when linked with other date-time input""" - yformat = self.config['options']['format'].replace('-01-01', '-12-31') - self.config['options']['format'] = yformat diff --git a/tox.ini b/tox.ini index 0526236f..a18af893 100644 --- a/tox.ini +++ b/tox.ini @@ -1,10 +1,10 @@ [tox] envlist = - # Ubuntu 20.04 Python - py38-django22 - # Debian Bullseye Python - py39-django22 + py39-django42 + + # Ubuntu 22.04 Python + py310-django42 # Debian Bookworm Python py311-django42 From b7a71d911d22fe2adfd322ecdeb0dfc4b2b3490f Mon Sep 17 00:00:00 2001 From: bleizi Date: Mon, 12 Feb 2024 22:56:43 +0100 Subject: [PATCH 11/33] _get_validtion_exclusions() now return a set, PIL.Image.ANTIALIAS was renamed LANCZOS and typo in .gitlab-ci.yml --- .gitlab-ci.yml | 2 +- apps/member/forms.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 23ba25aa..4f041867 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -37,7 +37,7 @@ py310-django42: python3-djangorestframework python3-django-oauth-toolkit python3-psycopg2 python3-pil python3-babel python3-lockfile python3-pip python3-phonenumbers python3-memcache python3-bs4 python3-setuptools tox texlive-xetex - script: tox -e py38-django42 + script: tox -e py310-django42 # Debian Bookworm py311-django42: diff --git a/apps/member/forms.py b/apps/member/forms.py index 420b35a4..0d78c726 100644 --- a/apps/member/forms.py +++ b/apps/member/forms.py @@ -33,7 +33,7 @@ class UserForm(forms.ModelForm): # Django usernames can only contain letters, numbers, @, ., +, - and _. # We want to allow users to have uncommon and unpractical usernames: # That is their problem, and we have normalized aliases for us. - return super()._get_validation_exclusions() + ["username"] + return super()._get_validation_exclusions() | {"username"} class Meta: model = User @@ -122,7 +122,7 @@ class ImageForm(forms.Form): frame = frame.crop((x, y, x + w, y + h)) frame = frame.resize( (settings.PIC_WIDTH, settings.PIC_RATIO * settings.PIC_WIDTH), - Image.ANTIALIAS, + Image.LANCZOS, ) frames.append(frame) From 96215cc1ff6ad50cdc79c1b80a1f3885b04d5b31 Mon Sep 17 00:00:00 2001 From: bleizi Date: Tue, 13 Feb 2024 13:43:14 +0100 Subject: [PATCH 12/33] oidc_claim_scope in Class instead of method --- apps/permission/scopes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/permission/scopes.py b/apps/permission/scopes.py index f8fd7687..6770c681 100644 --- a/apps/permission/scopes.py +++ b/apps/permission/scopes.py @@ -35,6 +35,8 @@ class PermissionScopes(BaseScopes): class PermissionOAuth2Validator(OAuth2Validator): + oidc_claim_scope = None # fix breaking change of django-oauth-toolkit 2.0.0 + def validate_scopes(self, client_id, scopes, client, request, *args, **kwargs): """ User can request as many scope as he wants, including invalid scopes, @@ -44,8 +46,6 @@ class PermissionOAuth2Validator(OAuth2Validator): subset of permissions. """ - oidc_claim_scope = None # fix breaking change of django-oauth-toolkit 2.0.0 - valid_scopes = set() for t in Permission.PERMISSION_TYPES: From 6c61daf1c58c1db899e5075d7470d65a2253e08d Mon Sep 17 00:00:00 2001 From: charliep Date: Mon, 11 Mar 2024 10:25:48 +0100 Subject: [PATCH 13/33] Update views.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Passage à la time zone Europe/Paris --- apps/activity/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/activity/views.py b/apps/activity/views.py index 38b87964..6a2b21ca 100644 --- a/apps/activity/views.py +++ b/apps/activity/views.py @@ -315,8 +315,8 @@ X-WR-CALNAME:Kfet Calendar NAME:Kfet Calendar CALSCALE:GREGORIAN BEGIN:VTIMEZONE -TZID:Europe/Berlin -X-LIC-LOCATION:Europe/Berlin +TZID:Europe/Paris +X-LIC-LOCATION:Europe/Paris BEGIN:DAYLIGHT TZOFFSETFROM:+0100 TZOFFSETTO:+0200 From feeb99041fe42d6cfb97794d3e989467fc85f5a8 Mon Sep 17 00:00:00 2001 From: korenstin Date: Sat, 13 Jul 2024 12:41:59 +0200 Subject: [PATCH 14/33] Fix the Alias Search API --- apps/note/api/views.py | 17 ++++------------- apps/registration/forms.py | 10 ---------- 2 files changed, 4 insertions(+), 23 deletions(-) diff --git a/apps/note/api/views.py b/apps/note/api/views.py index bc4f99ef..32ed1837 100644 --- a/apps/note/api/views.py +++ b/apps/note/api/views.py @@ -179,19 +179,10 @@ class ConsumerViewSet(ReadOnlyProtectedModelViewSet): # We match first an alias if it is matched without normalization, # then if the normalized pattern matches a normalized alias. queryset = queryset.filter( - **{f'name{suffix}': alias_prefix + alias} - ).union( - queryset.filter( - Q(**{f'normalized_name{suffix}': alias_prefix + Alias.normalize(alias)}) - & ~Q(**{f'name{suffix}': alias_prefix + alias}) - ), - all=True).union( - queryset.filter( - Q(**{f'normalized_name{suffix}': alias_prefix + alias.lower()}) - & ~Q(**{f'normalized_name{suffix}': alias_prefix + Alias.normalize(alias)}) - & ~Q(**{f'name{suffix}': alias_prefix + alias}) - ), - all=True) + Q(**{f'name{suffix}': alias_prefix + alias}) + | Q(**{f'normalized_name{suffix}': alias_prefix + Alias.normalize(alias)}) + | Q(**{f'normalized_name{suffix}': alias_prefix + alias.lower()}) + ) queryset = queryset if settings.DATABASES[queryset.db]["ENGINE"] == 'django.db.backends.postgresql' \ else queryset.order_by("name") diff --git a/apps/registration/forms.py b/apps/registration/forms.py index 6761da43..7791a8a1 100644 --- a/apps/registration/forms.py +++ b/apps/registration/forms.py @@ -5,7 +5,6 @@ from django import forms from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.models import User from django.utils.translation import gettext_lazy as _ -from member.models import Club from note.models import NoteSpecial, Alias from note_kfet.inputs import AmountInput @@ -115,12 +114,3 @@ class ValidationForm(forms.Form): required=False, initial=True, ) - - # If the bda exists - if Club.objects.filter(name__iexact="bda").exists(): - # The user can join the bda club at the inscription - join_bda = forms.BooleanField( - label=_("Join BDA Club"), - required=False, - initial=True, - ) From bbbdcc7247fe1539e1aa9eb48f447a4e6fae7472 Mon Sep 17 00:00:00 2001 From: korenstin Date: Sat, 13 Jul 2024 18:03:19 +0200 Subject: [PATCH 15/33] linters --- apps/permission/scopes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/permission/scopes.py b/apps/permission/scopes.py index f8fd7687..6770c681 100644 --- a/apps/permission/scopes.py +++ b/apps/permission/scopes.py @@ -35,6 +35,8 @@ class PermissionScopes(BaseScopes): class PermissionOAuth2Validator(OAuth2Validator): + oidc_claim_scope = None # fix breaking change of django-oauth-toolkit 2.0.0 + def validate_scopes(self, client_id, scopes, client, request, *args, **kwargs): """ User can request as many scope as he wants, including invalid scopes, @@ -44,8 +46,6 @@ class PermissionOAuth2Validator(OAuth2Validator): subset of permissions. """ - oidc_claim_scope = None # fix breaking change of django-oauth-toolkit 2.0.0 - valid_scopes = set() for t in Permission.PERMISSION_TYPES: From 1a258dfe9e1cc20cfa3fb07af3f2c5aee5069569 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Thu, 10 Mar 2022 16:11:01 +0100 Subject: [PATCH 16/33] Parse input of search filters to prevent errors based on invalid regex, fixes #113 Signed-off-by: Yohann D'ANELLO --- apps/activity/api/views.py | 11 +++++----- apps/api/filters.py | 42 ++++++++++++++++++++++++++++++++++++ apps/api/tests.py | 8 ++++--- apps/api/viewsets.py | 4 ++-- apps/logs/api/views.py | 1 + apps/member/api/views.py | 10 +++++---- apps/note/api/views.py | 17 +++++++++------ apps/permission/api/views.py | 9 ++++---- apps/treasury/api/views.py | 13 +++++------ apps/wei/api/views.py | 16 ++++++++------ 10 files changed, 93 insertions(+), 38 deletions(-) create mode 100644 apps/api/filters.py diff --git a/apps/activity/api/views.py b/apps/activity/api/views.py index 97e6c40d..a5644fab 100644 --- a/apps/activity/api/views.py +++ b/apps/activity/api/views.py @@ -1,9 +1,10 @@ # Copyright (C) 2018-2024 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later -from api.viewsets import ReadProtectedModelViewSet from django_filters.rest_framework import DjangoFilterBackend -from rest_framework.filters import SearchFilter + +from api.filters import RegexSafeSearchFilter +from api.viewsets import ReadProtectedModelViewSet from .serializers import ActivitySerializer, ActivityTypeSerializer, EntrySerializer, GuestSerializer from ..models import Activity, ActivityType, Entry, Guest @@ -29,7 +30,7 @@ class ActivityViewSet(ReadProtectedModelViewSet): """ queryset = Activity.objects.order_by('id') serializer_class = ActivitySerializer - filter_backends = [DjangoFilterBackend, SearchFilter] + filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter] filterset_fields = ['name', 'description', 'activity_type', 'location', 'creater', 'organizer', 'attendees_club', 'date_start', 'date_end', 'valid', 'open', ] search_fields = ['$name', '$description', '$location', '$creater__last_name', '$creater__first_name', @@ -47,7 +48,7 @@ class GuestViewSet(ReadProtectedModelViewSet): """ queryset = Guest.objects.order_by('id') serializer_class = GuestSerializer - filter_backends = [DjangoFilterBackend, SearchFilter] + filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter] filterset_fields = ['activity', 'activity__name', 'last_name', 'first_name', 'inviter', 'inviter__alias__name', 'inviter__alias__normalized_name', ] search_fields = ['$activity__name', '$last_name', '$first_name', '$inviter__user__email', '$inviter__alias__name', @@ -62,7 +63,7 @@ class EntryViewSet(ReadProtectedModelViewSet): """ queryset = Entry.objects.order_by('id') serializer_class = EntrySerializer - filter_backends = [DjangoFilterBackend, SearchFilter] + filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter] filterset_fields = ['activity', 'time', 'note', 'guest', ] search_fields = ['$activity__name', '$note__user__email', '$note__alias__name', '$note__alias__normalized_name', '$guest__last_name', '$guest__first_name', ] diff --git a/apps/api/filters.py b/apps/api/filters.py new file mode 100644 index 00000000..cb51c37c --- /dev/null +++ b/apps/api/filters.py @@ -0,0 +1,42 @@ +import re +from functools import lru_cache + +from rest_framework.filters import SearchFilter + + +class RegexSafeSearchFilter(SearchFilter): + @lru_cache + def validate_regex(self, search_term) -> bool: + try: + re.compile(search_term) + return True + except re.error: + return False + + def get_search_fields(self, view, request): + """ + Ensure that given regex are valid. + If not, we consider that the user is trying to search by substring. + """ + search_fields = super().get_search_fields(view, request) + search_terms = self.get_search_terms(request) + + for search_term in search_terms: + if not self.validate_regex(search_term): + # Invalid regex. We assume we don't query by regex but by substring. + search_fields = [f.replace('$', '') for f in search_fields] + break + + return search_fields + + def get_search_terms(self, request): + """ + Ensure that search field is a valid regex query. If not, we remove extra characters. + """ + terms = super().get_search_terms(request) + if not all(self.validate_regex(term) for term in terms): + # Invalid regex. If a ^ is prefixed to the search term, we remove it. + terms = [term[1:] if term[0] == '^' else term for term in terms] + # Same for dollars. + terms = [term[:-1] if term[-1] == '$' else term for term in terms] + return terms diff --git a/apps/api/tests.py b/apps/api/tests.py index 285acc46..83d9d936 100644 --- a/apps/api/tests.py +++ b/apps/api/tests.py @@ -12,11 +12,13 @@ from django.contrib.contenttypes.models import ContentType from django.db.models.fields.files import ImageFieldFile from django.test import TestCase from django_filters.rest_framework import DjangoFilterBackend +from phonenumbers import PhoneNumber +from rest_framework.filters import OrderingFilter + +from api.filters import RegexSafeSearchFilter from member.models import Membership, Club from note.models import NoteClub, NoteUser, Alias, Note from permission.models import PermissionMask, Permission, Role -from phonenumbers import PhoneNumber -from rest_framework.filters import SearchFilter, OrderingFilter from .viewsets import ContentTypeViewSet, UserViewSet @@ -87,7 +89,7 @@ class TestAPI(TestCase): resp = self.client.get(url + f"?ordering=-{field}") self.assertEqual(resp.status_code, 200) - if SearchFilter in backends: + if RegexSafeSearchFilter in backends: # Basic search for field in viewset.search_fields: obj = self.fix_note_object(obj, field) diff --git a/apps/api/viewsets.py b/apps/api/viewsets.py index 35dad92d..341af617 100644 --- a/apps/api/viewsets.py +++ b/apps/api/viewsets.py @@ -6,11 +6,11 @@ from django_filters.rest_framework import DjangoFilterBackend from django.db.models import Q from django.conf import settings from django.contrib.auth.models import User -from rest_framework.filters import SearchFilter from rest_framework.viewsets import ReadOnlyModelViewSet, ModelViewSet from permission.backends import PermissionBackend from note.models import Alias +from .filters import RegexSafeSearchFilter from .serializers import UserSerializer, ContentTypeSerializer @@ -107,6 +107,6 @@ class ContentTypeViewSet(ReadOnlyModelViewSet): """ queryset = ContentType.objects.order_by('id') serializer_class = ContentTypeSerializer - filter_backends = [DjangoFilterBackend, SearchFilter] + filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter] filterset_fields = ['id', 'app_label', 'model', ] search_fields = ['$app_label', '$model', ] diff --git a/apps/logs/api/views.py b/apps/logs/api/views.py index 655a473a..bf5aa8a5 100644 --- a/apps/logs/api/views.py +++ b/apps/logs/api/views.py @@ -3,6 +3,7 @@ from django_filters.rest_framework import DjangoFilterBackend from rest_framework.filters import OrderingFilter + from api.viewsets import ReadOnlyProtectedModelViewSet from .serializers import ChangelogSerializer diff --git a/apps/member/api/views.py b/apps/member/api/views.py index ab6146ed..5e4e4667 100644 --- a/apps/member/api/views.py +++ b/apps/member/api/views.py @@ -2,7 +2,9 @@ # SPDX-License-Identifier: GPL-3.0-or-later from django_filters.rest_framework import DjangoFilterBackend -from rest_framework.filters import OrderingFilter, SearchFilter +from rest_framework.filters import OrderingFilter + +from api.filters import RegexSafeSearchFilter from api.viewsets import ReadProtectedModelViewSet from .serializers import ProfileSerializer, ClubSerializer, MembershipSerializer @@ -17,7 +19,7 @@ class ProfileViewSet(ReadProtectedModelViewSet): """ queryset = Profile.objects.order_by('id') serializer_class = ProfileSerializer - filter_backends = [DjangoFilterBackend, SearchFilter] + filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter] filterset_fields = ['user', 'user__first_name', 'user__last_name', 'user__username', 'user__email', 'user__note__alias__name', 'user__note__alias__normalized_name', 'phone_number', "section", 'department', 'promotion', 'address', 'paid', 'ml_events_registration', 'ml_sport_registration', @@ -34,7 +36,7 @@ class ClubViewSet(ReadProtectedModelViewSet): """ queryset = Club.objects.order_by('id') serializer_class = ClubSerializer - filter_backends = [DjangoFilterBackend, SearchFilter] + filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter] filterset_fields = ['name', 'email', 'note__alias__name', 'note__alias__normalized_name', 'parent_club', 'parent_club__name', 'require_memberships', 'membership_fee_paid', 'membership_fee_unpaid', 'membership_duration', 'membership_start', 'membership_end', ] @@ -49,7 +51,7 @@ class MembershipViewSet(ReadProtectedModelViewSet): """ queryset = Membership.objects.order_by('id') serializer_class = MembershipSerializer - filter_backends = [DjangoFilterBackend, OrderingFilter, SearchFilter] + filter_backends = [DjangoFilterBackend, OrderingFilter, RegexSafeSearchFilter] filterset_fields = ['club__name', 'club__email', 'club__note__alias__name', 'club__note__alias__normalized_name', 'user__username', 'user__last_name', 'user__first_name', 'user__email', 'user__note__alias__name', 'user__note__alias__normalized_name', diff --git a/apps/note/api/views.py b/apps/note/api/views.py index 0aba9adc..4d39a7ce 100644 --- a/apps/note/api/views.py +++ b/apps/note/api/views.py @@ -1,15 +1,18 @@ # Copyright (C) 2018-2024 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later + import re from django.conf import settings from django.db.models import Q from django.core.exceptions import ValidationError from django_filters.rest_framework import DjangoFilterBackend -from rest_framework.filters import OrderingFilter, SearchFilter +from rest_framework.filters import OrderingFilter from rest_framework import viewsets from rest_framework.response import Response from rest_framework import status + +from api.filters import RegexSafeSearchFilter from api.viewsets import ReadProtectedModelViewSet, ReadOnlyProtectedModelViewSet from permission.backends import PermissionBackend @@ -29,7 +32,7 @@ class NotePolymorphicViewSet(ReadProtectedModelViewSet): """ queryset = Note.objects.order_by('id') serializer_class = NotePolymorphicSerializer - filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter] + filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter, OrderingFilter] filterset_fields = ['alias__name', 'polymorphic_ctype', 'is_active', 'balance', 'last_negative', 'created_at', ] search_fields = ['$alias__normalized_name', '$alias__name', '$polymorphic_ctype__model', '$noteuser__user__last_name', '$noteuser__user__first_name', '$noteuser__user__email', @@ -95,7 +98,7 @@ class AliasViewSet(ReadProtectedModelViewSet): """ queryset = Alias.objects serializer_class = AliasSerializer - filter_backends = [SearchFilter, DjangoFilterBackend, OrderingFilter] + filter_backends = [RegexSafeSearchFilter, DjangoFilterBackend, OrderingFilter] search_fields = ['$normalized_name', '$name', '$note__polymorphic_ctype__model', ] filterset_fields = ['name', 'normalized_name', 'note', 'note__noteuser__user', 'note__noteclub__club', 'note__polymorphic_ctype__model', ] @@ -147,7 +150,7 @@ class AliasViewSet(ReadProtectedModelViewSet): class ConsumerViewSet(ReadOnlyProtectedModelViewSet): queryset = Alias.objects serializer_class = ConsumerSerializer - filter_backends = [SearchFilter, OrderingFilter, DjangoFilterBackend] + filter_backends = [RegexSafeSearchFilter, OrderingFilter, DjangoFilterBackend] search_fields = ['$normalized_name', '$name', '$note__polymorphic_ctype__model', ] filterset_fields = ['name', 'normalized_name', 'note', 'note__noteuser__user', 'note__noteclub__club', 'note__polymorphic_ctype__model', ] @@ -207,7 +210,7 @@ class TemplateCategoryViewSet(ReadProtectedModelViewSet): """ queryset = TemplateCategory.objects.order_by('name') serializer_class = TemplateCategorySerializer - filter_backends = [DjangoFilterBackend, SearchFilter] + filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter] filterset_fields = ['name', 'templates', 'templates__name'] search_fields = ['$name', '$templates__name', ] @@ -220,7 +223,7 @@ class TransactionTemplateViewSet(viewsets.ModelViewSet): """ queryset = TransactionTemplate.objects.order_by('name') serializer_class = TransactionTemplateSerializer - filter_backends = [SearchFilter, DjangoFilterBackend, OrderingFilter] + filter_backends = [RegexSafeSearchFilter, DjangoFilterBackend, OrderingFilter] filterset_fields = ['name', 'amount', 'display', 'category', 'category__name', ] search_fields = ['$name', '$category__name', ] ordering_fields = ['amount', ] @@ -234,7 +237,7 @@ class TransactionViewSet(ReadProtectedModelViewSet): """ queryset = Transaction.objects.order_by('-created_at') serializer_class = TransactionPolymorphicSerializer - filter_backends = [SearchFilter, DjangoFilterBackend, OrderingFilter] + filter_backends = [RegexSafeSearchFilter, DjangoFilterBackend, OrderingFilter] filterset_fields = ['source', 'source_alias', 'source__alias__name', 'source__alias__normalized_name', 'destination', 'destination_alias', 'destination__alias__name', 'destination__alias__normalized_name', 'quantity', 'polymorphic_ctype', 'amount', diff --git a/apps/permission/api/views.py b/apps/permission/api/views.py index 5296e29b..1dd18899 100644 --- a/apps/permission/api/views.py +++ b/apps/permission/api/views.py @@ -1,9 +1,10 @@ # Copyright (C) 2018-2024 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later -from api.viewsets import ReadOnlyProtectedModelViewSet from django_filters.rest_framework import DjangoFilterBackend -from rest_framework.filters import SearchFilter + +from api.filters import RegexSafeSearchFilter +from api.viewsets import ReadOnlyProtectedModelViewSet from .serializers import PermissionSerializer, RoleSerializer from ..models import Permission, Role @@ -17,7 +18,7 @@ class PermissionViewSet(ReadOnlyProtectedModelViewSet): """ queryset = Permission.objects.order_by('id') serializer_class = PermissionSerializer - filter_backends = [DjangoFilterBackend, SearchFilter] + filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter] filterset_fields = ['model', 'type', 'query', 'mask', 'field', 'permanent', ] search_fields = ['$model__name', '$query', '$description', ] @@ -30,6 +31,6 @@ class RoleViewSet(ReadOnlyProtectedModelViewSet): """ queryset = Role.objects.order_by('id') serializer_class = RoleSerializer - filter_backends = [DjangoFilterBackend, SearchFilter] + filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter] filterset_fields = ['name', 'permissions', 'for_club', 'memberships__user', ] search_fields = ['$name', '$for_club__name', ] diff --git a/apps/treasury/api/views.py b/apps/treasury/api/views.py index 9b1825d1..8cdb79d8 100644 --- a/apps/treasury/api/views.py +++ b/apps/treasury/api/views.py @@ -2,7 +2,8 @@ # SPDX-License-Identifier: GPL-3.0-or-later from django_filters.rest_framework import DjangoFilterBackend -from rest_framework.filters import SearchFilter + +from api.filters import RegexSafeSearchFilter from api.viewsets import ReadProtectedModelViewSet from .serializers import InvoiceSerializer, ProductSerializer, RemittanceTypeSerializer, RemittanceSerializer, \ @@ -18,7 +19,7 @@ class InvoiceViewSet(ReadProtectedModelViewSet): """ queryset = Invoice.objects.order_by('id') serializer_class = InvoiceSerializer - filter_backends = [DjangoFilterBackend, SearchFilter] + filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter] filterset_fields = ['bde', 'object', 'description', 'name', 'address', 'date', 'acquitted', 'locked', ] search_fields = ['$object', '$description', '$name', '$address', ] @@ -31,7 +32,7 @@ class ProductViewSet(ReadProtectedModelViewSet): """ queryset = Product.objects.order_by('invoice_id', 'id') serializer_class = ProductSerializer - filter_backends = [DjangoFilterBackend, SearchFilter] + filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter] filterset_fields = ['invoice', 'designation', 'quantity', 'amount', ] search_fields = ['$designation', '$invoice__object', ] @@ -44,7 +45,7 @@ class RemittanceTypeViewSet(ReadProtectedModelViewSet): """ queryset = RemittanceType.objects.order_by('id') serializer_class = RemittanceTypeSerializer - filter_backends = [DjangoFilterBackend, SearchFilter] + filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter] filterset_fields = ['note', ] search_fields = ['$note__special_type', ] @@ -57,7 +58,7 @@ class RemittanceViewSet(ReadProtectedModelViewSet): """ queryset = Remittance.objects.order_by('id') serializer_class = RemittanceSerializer - filter_backends = [DjangoFilterBackend, SearchFilter] + filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter] filterset_fields = ['date', 'remittance_type', 'comment', 'closed', 'transaction_proxies__transaction', ] search_fields = ['$remittance_type__note__special_type', '$comment', ] @@ -70,7 +71,7 @@ class SogeCreditViewSet(ReadProtectedModelViewSet): """ queryset = SogeCredit.objects.order_by('id') serializer_class = SogeCreditSerializer - filter_backends = [DjangoFilterBackend, SearchFilter] + filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter] filterset_fields = ['user', 'user__last_name', 'user__first_name', 'user__email', 'user__note__alias__name', 'user__note__alias__normalized_name', 'transactions', 'credit_transaction', ] search_fields = ['$user__last_name', '$user__first_name', '$user__email', '$user__note__alias__name', diff --git a/apps/wei/api/views.py b/apps/wei/api/views.py index e16a5374..88189d70 100644 --- a/apps/wei/api/views.py +++ b/apps/wei/api/views.py @@ -2,7 +2,9 @@ # SPDX-License-Identifier: GPL-3.0-or-later from django_filters.rest_framework import DjangoFilterBackend -from rest_framework.filters import OrderingFilter, SearchFilter +from rest_framework.filters import OrderingFilter + +from api.filters import RegexSafeSearchFilter from api.viewsets import ReadProtectedModelViewSet from .serializers import WEIClubSerializer, BusSerializer, BusTeamSerializer, WEIRoleSerializer, \ @@ -18,7 +20,7 @@ class WEIClubViewSet(ReadProtectedModelViewSet): """ queryset = WEIClub.objects.order_by('id') serializer_class = WEIClubSerializer - filter_backends = [DjangoFilterBackend, SearchFilter] + filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter] filterset_fields = ['name', 'year', 'date_start', 'date_end', 'email', 'note__alias__name', 'note__alias__normalized_name', 'parent_club', 'parent_club__name', 'require_memberships', 'membership_fee_paid', 'membership_fee_unpaid', 'membership_duration', 'membership_start', @@ -34,7 +36,7 @@ class BusViewSet(ReadProtectedModelViewSet): """ queryset = Bus.objects.order_by('id') serializer_class = BusSerializer - filter_backends = [DjangoFilterBackend, SearchFilter] + filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter] filterset_fields = ['name', 'wei', 'description', ] search_fields = ['$name', '$wei__name', '$description', ] @@ -47,7 +49,7 @@ class BusTeamViewSet(ReadProtectedModelViewSet): """ queryset = BusTeam.objects.order_by('id') serializer_class = BusTeamSerializer - filter_backends = [DjangoFilterBackend, SearchFilter] + filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter] filterset_fields = ['name', 'bus', 'color', 'description', 'bus__wei', ] search_fields = ['$name', '$bus__name', '$bus__wei__name', '$description', ] @@ -60,7 +62,7 @@ class WEIRoleViewSet(ReadProtectedModelViewSet): """ queryset = WEIRole.objects.order_by('id') serializer_class = WEIRoleSerializer - filter_backends = [DjangoFilterBackend, SearchFilter] + filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter] filterset_fields = ['name', 'permissions', 'memberships', ] search_fields = ['$name', ] @@ -73,7 +75,7 @@ class WEIRegistrationViewSet(ReadProtectedModelViewSet): """ queryset = WEIRegistration.objects.order_by('id') serializer_class = WEIRegistrationSerializer - filter_backends = [DjangoFilterBackend, SearchFilter] + filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter] filterset_fields = ['user', 'user__username', 'user__first_name', 'user__last_name', 'user__email', 'user__note__alias__name', 'user__note__alias__normalized_name', 'wei', 'wei__name', 'wei__email', 'wei__year', 'soge_credit', 'caution_check', 'birth_date', 'gender', @@ -92,7 +94,7 @@ class WEIMembershipViewSet(ReadProtectedModelViewSet): """ queryset = WEIMembership.objects.order_by('id') serializer_class = WEIMembershipSerializer - filter_backends = [DjangoFilterBackend, OrderingFilter, SearchFilter] + filter_backends = [DjangoFilterBackend, OrderingFilter, RegexSafeSearchFilter] filterset_fields = ['club__name', 'club__email', 'club__note__alias__name', 'club__note__alias__normalized_name', 'user__username', 'user__last_name', 'user__first_name', 'user__email', 'user__note__alias__name', From 7322d557895f89a24aaf85da542ba9d391db8d2b Mon Sep 17 00:00:00 2001 From: korenstin Date: Thu, 18 Jul 2024 13:51:56 +0200 Subject: [PATCH 17/33] Fix #113. Fix regex in views. --- apps/activity/api/views.py | 1 - apps/activity/views.py | 28 ++++++++++++++-------- apps/api/tests.py | 1 - apps/api/viewsets.py | 34 +++++++++++++++++++-------- apps/logs/api/views.py | 1 - apps/member/api/views.py | 1 - apps/member/views.py | 39 +++++++++++++++++++++---------- apps/note/api/views.py | 45 ++++++++++++++++++------------------ apps/note/views.py | 18 +++++++++++---- apps/permission/api/views.py | 3 +-- apps/registration/views.py | 14 +++++++---- apps/treasury/api/views.py | 1 - apps/treasury/views.py | 14 +++++++---- apps/wei/api/views.py | 1 - apps/wei/views.py | 31 +++++++++++++++++-------- 15 files changed, 147 insertions(+), 85 deletions(-) diff --git a/apps/activity/api/views.py b/apps/activity/api/views.py index a5644fab..4c335491 100644 --- a/apps/activity/api/views.py +++ b/apps/activity/api/views.py @@ -2,7 +2,6 @@ # SPDX-License-Identifier: GPL-3.0-or-later from django_filters.rest_framework import DjangoFilterBackend - from api.filters import RegexSafeSearchFilter from api.viewsets import ReadProtectedModelViewSet diff --git a/apps/activity/views.py b/apps/activity/views.py index 74e39fb0..430e876e 100644 --- a/apps/activity/views.py +++ b/apps/activity/views.py @@ -19,6 +19,7 @@ from django.views.decorators.cache import cache_page from django.views.generic import DetailView, TemplateView, UpdateView from django.views.generic.list import ListView from django_tables2.views import MultiTableMixin +from api.viewsets import is_regex from note.models import Alias, NoteSpecial, NoteUser from permission.backends import PermissionBackend from permission.views import ProtectQuerysetMixin, ProtectedCreateView @@ -212,13 +213,16 @@ class ActivityEntryView(LoginRequiredMixin, TemplateView): if "search" in self.request.GET and self.request.GET["search"]: pattern = self.request.GET["search"] - if pattern[0] != "^": - pattern = "^" + pattern + + # Check if this is a valid regex. If not, we won't check regex + valid_regex = is_regex(pattern) + suffix = "__iregex" if valid_regex else "__istartswith" + pattern = "^" + pattern if valid_regex and pattern[0] != "^" else pattern guest_qs = guest_qs.filter( - Q(first_name__iregex=pattern) - | Q(last_name__iregex=pattern) - | Q(inviter__alias__name__iregex=pattern) - | Q(inviter__alias__normalized_name__iregex=Alias.normalize(pattern)) + Q(**{f"first_name{suffix}": pattern}) + | Q(**{f"last_name{suffix}": pattern}) + | Q(**{f"inviter__alias__name{suffix}": pattern}) + | Q(**{f"inviter__alias__normalized_name{suffix}": Alias.normalize(pattern)}) ) else: guest_qs = guest_qs.none() @@ -250,11 +254,15 @@ class ActivityEntryView(LoginRequiredMixin, TemplateView): if "search" in self.request.GET and self.request.GET["search"]: pattern = self.request.GET["search"] + + # Check if this is a valid regex. If not, we won't check regex + valid_regex = is_regex(pattern) + suffix = "__iregex" if valid_regex else "__icontains" note_qs = note_qs.filter( - Q(note__noteuser__user__first_name__iregex=pattern) - | Q(note__noteuser__user__last_name__iregex=pattern) - | Q(name__iregex=pattern) - | Q(normalized_name__iregex=Alias.normalize(pattern)) + Q(**{f"note__noteuser__user__first_name{suffix}": pattern}) + | Q(**{f"note__noteuser__user__last_name{suffix}": pattern}) + | Q(**{f"name{suffix}": pattern}) + | Q(**{f"normalized_name{suffix}": Alias.normalize(pattern)}) ) else: note_qs = note_qs.none() diff --git a/apps/api/tests.py b/apps/api/tests.py index 83d9d936..6be818bf 100644 --- a/apps/api/tests.py +++ b/apps/api/tests.py @@ -14,7 +14,6 @@ from django.test import TestCase from django_filters.rest_framework import DjangoFilterBackend from phonenumbers import PhoneNumber from rest_framework.filters import OrderingFilter - from api.filters import RegexSafeSearchFilter from member.models import Membership, Club from note.models import NoteClub, NoteUser, Alias, Note diff --git a/apps/api/viewsets.py b/apps/api/viewsets.py index 341af617..b1d42c50 100644 --- a/apps/api/viewsets.py +++ b/apps/api/viewsets.py @@ -1,6 +1,8 @@ # Copyright (C) 2018-2024 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later +import re + from django.contrib.contenttypes.models import ContentType from django_filters.rest_framework import DjangoFilterBackend from django.db.models import Q @@ -14,6 +16,14 @@ from .filters import RegexSafeSearchFilter from .serializers import UserSerializer, ContentTypeSerializer +def is_regex(pattern): + try: + re.compile(pattern) + return True + except (re.error, TypeError): + return False + + class ReadProtectedModelViewSet(ModelViewSet): """ Protect a ModelViewSet by filtering the objects that the user cannot see. @@ -60,34 +70,38 @@ class UserViewSet(ReadProtectedModelViewSet): if "search" in self.request.GET: pattern = self.request.GET["search"] + # Check if this is a valid regex. If not, we won't check regex + valid_regex = is_regex(pattern) + suffix = "__iregex" if valid_regex else "__istartswith" + prefix = "^" if valid_regex else "" # Filter with different rules # We use union-all to keep each filter rule sorted in result queryset = queryset.filter( # Match without normalization - note__alias__name__iregex="^" + pattern + Q(**{f"note__alias__name{suffix}": prefix + pattern}) ).union( queryset.filter( # Match with normalization - Q(note__alias__normalized_name__iregex="^" + Alias.normalize(pattern)) - & ~Q(note__alias__name__iregex="^" + pattern) + Q(**{f"note__alias__normalized_name{suffix}": prefix + Alias.normalize(pattern)}) + & ~Q(**{f"note__alias__name{suffix}": prefix + pattern}) ), all=True, ).union( queryset.filter( # Match on lower pattern - Q(note__alias__normalized_name__iregex="^" + pattern.lower()) - & ~Q(note__alias__normalized_name__iregex="^" + Alias.normalize(pattern)) - & ~Q(note__alias__name__iregex="^" + pattern) + Q(**{f"note__alias__normalized_name{suffix}": prefix + pattern.lower()}) + & ~Q(**{f"note__alias__normalized_name{suffix}": prefix + Alias.normalize(pattern)}) + & ~Q(**{f"note__alias__name{suffix}": prefix + pattern}) ), all=True, ).union( queryset.filter( # Match on firstname or lastname - (Q(last_name__iregex="^" + pattern) | Q(first_name__iregex="^" + pattern)) - & ~Q(note__alias__normalized_name__iregex="^" + pattern.lower()) - & ~Q(note__alias__normalized_name__iregex="^" + Alias.normalize(pattern)) - & ~Q(note__alias__name__iregex="^" + pattern) + (Q(**{f"last_name{suffix}": prefix + pattern}) | Q(**{f"first_name{suffix}": prefix + pattern})) + & ~Q(**{f"note__alias__normalized_name{suffix}": prefix + pattern.lower()}) + & ~Q(**{f"note__alias__normalized_name{suffix}": prefix + Alias.normalize(pattern)}) + & ~Q(**{f"note__alias__name{suffix}": prefix + pattern}) ), all=True, ) diff --git a/apps/logs/api/views.py b/apps/logs/api/views.py index bf5aa8a5..655a473a 100644 --- a/apps/logs/api/views.py +++ b/apps/logs/api/views.py @@ -3,7 +3,6 @@ from django_filters.rest_framework import DjangoFilterBackend from rest_framework.filters import OrderingFilter - from api.viewsets import ReadOnlyProtectedModelViewSet from .serializers import ChangelogSerializer diff --git a/apps/member/api/views.py b/apps/member/api/views.py index 5e4e4667..a24a12d6 100644 --- a/apps/member/api/views.py +++ b/apps/member/api/views.py @@ -3,7 +3,6 @@ from django_filters.rest_framework import DjangoFilterBackend from rest_framework.filters import OrderingFilter - from api.filters import RegexSafeSearchFilter from api.viewsets import ReadProtectedModelViewSet diff --git a/apps/member/views.py b/apps/member/views.py index 45ba81a7..61a7bbf2 100644 --- a/apps/member/views.py +++ b/apps/member/views.py @@ -18,6 +18,7 @@ from django.views.generic import DetailView, UpdateView, TemplateView from django.views.generic.edit import FormMixin from django_tables2.views import SingleTableView from rest_framework.authtoken.models import Token +from api.viewsets import is_regex from note.models import Alias, NoteClub, NoteUser, Trust from note.models.transactions import Transaction, SpecialTransaction from note.tables import HistoryTable, AliasTable, TrustTable, TrustedTable @@ -219,16 +220,20 @@ class UserListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView): if "search" in self.request.GET and self.request.GET["search"]: pattern = self.request.GET["search"] + # Check if this is a valid regex. If not, we won't check regex + valid_regex = is_regex(pattern) + suffix = "__iregex" if valid_regex else "__istartswith" + prefix = "^" if valid_regex else "" qs = qs.filter( - username__iregex="^" + pattern + Q(**{f"username{suffix}": prefix + pattern}) ).union( qs.filter( - (Q(alias__iregex="^" + pattern) - | Q(normalized_alias__iregex="^" + Alias.normalize(pattern)) - | Q(last_name__iregex="^" + pattern) - | Q(first_name__iregex="^" + pattern) + (Q(**{f"alias{suffix}": prefix + pattern}) + | Q(**{f"normalized_alias{suffix}": prefix + Alias.normalize(pattern)}) + | Q(**{f"last_name{suffix}": prefix + pattern}) + | Q(**{f"first_name{suffix}": prefix + pattern}) | Q(email__istartswith=pattern)) - & ~Q(username__iregex="^" + pattern) + & ~Q(**{f"username{suffix}": prefix + pattern}) ), all=True) else: qs = qs.none() @@ -410,10 +415,15 @@ class ClubListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView): if "search" in self.request.GET: pattern = self.request.GET["search"] + # Check if this is a valid regex. If not, we won't check regex + valid_regex = is_regex(pattern) + suffix = "__iregex" if valid_regex else "__istartswith" + prefix = "^" if valid_regex else "" + qs = qs.filter( - Q(name__iregex=pattern) - | Q(note__alias__name__iregex=pattern) - | Q(note__alias__normalized_name__iregex=Alias.normalize(pattern)) + Q(**{f"name{suffix}": prefix + pattern}) + | Q(**{f"note__alias__name{suffix}": prefix + pattern}) + | Q(**{f"note__alias__normalized_name{suffix}": prefix + Alias.normalize(pattern)}) ) return qs @@ -912,10 +922,15 @@ class ClubMembersListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableV if 'search' in self.request.GET: pattern = self.request.GET['search'] + + # Check if this is a valid regex. If not, we won't check regex + valid_regex = is_regex(pattern) + suffix = "__iregex" if valid_regex else "__istartswith" + prefix = "^" if valid_regex else "" qs = qs.filter( - Q(user__first_name__iregex='^' + pattern) - | Q(user__last_name__iregex='^' + pattern) - | Q(user__note__alias__normalized_name__iregex='^' + Alias.normalize(pattern)) + Q(**{f"user__first_name{suffix}": prefix + pattern}) + | Q(**{f"user__last_name{suffix}": prefix + pattern}) + | Q(**{f"user__note__alias__normalized_name{suffix}": prefix + Alias.normalize(pattern)}) ) only_active = "only_active" not in self.request.GET or self.request.GET["only_active"] != '0' diff --git a/apps/note/api/views.py b/apps/note/api/views.py index 4d39a7ce..ee1479be 100644 --- a/apps/note/api/views.py +++ b/apps/note/api/views.py @@ -1,19 +1,16 @@ # Copyright (C) 2018-2024 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later -import re - from django.conf import settings from django.db.models import Q from django.core.exceptions import ValidationError from django_filters.rest_framework import DjangoFilterBackend from rest_framework.filters import OrderingFilter -from rest_framework import viewsets +from rest_framework import status, viewsets from rest_framework.response import Response -from rest_framework import status - from api.filters import RegexSafeSearchFilter -from api.viewsets import ReadProtectedModelViewSet, ReadOnlyProtectedModelViewSet +from api.viewsets import ReadProtectedModelViewSet, ReadOnlyProtectedModelViewSet, \ + is_regex from permission.backends import PermissionBackend from .serializers import NotePolymorphicSerializer, AliasSerializer, ConsumerSerializer, \ @@ -51,10 +48,14 @@ class NotePolymorphicViewSet(ReadProtectedModelViewSet): .distinct() alias = self.request.query_params.get("alias", ".*") + # Check if this is a valid regex. If not, we won't check regex + valid_regex = is_regex(alias) + suffix = '__iregex' if valid_regex else '__istartswith' + alias_prefix = '^' if valid_regex else '' queryset = queryset.filter( - Q(alias__name__iregex="^" + alias) - | Q(alias__normalized_name__iregex="^" + Alias.normalize(alias)) - | Q(alias__normalized_name__iregex="^" + alias.lower()) + Q(**{f"alias__name{suffix}": alias_prefix + alias}) + | Q(**{f"alias__normalized_name{suffix}": alias_prefix + Alias.normalize(alias)}) + | Q(**{f"alias__normalized_name{suffix}": alias_prefix + alias.lower()}) ) return queryset.order_by("id") @@ -68,7 +69,7 @@ class TrustViewSet(ReadProtectedModelViewSet): """ queryset = Trust.objects serializer_class = TrustSerializer - filter_backends = [SearchFilter, DjangoFilterBackend, OrderingFilter] + filter_backends = [RegexSafeSearchFilter, DjangoFilterBackend, OrderingFilter] search_fields = ['$trusting__alias__name', '$trusting__alias__normalized_name', '$trusted__alias__name', '$trusted__alias__normalized_name'] filterset_fields = ['trusting', 'trusting__noteuser__user', 'trusted', 'trusted__noteuser__user'] @@ -94,7 +95,7 @@ class AliasViewSet(ReadProtectedModelViewSet): """ REST API View set. The djangorestframework plugin will get all `Alias` objects, serialize it to JSON with the given serializer, - then render it on /api/note/aliases/ + then render it on /api/note/alias/ """ queryset = Alias.objects serializer_class = AliasSerializer @@ -129,18 +130,22 @@ class AliasViewSet(ReadProtectedModelViewSet): alias = self.request.query_params.get("alias", None) if alias: + # Check if this is a valid regex. If not, we won't check regex + valid_regex = is_regex(alias) + suffix = '__iregex' if valid_regex else '__istartswith' + alias_prefix = '^' if valid_regex else '' queryset = queryset.filter( - name__iregex="^" + alias + **{f"name{suffix}": alias_prefix + alias} ).union( queryset.filter( - Q(normalized_name__iregex="^" + Alias.normalize(alias)) - & ~Q(name__iregex="^" + alias) + Q(**{f"normalized_name{suffix}": alias_prefix + Alias.normalize(alias)}) + & ~Q(**{f"name{suffix}": alias_prefix + alias}) ), all=True).union( queryset.filter( - Q(normalized_name__iregex="^" + alias.lower()) - & ~Q(normalized_name__iregex="^" + Alias.normalize(alias)) - & ~Q(name__iregex="^" + alias) + Q(**{f"normalized_name{suffix}": "^" + alias.lower()}) + & ~Q(**{f"normalized_name{suffix}": "^" + Alias.normalize(alias)}) + & ~Q(**{f"name{suffix}": "^" + alias}) ), all=True) @@ -169,11 +174,7 @@ class ConsumerViewSet(ReadOnlyProtectedModelViewSet): alias = self.request.query_params.get("alias", None) # Check if this is a valid regex. If not, we won't check regex - try: - re.compile(alias) - valid_regex = True - except (re.error, TypeError): - valid_regex = False + valid_regex = is_regex(alias) suffix = '__iregex' if valid_regex else '__istartswith' alias_prefix = '^' if valid_regex else '' queryset = queryset.prefetch_related('note') diff --git a/apps/note/views.py b/apps/note/views.py index a84e3636..7055ea12 100644 --- a/apps/note/views.py +++ b/apps/note/views.py @@ -13,6 +13,7 @@ from django.views.generic import CreateView, UpdateView, DetailView from django.urls import reverse_lazy from django_tables2 import SingleTableView from activity.models import Entry +from api.viewsets import is_regex from permission.backends import PermissionBackend from permission.views import ProtectQuerysetMixin from note_kfet.inputs import AmountInput @@ -89,11 +90,15 @@ class TransactionTemplateListView(ProtectQuerysetMixin, LoginRequiredMixin, Sing qs = super().get_queryset().distinct() if "search" in self.request.GET: pattern = self.request.GET["search"] + + # Check if this is a valid regex. If not, we won't check regex + valid_regex = is_regex(pattern) + suffix = "__iregex" if valid_regex else "__icontains" qs = qs.filter( - Q(name__iregex=pattern) - | Q(destination__club__name__iregex=pattern) - | Q(category__name__iregex=pattern) - | Q(description__iregex=pattern) + Q(**{f"name{suffix}": pattern}) + | Q(**{f"destination__club__name{suffix}": pattern}) + | Q(**{f"category__name{suffix}": pattern}) + | Q(**{f"description{suffix}": pattern}) ) qs = qs.order_by('-display', 'category__name', 'destination__club__name', 'name') @@ -223,7 +228,10 @@ class TransactionSearchView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView if "type" in data and data["type"]: transactions = transactions.filter(polymorphic_ctype__in=data["type"]) if "reason" in data and data["reason"]: - transactions = transactions.filter(reason__iregex=data["reason"]) + # Check if this is a valid regex. If not, we won't check regex + valid_regex = is_regex(data["reason"]) + suffix = "__iregex" if valid_regex else "__istartswith" + transactions = transactions.filter(Q(**{f"reason{suffix}": data["reason"]})) if "valid" in data and data["valid"]: transactions = transactions.filter(valid=data["valid"]) if "amount_gte" in data and data["amount_gte"]: diff --git a/apps/permission/api/views.py b/apps/permission/api/views.py index 1dd18899..39ff353c 100644 --- a/apps/permission/api/views.py +++ b/apps/permission/api/views.py @@ -2,7 +2,6 @@ # SPDX-License-Identifier: GPL-3.0-or-later from django_filters.rest_framework import DjangoFilterBackend - from api.filters import RegexSafeSearchFilter from api.viewsets import ReadOnlyProtectedModelViewSet @@ -20,7 +19,7 @@ class PermissionViewSet(ReadOnlyProtectedModelViewSet): serializer_class = PermissionSerializer filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter] filterset_fields = ['model', 'type', 'query', 'mask', 'field', 'permanent', ] - search_fields = ['$model__name', '$query', '$description', ] + search_fields = ['$model__model', '$query', '$description', ] class RoleViewSet(ReadOnlyProtectedModelViewSet): diff --git a/apps/registration/views.py b/apps/registration/views.py index 3dd820d7..58299da2 100644 --- a/apps/registration/views.py +++ b/apps/registration/views.py @@ -16,6 +16,7 @@ from django.views import View from django.views.generic import CreateView, TemplateView, DetailView from django.views.generic.edit import FormMixin from django_tables2 import SingleTableView +from api.viewsets import is_regex from member.forms import ProfileForm from member.models import Membership, Club from note.models import SpecialTransaction, Alias @@ -192,11 +193,16 @@ class FutureUserListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableVi if "search" in self.request.GET and self.request.GET["search"]: pattern = self.request.GET["search"] + # Check if this is a valid regex. If not, we won't check regex + valid_regex = is_regex(pattern) + suffix_username = "__iregex" if valid_regex else "__icontains" + suffix = "__iregex" if valid_regex else "__istartswith" + prefix = "^" if valid_regex else "" qs = qs.filter( - Q(first_name__iregex=pattern) - | Q(last_name__iregex=pattern) - | Q(profile__section__iregex=pattern) - | Q(username__iregex="^" + pattern) + Q(**{f"first_name{suffix}": pattern}) + | Q(**{f"last_name{suffix}": pattern}) + | Q(**{f"profile__section{suffix}": pattern}) + | Q(**{f"username{suffix_username}": prefix + pattern}) ) return qs diff --git a/apps/treasury/api/views.py b/apps/treasury/api/views.py index 8cdb79d8..418bf220 100644 --- a/apps/treasury/api/views.py +++ b/apps/treasury/api/views.py @@ -2,7 +2,6 @@ # SPDX-License-Identifier: GPL-3.0-or-later from django_filters.rest_framework import DjangoFilterBackend - from api.filters import RegexSafeSearchFilter from api.viewsets import ReadProtectedModelViewSet diff --git a/apps/treasury/views.py b/apps/treasury/views.py index be989f99..64692793 100644 --- a/apps/treasury/views.py +++ b/apps/treasury/views.py @@ -20,6 +20,7 @@ from django.views.generic import UpdateView, DetailView from django.views.generic.base import View, TemplateView from django.views.generic.edit import BaseFormView, DeleteView from django_tables2 import SingleTableView +from api.viewsets import is_regex from note.models import SpecialTransaction, NoteSpecial, Alias from note_kfet.settings.base import BASE_DIR from permission.backends import PermissionBackend @@ -411,11 +412,16 @@ class SogeCreditListView(LoginRequiredMixin, ProtectQuerysetMixin, SingleTableVi if "search" in self.request.GET: pattern = self.request.GET["search"] if pattern: + # Check if this is a valid regex. If not, we won't check regex + valid_regex = is_regex(pattern) + suffix_alias = "__iregex" if valid_regex else "__icontains" + suffix = "__iregex" if valid_regex else "__istartswith" + prefix = "^" if valid_regex else "" qs = qs.filter( - Q(user__first_name__iregex=pattern) - | Q(user__last_name__iregex=pattern) - | Q(user__note__alias__name__iregex="^" + pattern) - | Q(user__note__alias__normalized_name__iregex="^" + Alias.normalize(pattern)) + Q(**{f"user__first_name{suffix}": pattern}) + | Q(**{f"user__last_name{suffix}": pattern}) + | Q(**{f"user__note__alias__name{suffix_alias}": prefix + pattern}) + | Q(**{f"user__note__alias__normalized_name{suffix_alias}": prefix + Alias.normalize(pattern)}) ) if "valid" not in self.request.GET or not self.request.GET["valid"]: diff --git a/apps/wei/api/views.py b/apps/wei/api/views.py index 88189d70..13f04a91 100644 --- a/apps/wei/api/views.py +++ b/apps/wei/api/views.py @@ -3,7 +3,6 @@ from django_filters.rest_framework import DjangoFilterBackend from rest_framework.filters import OrderingFilter - from api.filters import RegexSafeSearchFilter from api.viewsets import ReadProtectedModelViewSet diff --git a/apps/wei/views.py b/apps/wei/views.py index 4771cb5b..af0ce968 100644 --- a/apps/wei/views.py +++ b/apps/wei/views.py @@ -23,6 +23,7 @@ from django.views.generic import DetailView, UpdateView, RedirectView, TemplateV from django.utils.translation import gettext_lazy as _ from django.views.generic.edit import BaseFormView, DeleteView from django_tables2 import SingleTableView +from api.viewsets import is_regex from member.models import Membership, Club from note.models import Transaction, NoteClub, Alias, SpecialTransaction, NoteSpecial from note.tables import HistoryTable @@ -219,13 +220,18 @@ class WEIMembershipsView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableVi if not pattern: return qs.none() + # Check if this is a valid regex. If not, we won't check regex + valid_regex = is_regex(pattern) + suffix_alias = "__iregex" if valid_regex else "__istartswith" + suffix = "__iregex" if valid_regex else "__icontains" + prefix = "^" if valid_regex else "" qs = qs.filter( - Q(user__first_name__iregex=pattern) - | Q(user__last_name__iregex=pattern) - | Q(user__note__alias__name__iregex="^" + pattern) - | Q(user__note__alias__normalized_name__iregex="^" + Alias.normalize(pattern)) - | Q(bus__name__iregex=pattern) - | Q(team__name__iregex=pattern) + Q(**{f"user__first_name{suffix}": pattern}) + | Q(**{f"user__last_name{suffix}": pattern}) + | Q(**{f"user__note__alias__name{suffix_alias}": prefix + pattern}) + | Q(**{f"user__note__alias__normalized_name{suffix_alias}": prefix + Alias.normalize(pattern)}) + | Q(**{f"bus__name{suffix}": pattern}) + | Q(**{f"team__name{suffix}": pattern}) ) return qs @@ -255,11 +261,16 @@ class WEIRegistrationsView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTable pattern = self.request.GET.get("search", "") if pattern: + # Check if this is a valid regex. If not, we won't check regex + valid_regex = is_regex(pattern) + suffix_alias = "__iregex" if valid_regex else "__istartswith" + suffix = "__iregex" if valid_regex else "__icontains" + prefix = "^" if valid_regex else "" qs = qs.filter( - Q(user__first_name__iregex=pattern) - | Q(user__last_name__iregex=pattern) - | Q(user__note__alias__name__iregex="^" + pattern) - | Q(user__note__alias__normalized_name__iregex="^" + Alias.normalize(pattern)) + Q(**{f"user__first_name{suffix}": pattern}) + | Q(**{f"user__last_name{suffix}": pattern}) + | Q(**{f"user__note__alias__name{suffix_alias}": prefix + pattern}) + | Q(**{f"user__note__alias__normalized_name{suffix_alias}": prefix + Alias.normalize(pattern)}) ) return qs From b0c7d43a500b14491b03b598f58981f47d421799 Mon Sep 17 00:00:00 2001 From: Emmy D'ANELLO Date: Mon, 29 Aug 2022 13:19:19 +0200 Subject: [PATCH 18/33] De l'inclusif, partout Signed-off-by: Emmy D'ANELLO --- .gitmodules | 2 +- README.md | 2 +- apps/logs/signals.py | 8 +- apps/member/forms.py | 4 +- apps/member/models.py | 4 +- apps/member/views.py | 6 +- .../note/mails/negative_balance.html | 2 +- .../templates/note/mails/negative_balance.txt | 2 +- apps/permission/fixtures/initial.json | 72 ++++---- apps/permission/tables.py | 4 +- apps/permission/tests/test_oauth2.py | 4 +- apps/permission/views.py | 4 +- apps/registration/views.py | 4 +- apps/scripts | 2 +- apps/wei/forms/registration.py | 2 +- .../commands/export_wei_registrations.py | 2 +- apps/wei/tests/test_wei_registration.py | 4 +- apps/wei/views.py | 4 +- docs/api/index.rst | 11 +- docs/api/member.rst | 2 +- docs/api/wei.rst | 4 +- docs/apps/activity.rst | 36 ++-- docs/apps/index.rst | 37 ++-- docs/apps/logs.rst | 12 +- docs/apps/member.rst | 82 ++++----- docs/apps/note/consumptions.rst | 22 +-- docs/apps/note/index.rst | 4 +- docs/apps/note/transfers.rst | 4 +- docs/apps/permission.rst | 30 ++-- docs/apps/registration.rst | 22 +-- docs/apps/treasury.rst | 34 ++-- docs/apps/wei.rst | 116 ++++++------- docs/external_services/cas.rst | 2 +- docs/external_services/index.rst | 6 +- docs/external_services/oauth2.rst | 38 ++-- docs/faq.rst | 66 +++---- docs/getting_started.rst | 36 ++-- docs/index.rst | 2 +- docs/install-dev.rst | 8 +- docs/install.rst | 6 +- docs/scripts.rst | 42 ++--- locale/de/LC_MESSAGES/django.po | 6 +- locale/es/LC_MESSAGES/django.po | 6 +- locale/fr/LC_MESSAGES/django.po | 163 +++++++++--------- 44 files changed, 467 insertions(+), 462 deletions(-) diff --git a/.gitmodules b/.gitmodules index 925f7178..ffc15af5 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "apps/scripts"] path = apps/scripts - url = https://gitlab.crans.org/bde/nk20-scripts.git + url = https://gitlab.crans.org/bde/nk20-scripts diff --git a/README.md b/README.md index 98fe3713..7297a1b6 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ Bien que cela permette de créer une instance sur toutes les distributions, (env)$ ./manage.py makemigrations (env)$ ./manage.py migrate (env)$ ./manage.py loaddata initial - (env)$ ./manage.py createsuperuser # Création d'un utilisateur initial + (env)$ ./manage.py createsuperuser # Création d'un⋅e utilisateur⋅rice initial ``` 6. Enjoy : diff --git a/apps/logs/signals.py b/apps/logs/signals.py index c331e89e..c4fc08f3 100644 --- a/apps/logs/signals.py +++ b/apps/logs/signals.py @@ -56,13 +56,13 @@ def save_object(sender, instance, **kwargs): # noinspection PyProtectedMember previous = instance._previous - # Si un utilisateur est connecté, on récupère l'utilisateur courant ainsi que son adresse IP + # Si un⋅e utilisateur⋅rice est connecté⋅e, on récupère l'utilisateur⋅rice courant⋅e ainsi que son adresse IP request = get_current_request() if request is None: # Si la modification n'a pas été faite via le client Web, on suppose que c'est du à `manage.py` # On récupère alors l'utilisateur·trice connecté·e à la VM, et on récupère la note associée - # IMPORTANT : l'utilisateur dans la VM doit être un des alias note du respo info + # IMPORTANT : l'utilisateur⋅rice dans la VM doit être un des alias note du respo info ip = "127.0.0.1" username = Alias.normalize(getpass.getuser()) note = NoteUser.objects.filter(alias__normalized_name=username) @@ -134,13 +134,13 @@ def delete_object(sender, instance, **kwargs): if instance._meta.label_lower in EXCLUDED or hasattr(instance, "_no_signal"): return - # Si un utilisateur est connecté, on récupère l'utilisateur courant ainsi que son adresse IP + # Si un⋅e utilisateur⋅rice est connecté⋅e, on récupère l'utilisateur⋅rice courant⋅e ainsi que son adresse IP request = get_current_request() if request is None: # Si la modification n'a pas été faite via le client Web, on suppose que c'est du à `manage.py` # On récupère alors l'utilisateur·trice connecté·e à la VM, et on récupère la note associée - # IMPORTANT : l'utilisateur dans la VM doit être un des alias note du respo info + # IMPORTANT : l'utilisateur⋅rice dans la VM doit être un des alias note du respo info ip = "127.0.0.1" username = Alias.normalize(getpass.getuser()) note = NoteUser.objects.filter(alias__normalized_name=username) diff --git a/apps/member/forms.py b/apps/member/forms.py index 33a29ebd..ad295b41 100644 --- a/apps/member/forms.py +++ b/apps/member/forms.py @@ -210,9 +210,9 @@ class MembershipForm(forms.ModelForm): class Meta: model = Membership fields = ('user', 'date_start') - # Le champ d'utilisateur est remplacé par un champ d'auto-complétion. + # Le champ d'utilisateur⋅rice est remplacé par un champ d'auto-complétion. # Quand des lettres sont tapées, une requête est envoyée sur l'API d'auto-complétion - # et récupère les noms d'utilisateur valides + # et récupère les noms d'utilisateur⋅rices valides widgets = { 'user': Autocomplete( diff --git a/apps/member/models.py b/apps/member/models.py index 4f78ecd3..e0f4f659 100644 --- a/apps/member/models.py +++ b/apps/member/models.py @@ -473,10 +473,10 @@ class Membership(models.Model): if self.club.parent_club.name == "BDE": parent_membership.roles.set( - Role.objects.filter(Q(name="Adhérent BDE") | Q(name="Membre de club")).all()) + Role.objects.filter(Q(name="Adhérent⋅e BDE") | Q(name="Membre de club")).all()) elif self.club.parent_club.name == "Kfet": parent_membership.roles.set( - Role.objects.filter(Q(name="Adhérent Kfet") | Q(name="Membre de club")).all()) + Role.objects.filter(Q(name="Adhérent⋅e Kfet") | Q(name="Membre de club")).all()) else: parent_membership.roles.set(Role.objects.filter(name="Membre de club").all()) parent_membership.save() diff --git a/apps/member/views.py b/apps/member/views.py index 45ba81a7..d652b6b0 100644 --- a/apps/member/views.py +++ b/apps/member/views.py @@ -827,8 +827,8 @@ class ClubAddMemberView(ProtectQuerysetMixin, ProtectedCreateView): ret = super().form_valid(form) - member_role = Role.objects.filter(Q(name="Adhérent BDE") | Q(name="Membre de club")).all() \ - if club.name == "BDE" else Role.objects.filter(Q(name="Adhérent Kfet") | Q(name="Membre de club")).all() \ + member_role = Role.objects.filter(Q(name="Adhérent⋅e BDE") | Q(name="Membre de club")).all() \ + if club.name == "BDE" else Role.objects.filter(Q(name="Adhérent⋅e Kfet") | Q(name="Membre de club")).all() \ if club.name == "Kfet"else Role.objects.filter(name="Membre de club").all() # Set the same roles as before if old_membership: @@ -864,7 +864,7 @@ class ClubAddMemberView(ProtectQuerysetMixin, ProtectedCreateView): membership.refresh_from_db() if old_membership.exists(): membership.roles.set(old_membership.get().roles.all()) - membership.roles.set(Role.objects.filter(Q(name="Adhérent Kfet") | Q(name="Membre de club")).all()) + membership.roles.set(Role.objects.filter(Q(name="Adhérent⋅e Kfet") | Q(name="Membre de club")).all()) membership.save() return ret diff --git a/apps/note/templates/note/mails/negative_balance.html b/apps/note/templates/note/mails/negative_balance.html index 70af1f0f..04b2dd6a 100644 --- a/apps/note/templates/note/mails/negative_balance.html +++ b/apps/note/templates/note/mails/negative_balance.html @@ -22,7 +22,7 @@

- Par ailleurs, le BDE ne sert pas d'alcool aux adhérents dont le solde + Par ailleurs, le BDE ne sert pas d'alcool aux adhérent⋅es dont le solde est inférieur à 0 €.

diff --git a/apps/note/templates/note/mails/negative_balance.txt b/apps/note/templates/note/mails/negative_balance.txt index 8707bde5..638d82f6 100644 --- a/apps/note/templates/note/mails/negative_balance.txt +++ b/apps/note/templates/note/mails/negative_balance.txt @@ -22,4 +22,4 @@ virement bancaire. -- Le BDE -{% trans "Mail generated by the Note Kfet on the" %} {% now "j F Y à H:i:s" %} \ No newline at end of file +{% trans "Mail generated by the Note Kfet on the" %} {% now "j F Y à H:i:s" %} diff --git a/apps/permission/fixtures/initial.json b/apps/permission/fixtures/initial.json index b59fdb61..82b058f2 100644 --- a/apps/permission/fixtures/initial.json +++ b/apps/permission/fixtures/initial.json @@ -36,7 +36,7 @@ "mask": 1, "field": "", "permanent": true, - "description": "Voir son compte utilisateur" + "description": "Voir son compte utilisateur⋅rice" } }, { @@ -68,7 +68,7 @@ "mask": 1, "field": "", "permanent": true, - "description": "Voir sa propre note d'utilisateur" + "description": "Voir sa propre note d'utilisateur⋅rice" } }, { @@ -116,7 +116,7 @@ "mask": 1, "field": "", "permanent": false, - "description": "Voir les aliases des notes des clubs et des adhérents du club BDE" + "description": "Voir les alias des notes des clubs et des adhérent⋅es du club BDE" } }, { @@ -772,7 +772,7 @@ "mask": 3, "field": "", "permanent": false, - "description": "Voir les adhérents du club" + "description": "Voir les adhérent⋅es du club" } }, { @@ -788,7 +788,7 @@ "mask": 2, "field": "", "permanent": false, - "description": "Ajouter un membre à un club" + "description": "Ajouter un⋅e membre à un club" } }, { @@ -852,7 +852,7 @@ "mask": 3, "field": "", "permanent": false, - "description": "Modifier n'importe quel utilisateur" + "description": "Modifier n'importe quel⋅le utilisateur⋅rice" } }, { @@ -868,7 +868,7 @@ "mask": 3, "field": "", "permanent": false, - "description": "Ajouter un utilisateur" + "description": "Ajouter un⋅e utilisateur⋅rice" } }, { @@ -1284,7 +1284,7 @@ "mask": 2, "field": "", "permanent": false, - "description": "Inscrire un 1A au WEI" + "description": "Inscrire un⋅e 1A au WEI" } }, { @@ -1956,7 +1956,7 @@ "mask": 1, "field": "", "permanent": true, - "description": "Voir mes activitées passées, même après la fin de l'adhésion BDE" + "description": "Voir mes activités passées, même après la fin de l'adhésion BDE" } }, { @@ -2100,7 +2100,7 @@ "mask": 3, "field": "", "permanent": false, - "description": "Voir n'importe quel utilisateur" + "description": "Voir n'importe quel⋅le utilisateur⋅rice" } }, { @@ -2228,7 +2228,7 @@ "mask": 3, "field": "", "permanent": false, - "description": "Créer une note d'utilisateur" + "description": "Créer une note d'utilisateur⋅rice" } }, { @@ -2276,7 +2276,7 @@ "mask": 3, "field": "", "permanent": false, - "description": "Voir tous les adhérents de tous les clubs" + "description": "Voir toustes les adhérent⋅es de tous les clubs" } }, { @@ -2292,7 +2292,7 @@ "mask": 3, "field": "", "permanent": false, - "description": "Ajouter un membre à n'importe quel club" + "description": "Ajouter un⋅e membre à n'importe quel club" } }, { @@ -2372,7 +2372,7 @@ "mask": 1, "field": "name", "permanent": false, - "description": "Modifier le nom d'une activité non validée dont on est l'auteur" + "description": "Modifier le nom d'une activité non validée dont on est l'auteur⋅rice" } }, { @@ -2388,7 +2388,7 @@ "mask": 1, "field": "description", "permanent": false, - "description": "Modifier la description d'une activité non validée dont on est l'auteur" + "description": "Modifier la description d'une activité non validée dont on est l'auteur⋅rice" } }, { @@ -2404,7 +2404,7 @@ "mask": 1, "field": "location", "permanent": false, - "description": "Modifier le lieu d'une activité non validée dont on est l'auteur" + "description": "Modifier le lieu d'une activité non validée dont on est l'auteur⋅rice" } }, { @@ -2420,7 +2420,7 @@ "mask": 1, "field": "activity_type", "permanent": false, - "description": "Modifier le type d'une activité non validée dont on est l'auteur" + "description": "Modifier le type d'une activité non validée dont on est l'auteur⋅rice" } }, { @@ -2436,7 +2436,7 @@ "mask": 1, "field": "organizer", "permanent": false, - "description": "Modifier l'organisateur d'une activité non validée dont on est l'auteur" + "description": "Modifier l'organisateur d'une activité non validée dont on est l'auteur⋅rice" } }, { @@ -2452,7 +2452,7 @@ "mask": 1, "field": "attendees_club", "permanent": false, - "description": "Modifier le club attendu d'une activité non validée dont on est l'auteur" + "description": "Modifier le club attendu d'une activité non validée dont on est l'auteur⋅rice" } }, { @@ -2468,7 +2468,7 @@ "mask": 1, "field": "date_start", "permanent": false, - "description": "Modifier la date de début d'une activité non validée dont on est l'auteur" + "description": "Modifier la date de début d'une activité non validée dont on est l'auteur⋅rice" } }, { @@ -2484,7 +2484,7 @@ "mask": 1, "field": "date_end", "permanent": false, - "description": "Modifier la date de fin d'une activité non validée dont on est l'auteur" + "description": "Modifier la date de fin d'une activité non validée dont on est l'auteur⋅rice" } }, { @@ -2756,7 +2756,7 @@ "mask": 3, "field": "", "permanent": false, - "description": "Modifier n'importe quel utilisateur non encore inscrit" + "description": "Modifier n'importe quel⋅le utilisateur⋅rice non encore inscrit⋅e" } }, { @@ -2788,7 +2788,7 @@ "mask": 3, "field": "", "permanent": false, - "description": "Voir tous les alias, y compris ceux des non adhérents" + "description": "Voir tous les alias, y compris ceux des non adhérent⋅es" } }, { @@ -2820,7 +2820,7 @@ "mask": 2, "field": "", "permanent": false, - "description": "Voir n'importe quel utilisateur non encore inscrit" + "description": "Voir n'importe quel⋅le utilisateur⋅rice non encore inscrit⋅e" } }, { @@ -2847,12 +2847,12 @@ "auth", "user" ], - "query": "{\"memberships__club__name\": \"BDE\", \"memberships__roles__name\": \"Adhérent BDE\", \"memberships__date_start__lte\": [\"today\"], \"memberships__date_end__gte\": [\"today\"]}", + "query": "{\"memberships__club__name\": \"BDE\", \"memberships__roles__name\": \"Adhérent⋅e BDE\", \"memberships__date_start__lte\": [\"today\"], \"memberships__date_end__gte\": [\"today\"]}", "type": "view", "mask": 2, "field": "", "permanent": false, - "description": "Voir n'importe quel utilisateur qui est adhérent BDE" + "description": "Voir n'importe quel⋅le utilisateur⋅rice qui est adhérent⋅e BDE" } }, { @@ -3044,7 +3044,7 @@ "mask": 3, "field": "", "permanent": false, - "description": "Voir toutes les amitiés, y compris celles des non adhérents" + "description": "Voir toutes les amitiés, y compris celles des non adhérent⋅es" } }, { @@ -3116,7 +3116,7 @@ "pk": 1, "fields": { "for_club": 1, - "name": "Adh\u00e9rent BDE", + "name": "Adh\u00e9rent\u22c5e BDE", "permissions": [ 1, 2, @@ -3161,7 +3161,7 @@ "pk": 2, "fields": { "for_club": 2, - "name": "Adh\u00e9rent Kfet", + "name": "Adh\u00e9rent\u22c5e Kfet", "permissions": [ 22, 36, @@ -3225,7 +3225,7 @@ "pk": 5, "fields": { "for_club": null, - "name": "Pr\u00e9sident\u00b7e de club", + "name": "Pr\u00e9sident\u22c5e de club", "permissions": [ 62, 142, @@ -3238,7 +3238,7 @@ "pk": 6, "fields": { "for_club": null, - "name": "Tr\u00e9sorier\u00b7\u00e8re de club", + "name": "Tr\u00e9sorièr\u22c5e de club", "permissions": [ 19, 20, @@ -3262,7 +3262,7 @@ "pk": 7, "fields": { "for_club": 1, - "name": "Pr\u00e9sident\u00b7e BDE", + "name": "Pr\u00e9sident\u22c5e BDE", "permissions": [ 24, 25, @@ -3291,7 +3291,7 @@ "pk": 8, "fields": { "for_club": 1, - "name": "Tr\u00e9sorier\u00b7\u00e8re BDE", + "name": "Tr\u00e9sorièr\u22c5e BDE", "permissions": [ 23, 24, @@ -3459,7 +3459,7 @@ "pk": 13, "fields": { "for_club": null, - "name": "Chef de bus", + "name": "Chef\u22c5fe de bus", "permissions": [ 22, 84, @@ -3478,7 +3478,7 @@ "pk": 14, "fields": { "for_club": null, - "name": "Chef d'\u00e9quipe", + "name": "Chef\u22c5fe d'\u00e9quipe", "permissions": [ 22, 84, @@ -3527,7 +3527,7 @@ "pk": 18, "fields": { "for_club": null, - "name": "Adhérent WEI", + "name": "Adhérent\u22c5e WEI", "permissions": [ 77, 114 diff --git a/apps/permission/tables.py b/apps/permission/tables.py index 894d4d13..955b14bb 100644 --- a/apps/permission/tables.py +++ b/apps/permission/tables.py @@ -36,8 +36,8 @@ class RightsTable(tables.Table): def render_roles(self, record): # If the user has the right to manage the roles, display the link to manage them - roles = record.roles.filter((~(Q(name="Adhérent BDE") - | Q(name="Adhérent Kfet") + roles = record.roles.filter((~(Q(name="Adhérent⋅e BDE") + | Q(name="Adhérent⋅e Kfet") | Q(name="Membre de club") | Q(name="Bureau de club")) & Q(weirole__isnull=True))).all() diff --git a/apps/permission/tests/test_oauth2.py b/apps/permission/tests/test_oauth2.py index b37902b5..889ad588 100644 --- a/apps/permission/tests/test_oauth2.py +++ b/apps/permission/tests/test_oauth2.py @@ -58,7 +58,7 @@ class OAuth2TestCase(TestCase): # Create membership to validate permissions NoteUser.objects.create(user=self.user) membership = Membership.objects.create(user=self.user, club_id=bde.pk) - membership.roles.add(Role.objects.get(name="Adhérent BDE")) + membership.roles.add(Role.objects.get(name="Adhérent⋅e BDE")) membership.save() # User is now a member and can now see its own user detail @@ -85,7 +85,7 @@ class OAuth2TestCase(TestCase): bde = Club.objects.get(name="BDE") NoteUser.objects.create(user=self.user) membership = Membership.objects.create(user=self.user, club_id=bde.pk) - membership.roles.add(Role.objects.get(name="Adhérent BDE")) + membership.roles.add(Role.objects.get(name="Adhérent⋅e BDE")) membership.save() resp = self.client.get(reverse('permission:scopes')) diff --git a/apps/permission/views.py b/apps/permission/views.py index 77e5a4d0..3812a140 100644 --- a/apps/permission/views.py +++ b/apps/permission/views.py @@ -131,8 +131,8 @@ class RightsView(TemplateView): special_memberships = Membership.objects.filter( date_start__lte=date.today(), date_end__gte=date.today(), - ).filter(roles__in=Role.objects.filter((~(Q(name="Adhérent BDE") - | Q(name="Adhérent Kfet") + ).filter(roles__in=Role.objects.filter((~(Q(name="Adhérent⋅e BDE") + | Q(name="Adhérent⋅e Kfet") | Q(name="Membre de club") | Q(name="Bureau de club")) & Q(weirole__isnull=True))))\ diff --git a/apps/registration/views.py b/apps/registration/views.py index 3dd820d7..0166902c 100644 --- a/apps/registration/views.py +++ b/apps/registration/views.py @@ -377,7 +377,7 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin, # membership._soge = True membership.save() membership.refresh_from_db() - membership.roles.add(Role.objects.get(name="Adhérent BDE")) + membership.roles.add(Role.objects.get(name="Adhérent⋅e BDE")) membership.save() if join_kfet: @@ -391,7 +391,7 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin, # membership._soge = True membership.save() membership.refresh_from_db() - membership.roles.add(Role.objects.get(name="Adhérent Kfet")) + membership.roles.add(Role.objects.get(name="Adhérent⋅e Kfet")) membership.save() for club, join_club in join_clubs: diff --git a/apps/scripts b/apps/scripts index f580f9b9..472c9c33 160000 --- a/apps/scripts +++ b/apps/scripts @@ -1 +1 @@ -Subproject commit f580f9b9e9beee76605975fdbc3a2014769e3c61 +Subproject commit 472c9c33cea3a9c277033f2108fd81304fb62097 diff --git a/apps/wei/forms/registration.py b/apps/wei/forms/registration.py index 808d7eda..94c1d5e8 100644 --- a/apps/wei/forms/registration.py +++ b/apps/wei/forms/registration.py @@ -74,7 +74,7 @@ class WEIChooseBusForm(forms.Form): queryset=WEIRole.objects.filter(~Q(name="1A")), label=_("WEI Roles"), help_text=_("Select the roles that you are interested in."), - initial=WEIRole.objects.filter(name="Adhérent WEI").all(), + initial=WEIRole.objects.filter(name="Adhérent⋅e WEI").all(), widget=CheckboxSelectMultiple(), ) diff --git a/apps/wei/management/commands/export_wei_registrations.py b/apps/wei/management/commands/export_wei_registrations.py index ca3dc06c..39fd238a 100644 --- a/apps/wei/management/commands/export_wei_registrations.py +++ b/apps/wei/management/commands/export_wei_registrations.py @@ -84,5 +84,5 @@ class Command(BaseCommand): s += sep + user.profile.section_generated s += sep + bus.name s += sep + (team.name if team else "--") - s += sep + ", ".join(role.name for role in membership.roles.filter(~Q(name="Adhérent WEI")).all()) + s += sep + ", ".join(role.name for role in membership.roles.filter(~Q(name="Adhérent⋅e WEI")).all()) self.stdout.write(s) diff --git a/apps/wei/tests/test_wei_registration.py b/apps/wei/tests/test_wei_registration.py index 74fdcf0b..4422b324 100644 --- a/apps/wei/tests/test_wei_registration.py +++ b/apps/wei/tests/test_wei_registration.py @@ -504,7 +504,7 @@ class TestWEIRegistration(TestCase): emergency_contact_phone='+33600000000', bus=[self.bus.id], team=[self.team.id], - roles=[role.id for role in WEIRole.objects.filter(name="Adhérent WEI").all()], + roles=[role.id for role in WEIRole.objects.filter(name="Adhérent⋅e WEI").all()], information_json=self.registration.information_json, ) ) @@ -558,7 +558,7 @@ class TestWEIRegistration(TestCase): emergency_contact_phone='+33600000000', bus=[self.bus.id], team=[self.team.id], - roles=[role.id for role in WEIRole.objects.filter(name="Adhérent WEI").all()], + roles=[role.id for role in WEIRole.objects.filter(name="Adhérent⋅e WEI").all()], information_json=self.registration.information_json, ) ) diff --git a/apps/wei/views.py b/apps/wei/views.py index 4771cb5b..ce1e5791 100644 --- a/apps/wei/views.py +++ b/apps/wei/views.py @@ -916,7 +916,7 @@ class WEIValidateRegistrationView(ProtectQuerysetMixin, ProtectedCreateView): form["team"].initial = BusTeam.objects.get(pk=information["preferred_team_pk"][0]) if "preferred_roles_pk" in information: form["roles"].initial = WEIRole.objects.filter( - Q(pk__in=information["preferred_roles_pk"]) | Q(name="Adhérent WEI") + Q(pk__in=information["preferred_roles_pk"]) | Q(name="Adhérent⋅e WEI") ).all() return form @@ -1008,7 +1008,7 @@ class WEIValidateRegistrationView(ProtectQuerysetMixin, ProtectedCreateView): membership.save() membership.refresh_from_db() - membership.roles.add(WEIRole.objects.get(name="Adhérent WEI")) + membership.roles.add(WEIRole.objects.get(name="Adhérent⋅e WEI")) return super().form_valid(form) diff --git a/docs/api/index.rst b/docs/api/index.rst index fc55fc5c..2f75dbb8 100644 --- a/docs/api/index.rst +++ b/docs/api/index.rst @@ -23,7 +23,7 @@ Pages de l'API Il suffit d'ajouter le préfixe ``/api/`` pour arriver sur ces pages. * `models `_ : liste des différents modèles enregistrés en base de données -* `user `_ : liste des différents utilisateurs enregistrés +* `user `_ : liste des différent⋅es utilisateur⋅rices enregistrés * `members/profile `_ : liste des différents profils associés à des utilisateurs * `members/club `_ : liste des différents clubs enregistrés * `members/membership `_ : liste des adhésions enregistrées @@ -69,7 +69,7 @@ S'authentifier L'authentification peut se faire soit par session en se connectant via la page de connexion classique, soit via un jeton d'authentification. Le jeton peut se récupérer via la page de son propre compte, en cliquant -sur le bouton « `Accès API `_ ». Il peut être révoqué et regénéré +sur le bouton « `Accès API `_ ». Il peut être révoqué et régénéré en un clic. Pour s'authentifier via ce jeton, il faut ajouter l'en-tête ``Authorization: Token `` aux paramètres HTTP. @@ -111,7 +111,7 @@ Trois types de filtres sont implémentés : Les filtres disponibles sont indiqués sur chacune des pages de documentation. -Le résultat est déjà par défaut filtré par droits : seuls les éléments que l'utilisateur à le droit de voir sont affichés. +Le résultat est déjà par défaut filtré par droits : seuls les éléments que l'utilisateur⋅rice a le droit de voir sont affichés. Cela est possible grâce à la structure des permissions, générant justement des filtres de requêtes de base de données. Une requête à l'adresse ``/api///`` affiche directement les informations du modèle demandé au format JSON. @@ -126,8 +126,9 @@ Des exceptions sont faites sur certaines pages : les pages de logs et de content Les formats supportés sont multiples : ``application/json``, ``application/x-www-url-encoded``, ``multipart/form-data``. Cela facilite l'envoi de requêtes. Le module construit ensuite l'instance du modèle et le sauvegarde dans la base de -données. L'application ``permission`` s'assure que l'utilisateur à le droit de faire ce type de modification. La réponse -renvoyée est l'objet enregistré au format JSON si l'ajout s'est bien déroulé, sinon un message d'erreur au format JSON. +données. L'application ``permission`` s'assure que l'utilisateur⋅rice a le droit de faire ce type de modification. +La réponse renvoyée est l'objet enregistré au format JSON si l'ajout s'est bien déroulé, sinon un message d'erreur au +format JSON. PATCH ~~~~~ diff --git a/docs/api/member.rst b/docs/api/member.rst index 88d4c874..5aa1fe84 100644 --- a/docs/api/member.rst +++ b/docs/api/member.rst @@ -135,7 +135,7 @@ Options "required": false, "read_only": false, "label": "Pay\u00e9", - "help_text": "Indique si l'utilisateur per\u00e7oit un salaire." + "help_text": "Indique si l'utilisateur⋅rice per\u00e7oit un salaire." }, "ml_events_registration": { "type": "choice", diff --git a/docs/api/wei.rst b/docs/api/wei.rst index 125ac9b4..cfe3f411 100644 --- a/docs/api/wei.rst +++ b/docs/api/wei.rst @@ -511,7 +511,7 @@ Options "required": false, "read_only": false, "label": "Premi\u00e8re ann\u00e9e", - "help_text": "Indique si l'utilisateur est nouveau dans l'\u00e9cole." + "help_text": "Indique si l'utilisateur⋅rice est nouvelleau dans l'\u00e9cole." }, "information_json": { "type": "string", @@ -524,7 +524,7 @@ Options "type": "field", "required": true, "read_only": false, - "label": "Utilisateur" + "label": "Utilisateur⋅rice" }, "wei": { "type": "field", diff --git a/docs/apps/activity.rst b/docs/apps/activity.rst index f4df6062..d2de9037 100644 --- a/docs/apps/activity.rst +++ b/docs/apps/activity.rst @@ -3,12 +3,12 @@ Application Activités L'application activités gère les différentes activités liées au BDE. Elle permet entre autres de créer des activités qui peuvent être diffusées via des calendriers ou la mailing list d'événements. Elle permet aussi de réguler l'accès aux -événements, en s'assurant que leur note est positive. Elle permet enfin de gérer les invités. +événements, en s'assurant que leur note est positive. Elle permet enfin de gérer les invité⋅es. Modèles ------- -L'application comporte 5 modèles : activités, types d'activité, invités, entrées et transactions d'invitation. +L'application comporte 5 modèles : activités, types d'activité, invité⋅es, entrées et transactions d'invitation. Types d'activité ~~~~~~~~~~~~~~~~ @@ -16,7 +16,7 @@ Types d'activité Les activités sont triées par type (pots, soirées de club, ...), et chaque type regroupe diverses informations : * Nom du type -* Possibilité d'inviter des non-adhérents (booléen) +* Possibilité d'inviter des non-adhérent⋅es (booléen) * Prix d'invitation (entier, centimes à débiter sur la note de l'hôte) Activités @@ -26,7 +26,7 @@ Le modèle d'activité regroupe les informations liées à l'activité même : * Nom de l'activité * Description de l'activité -* Créateur, personne qui a proposé l'activité +* Créateur⋅rice, personne qui a proposé l'activité * Club ayant organisé l'activité * Note sur laquelle verser les crédits d'invitation (peut être nul si non concerné) * Club invité (généralement le club Kfet) @@ -38,19 +38,19 @@ Le modèle d'activité regroupe les informations liées à l'activité même : Entrées ~~~~~~~ -Une instance de ce modèle est créé dès que quelqu'un est inscrit à l'activité. Sont stockées les informations suivantes : +Une instance de ce modèle est créé dès que quelqu'un⋅e est inscrit⋅e à l'activité. Sont stockées les informations suivantes : * Activité concernée (clé étrangère) * Heure d'entrée -* Note de la personne entrée, ou hôte s'il s'agit d'un invité (clé étrangère vers ``NoteUser``) -* Invité (``OneToOneField`` vers ``Guest``, ``None`` si c'est la personne elle-même qui rentre et non son invité) +* Note de la personne entrée, ou hôte s'il s'agit d'un⋅e invité⋅e (clé étrangère vers ``NoteUser``) +* Invité⋅e (``OneToOneField`` vers ``Guest``, ``None`` si c'est la personne elle-même qui rentre et non saon invité⋅e) Il n'est pas possible de créer une entrée si la note est en négatif. -Invités -~~~~~~~ +Invité⋅es +~~~~~~~~~ -Les adhérents ont la possibilité d'inviter des amis. Pour cela, les différentes informations sont enregistrées : +Les adhérent⋅es ont la possibilité d'inviter des ami⋅es. Pour cela, les différentes informations sont enregistrées : * Activité concernée (clé étrangère) * Nom de famille @@ -60,7 +60,7 @@ Les adhérents ont la possibilité d'inviter des amis. Pour cela, les différent Certaines contraintes s'appliquent : * Une personne ne peut pas être invitée plus de 5 fois par an (coupe nom/prénom) -* Un adhérent ne peut pas inviter plus de 3 personnes par activité. +* Un⋅e adhérent⋅e ne peut pas inviter plus de 3 personnes par activité. Transactions d'invitation ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -83,15 +83,15 @@ UI Création d'activités ~~~~~~~~~~~~~~~~~~~~ -N'importe quel adhérent Kfet peut suggérer l'ajout d'une activité via un formulaire. +N'importe quel⋅le adhérent⋅e Kfet peut suggérer l'ajout d'une activité via un formulaire. Gestion des activités ~~~~~~~~~~~~~~~~~~~~~ Les ayant-droit (Res[pot] et respos infos) peuvent valider les activités proposées. Ils peuvent également la modifier -si besoin. Ils peuvent enfin la déclarer ouvertes pour lancer l'accès aux entrées. +si besoin. Iels peuvent enfin la déclarer ouverte pour lancer l'accès aux entrées. -N'importe qui peut inviter des amis non adhérents, tant que les contraintes de nombre (un adhérent n'invite pas plus de +N'importe qui peut inviter des ami⋅es non adhérent⋅es, tant que les contraintes de nombre (un⋅e adhérent⋅e n'invite pas plus de trois personnes par activité et une personne ne peut pas être invitée plus de 5 fois par an). L'invitation est facturée à l'entrée. @@ -99,12 +99,12 @@ Entrées aux soirées ~~~~~~~~~~~~~~~~~~~ L'interface d'entrées est simple et ergonomique. Elle contient un champ de texte. À chaque fois que le champ est -modifié, un tableau est affiché comprenant la liste des invités et des adhérents dont le prénom, le nom ou un alias +modifié, un tableau est affiché comprenant la liste des invité⋅es et des adhérent⋅es dont le prénom, le nom ou un alias de la note est acceptée par le texte entré. -En cliquant sur la ligne de la personne qui souhaite rentrée, s'il s'agit d'un adhérent, alors la personne est comptée -comme entrée à l'activité, sous réserve que sa note soit positive. S'il s'agit d'un invité, alors 3 boutons +En cliquant sur la ligne de la personne qui souhaite rentrer, s'il s'agit d'un⋅e adhérent⋅e, alors la personne est comptée +comme entrée à l'activité, sous réserve que sa note soit positive. S'il s'agit d'un⋅e invité⋅e, alors 3 boutons apparaîssent, afin de régler la taxe d'invitation : l'un prélève directement depuis la note de l'hôte, les deux autres permettent un paiement par espèces ou par carte bancaire. En réalité, les deux derniers boutons enregistrent automatiquement un crédit sur la note de l'hôte, puis une transaction (de type ``GuestTransaction``) est faite depuis -la note de l'hôte vers la note de l'organisateur de l'événement. +la note de l'hôte vers la note du club organisateur de l'événement. diff --git a/docs/apps/index.rst b/docs/apps/index.rst index d1fa1ee0..eb31fd11 100644 --- a/docs/apps/index.rst +++ b/docs/apps/index.rst @@ -1,5 +1,5 @@ -Applications de la NoteKfet2020 -=============================== +Applications de la Note Kfet 2020 +================================= .. toctree:: :maxdepth: 2 @@ -15,27 +15,26 @@ Applications de la NoteKfet2020 treasury wei -La NoteKfet est un projet Django, décomposé en applications. -Certaines Applications sont développées uniquement pour ce projet, et sont indispensables, -d'autres sont packagesé et sont installées comme dépendances. -Enfin des fonctionnalités annexes ont été rajouté, mais ne sont pas essentiel au déploiement de la NoteKfet; -leur usage est cependant recommandé. +La Note Kfet 2020 est un projet Django, décomposé en applications. +Certaines applications sont développées uniquement pour ce projet, et sont indispensables, +d'autres sont packagées et sont installées comme dépendances. +Enfin, des fonctionnalités annexes ont été rajoutées, mais ne sont pas essentielles au déploiement de la Note Kfet 2020. Leur usage est cependant recommandé. -Le front utilise le framework Bootstrap4 et quelques morceaux de javascript custom. +L'affichage Web utilise le framework Bootstrap4 et quelques morceaux de JavaScript personnalisés. Applications indispensables --------------------------- * ``note_kfet`` : - Application "projet" de django, c'est ici que la config de la note est gérée. + Application "projet" de django, c'est ici que la configuration de la note est gérée. * `Member `_ : - Gestion des profils d'utilisateurs, des clubs et de leur membres. + Gestion des profils d'utilisateur⋅rices, des clubs et de leur membres. * `Note `_ : - Les notes associés a des utilisateurs ou des clubs. + Les notes associées à des utilisateur⋅rices ou des clubs. * `Activity `_ : - La gestion des Activités (créations, gestion, entrée...) + La gestion des activités (créations, gestion, entrées,…) * `Permission `_ : - Backend de droits, limites les pouvoirs des utilisateurs + Backend de droits, limites les pouvoirs des utilisateur⋅rices * `API <../api>`_ : API REST de la note, est notamment utilisée pour rendre la note dynamique (notamment la page de conso) @@ -52,9 +51,9 @@ Applications packagées ``_ * ``crispy_forms`` - Utiliser pour générer des forms avec bootstrap4 + Utiliser pour générer des formulairess avec Bootstrap4 * ``django_tables2`` - utiliser pour afficher des tables de données et les formater, en python plutôt qu'en HTML. + utiliser pour afficher des tables de données et les formater, en Python plutôt qu'en HTML. * ``restframework`` Base de l'`API <../api>`_. @@ -63,11 +62,11 @@ Applications facultatives * `Logs `_ Enregistre toute les modifications effectuées en base de donnée. * ``cas-server`` - Serveur central d'authenfication, permet d'utiliser son compte de la NoteKfet2020 pour se connecter à d'autre application ayant intégrer un client. -* `Script `_ - Ensemble de commande `./manage.py` pour la gestion de la note: import de données, verification d'intégrité, etc ... + Serveur central d'authentification, permet d'utiliser son compte de la NoteKfet2020 pour se connecter à d'autre application ayant intégrer un client. +* `Scripts `_ + Ensemble de commande `./manage.py` pour la gestion de la note: import de données, verification d'intégrité, etc… * `Treasury `_ : - Interface de gestion pour les trésoriers, émission de facture, remise de chèque, statistiques ... + Interface de gestion pour les trésorièr⋅es, émission de factures, remises de chèque, statistiques ... * `WEI `_ : Interface de gestion du WEI. diff --git a/docs/apps/logs.rst b/docs/apps/logs.rst index afb3cf70..b561e4f2 100644 --- a/docs/apps/logs.rst +++ b/docs/apps/logs.rst @@ -6,22 +6,22 @@ Chaque modification effectuée sur un modèle est enregistrée dans la base dans Dès qu'un modèle veut être sauvegardé, deux signaux sont envoyés dans ``logs.signals`` : un avant et un après la sauvegarde. En pré-sauvegarde, on récupère l'ancienne version du modèle, si elle existe. -En post-sauvegarde, on récupère l'utilisateur et l'IP courants (voir ci-dessous), on convertit les modèles en JSON +En post-sauvegarde, on récupère l'utilisateur⋅rice et l'IP courant⋅es (voir ci-dessous), on convertit les modèles en JSON et on enregistre une entrée ``Changelog`` dans la base de données. -Pour récupérer l'utilisateur et son IP, le middleware ``logs.middlewares.LogsMiddlewares`` récupère à chaque requête -l'utilisateur et l'adresse IP, et les stocke dans le processus courant, afin qu'ils puissent être +Pour récupérer l'utilisateur⋅rice et son IP, le middleware ``logs.middlewares.LogsMiddlewares`` récupère à chaque requête +l'utilisateur⋅rice et l'adresse IP, et les stocke dans le processus courant, afin qu'ils puissent être récupérés par les signaux. Si jamais la modification ne provient pas d'une requête Web, on suppose qu'elle vient d'une instruction lancée avec ``manage.py``. -On récupère alors le nom de l'utilisateur dans l'interface de commandes, et si une note est associée à cet alias, +On récupère alors le nom de l'utilisateur⋅rice dans l'interface de commandes, et si une note est associée à cet alias, alors on considère que c'est le détenteur de la note qui a effectué cette modification, sur l'adresse IP ``127.0.0.1``. Sinon, le champ est laissé à ``None``. Une entrée de ``Changelog`` contient les informations suivantes : - * Utilisateur (``ForeignKey`` vers ``User``, nullable) + * Utilisateur⋅rice (``ForeignKey`` vers ``User``, nullable) * Adresse IP (``GenericIPAddressField``) * Type de modèle enregistré (``ForeignKey`` vers ``Model``) * Identifiant ``pk`` de l'instance enregistrée (``CharField``) @@ -54,4 +54,4 @@ Graphe ~~~~~~ .. image:: ../_static/img/graphs/logs.svg - :alt: Logs graphe + :alt: Logs graph diff --git a/docs/apps/member.rst b/docs/apps/member.rst index 7ec7cd8d..30d78de6 100644 --- a/docs/apps/member.rst +++ b/docs/apps/member.rst @@ -1,63 +1,63 @@ Application Member ================== -L'application ``member`` s'occcupe de la gestion des utilisateurs enregistrés. +L'application ``member`` s'occcupe de la gestion des utilisateur⋅rices enregistré⋅es. -Le model d'utilisateur ``django.contrib.auth.model.User`` est complété par un ``Profile`` utilisateur. +Le model d'utilisateur⋅rice ``django.contrib.auth.model.User`` est complété par un ``Profile`` utilisateur⋅rice. -Tous les utilisateurs peuvent être membre de ``Club``. Cela se traduit par une adhésion ``Membership``, dont les +Toustes les utilisateur⋅rices peuvent être membre de ``Club``. Cela se traduit par une adhésion ``Membership``, dont les caractéristiques sont propres à chaque club. -En pratique, la NoteKfet possède au minimum deux Club: **Bde** et **Kfet** (instanciés via les fixtures). Et tous -les personnes à jour de cotisation sont membre à minima de Bde. -Être adhérent du club Kfet permet d'utiliser sa note pour consommer. +En pratique, la Note Kfet possède au minimum deux clubs : **Bde** et **Kfet** (instanciés +via les fixtures). Et toutes les personnes à jour de cotisation sont membre à minima de +BDE. Être adhérent⋅e du club Kfet permet d'utiliser sa note pour consommer. Modèles ------- -Utilisateur -~~~~~~~~~~~ +Utilisateur⋅rice +~~~~~~~~~~~~~~~~ Le modèle ``User`` est directement implémenté dans Django et n'appartient pas à l'application ``member``, mais il est bon de rappeler à quoi ressemble ce modèle. -* ``date_joined`` : ``DateTimeField``, date à laquelle l'utilisateur a été inscrit (*inutilisé dans la Note*) -* ``email`` : ``EmailField``, adresse e-mail de l'utilisateur. -* ``first_name`` : ``CharField``, prénom de l'utilisateur. +* ``date_joined`` : ``DateTimeField``, date à laquelle l'utilisateur⋅rice a été inscrit (*inutilisé dans la Note*) +* ``email`` : ``EmailField``, adresse e-mail de l'utilisateur⋅rice. +* ``first_name`` : ``CharField``, prénom de l'utilisateur⋅rice. * ``is_active`` : ``BooleanField``, indique si le compte est actif et peut se connecter. -* ``is_staff`` : ``BooleanField``, indique si l'utilisateur peut se connecter à l'interface Django-admin. -* ``is_superuser`` : ``BooleanField``, indique si l'utilisateur dispose de droits super-utilisateurs, permettant n'importe quelle action en base de donnée (lecture, ajout, modification, suppression). +* ``is_staff`` : ``BooleanField``, indique si l'utilisateur⋅rice peut se connecter à l'interface Django-admin. +* ``is_superuser`` : ``BooleanField``, indique si l'utilisateur⋅rice dispose de droits super-utilisateur⋅rices, permettant n'importe quelle action en base de donnée (lecture, ajout, modification, suppression). * ``last_login`` : ``DateTimeField``, date et heure de dernière connexion. -* ``last_name`` : ``CharField``, nom de famille de l'utilisateur. -* ``password`` : ``CharField``, contient le hash du mot de passe de l'utilisateur. L'algorithme utilisé est celui par défaut de Django : PBKDF2 + HMAC + SHA256 avec 150000 itérations. -* ``username`` : ``CharField`` (unique), pseudo de l'utilisateur. +* ``last_name`` : ``CharField``, nom de famille de l'utilisateur⋅rice. +* ``password`` : ``CharField``, contient le hash du mot de passe de l'utilisateur⋅rice. L'algorithme utilisé est celui par défaut de Django : PBKDF2 + HMAC + SHA256 avec 150000 itérations. +* ``username`` : ``CharField`` (unique), pseudo de l'utilisateur⋅rice. Profil ~~~~~~ Le modèle ``Profile`` contient un champ ``user`` de type ``OneToOneField``, ce qui permet de voir ce modèle comme une extension du modèle ``User``, sans avoir à le réécrire. Il contient diverses informations personnelles sur -l'utilisateur, utiles pour l'adhésion au BDE : +l'utilisateur⋅rice, utiles pour l'adhésion au BDE : -* ``user`` : ``OneToOneField(User)``, utilisateur lié à ce profil -* ``address`` : ``CharField``, adresse physique de l'utilisateur -* ``paid`` : ``BooleanField``, indique si l'utilisateur normalien est rémunéré ou non (utile pour différencier les montants d'adhésion aux clubs) -* ``phone_number`` : ``CharField``, numéro de téléphone de l'utilisateur -* ``section`` : ``CharField``, section de l'ENS à laquelle apartient l'utilisateur (exemple : 1A0, ...) +* ``user`` : ``OneToOneField(User)``, utilisateur⋅rice lié à ce profil +* ``address`` : ``CharField``, adresse physique de l'utilisateur⋅rice +* ``paid`` : ``BooleanField``, indique si l'utilisateur⋅rice normalien⋅ne est rémunéré⋅e ou non (utile pour différencier les montants d'adhésion aux clubs) +* ``phone_number`` : ``CharField``, numéro de téléphone de l'utilisateur⋅rice +* ``section`` : ``CharField``, section de l'ENS à laquelle appartient l'utilisateur⋅rice (exemple : 1A0,…) Clubs ~~~~~ La gestion des clubs est une différence majeure avec la Note Kfet 2015. La Note gère ainsi les adhésions des -utilisateurs aux différents clubs. +utilisateur⋅rices aux différents clubs. * ``parent_club`` : ``ForeignKey(Club)``. La présence d'un club parent force l'adhésion au club parent avant de pouvoir adhérer au dit club. Tout club qui n'est pas le club BDE doit avoir le club BDE dans son arborescence. * ``email`` : ``EmailField``, adresse e-mail sur laquelle contacter le bureau du club. -* ``membership_start`` : ``DateField``, date à partir de laquelle il est possible d'adhérer à un club pour l'année suivante (si adhésions à l'année), en ignorant l'année. Par exemple, l'adhésion BDE est possible à partir du 31/08 par défaut, et c'est à cette date que les adhésions pour l'année future est possible. +* ``membership_start`` : ``DateField``, date à partir de laquelle il est possible d'adhérer à un club pour l'année suivante (si adhésions à l'année), en ignorant l'année. Par exemple, l'adhésion BDE est possible à partir du 01/08 par défaut, et c'est à cette date que les adhésions pour l'année future est possible. * ``membership_end`` : ``DateField``, date maximale de fin d'adhésion. Pour le club BDE, il s'agit du 30/09 de l'année suivante. Si cette valeur vaut ``null``, la fin d'adhésion n'est pas limitée. * ``membership_duration`` : ``PositiveIntegerField``, durée (en jours) maximale d'adhésion. Par exemple, le club BDE permet des adhésions maximales de 13 mois, soit 396 jours. -* ``membership_fee_paid`` : ``PositiveIntegerField``, montant de la cotisation (en centimes) pour qu'un élève normalien (donc rémunéré) puisse adhérer. -* ``membership_fee_unpaid`` : ``PositiveIntegerField``, montant de la cotisation (en centimes) pour qu'un étudiant normalien (donc non rémunéré) puisse adhérer. +* ``membership_fee_paid`` : ``PositiveIntegerField``, montant de la cotisation (en centimes) pour qu'un⋅e élève normalien⋅ne (donc rémunéré⋅e) puisse adhérer. +* ``membership_fee_unpaid`` : ``PositiveIntegerField``, montant de la cotisation (en centimes) pour qu'un⋅e étudiant⋅e normalien⋅ne (donc non rémunéré) puisse adhérer. * ``name`` : ``CharField``, nom du club. * ``require_memberships`` : ``BooleanField``, indique si le club est un vrai club BDE qui nécessite des adhésions de club, ou s'il s'agit d'une note "pot commun" (organisation d'une activité, note de département, ...) @@ -67,16 +67,16 @@ Adhésions Comme indiqué précédemment, la note gère les adhésions. * ``club`` : ``ForeignKey(Club)``, club lié à l'adhésion. -* ``user`` : ``ForeignKey(User)``, utilisateur adhéré. +* ``user`` : ``ForeignKey(User)``, utilisateur⋅rice qui a adhéré. * ``date_start`` : ``DateField``, date de début d'adhésion. * ``date_end`` : ``DateField``, date de fin d'adhésion. * ``fee`` : ``PositiveIntegerField``, montant de la cotisation payée. -* ``roles`` : ``ManyToManyField(Role)``, liste des rôles endossés par l'adhérent. +* ``roles`` : ``ManyToManyField(Role)``, liste des rôles endossés par l'adhérent⋅e. Rôles ~~~~~ -Comme indiqué le modèle des adhésions, les adhésions octroient des rôles aux adhérents, qui offrent des permissions +Comme indiqué le modèle des adhésions, les adhésions octroient des rôles aux adhérent⋅es, qui offrent des permissions (cf ``RolesPermissions`` dans la page des permissions). Le modèle ``RolesPermissions`` possède un ``OneToOneField(Role)``, qui implémente les permissions des rôles. Le modèle ``Role`` à proprement parler ne contient que le champ de son nom (``CharField``). @@ -88,7 +88,7 @@ Si le modèle ``MembershipTransaction`` appartient à l'application ``note``, il Le modèle ``MembershipTransaction`` est une extension du modèle ``Transaction`` (application ``note``) qui est de type polymorphique, et contient en plus des informations de base de la transaction un champ ``OneToOneField(Membership)`` faisant le lien entre l'adhésion et la transaction liée. Une adhésion club, si elle n'est pas gratuite, -génère en effet automatiquement une transaction de l'utilisateur vers le club (voir section adhésions). +génère en effet automatiquement une transaction de l'utilisateur⋅rice vers le club (voir section adhésions). Graphe ------ @@ -100,28 +100,28 @@ Adhésions --------- La Note Kfet offre la possibilité aux clubs de gérer l'adhésion de leurs membres. En plus de réguler les cotisations -des adhérents, des permissions sont octroyées sur la note en fonction des rôles au sein des clubs. Un rôle est une -fonction occupée au sein d'un club (Trésorier de club, président de club, GCKfet, Res[pot], respo info, ...). -Une adhésion attribue à un adhérent ses rôles. Les rôles fournissent les permissions. Par exemple, le trésorier d'un +des adhérent⋅es, des permissions sont octroyées sur la note en fonction des rôles au sein des clubs. Un rôle est une +fonction occupée au sein d'un club (Trésorièr⋅e de club, président⋅e de club, GC Kfet, Res[pot], respo info,…). +Une adhésion attribue à un⋅e adhérent⋅e ses rôles. Les rôles fournissent les permissions. Par exemple, læ trésorièr⋅e d'un club a le droit de faire des transferts de et vers la note du club, tant que la source reste au-dessus de -50 €. Une adhésion est considérée comme valide si la date du jour est comprise (au sens large) entre les dates de début et de fin d'adhésion. -On peut ajouter une adhésion à un utilisateur dans un club à tout non adhérent de ce club. La personne en charge -d'adhérer quelqu'un choisit l'utilisateur, les rôles au sein du club et la date de début d'adhésion. Cette date de +On peut ajouter une adhésion à un⋅e utilisateur⋅rice dans un club à tout⋅e non adhérent⋅e de ce club. La personne en charge +d'adhérer quelqu'un choisit l'utilisateur⋅rice, les rôles au sein du club et la date de début d'adhésion. Cette date de début d'adhésion doit se situer entre les champs ``club.membership_start`` et ``club.membership_end``, -si ces champs sont non nuls. Si ``club.parent_club`` n'est pas nul, l'utilisateur doit être membre de ce club. -Le montant de la cotisation est fixé en fonction du statut normalien de l'utilisateur (``club.membership_fee_paid`` -centimes pour les élèves et ``club.membership_fee_unpaid`` centimes pour les étudiants). La date de fin est calculée +si ces champs sont non nuls. Si ``club.parent_club`` n'est pas nul, l'utilisateur⋅rice doit être membre de ce club. +Le montant de la cotisation est fixé en fonction du statut normalien de l'utilisateur⋅rice (``club.membership_fee_paid`` +centimes pour les élèves et ``club.membership_fee_unpaid`` centimes pour les étudiant⋅es). La date de fin est calculée comme ce qui suit : * Si ``club.membership_duration`` est non nul, alors ``date_end`` = ``date_start`` + ``club.membership_duration`` * Sinon ``club``, ``date_end`` = ``date_start`` + 424242 jours (suffisant pour tenir au moins une vie) * Si ``club.membership_end`` est non nul, alors ``date_end`` = min(``date_end``, ``club.membership_end``) -Si l'utilisateur n'est pas membre du club ``Kfet``, l'adhésion n'est pas possible si le solde disponible sur sa note est +Si l'utilisateur⋅rice n'est pas membre du club ``Kfet``, l'adhésion n'est pas possible si le solde disponible sur sa note est insuffisant. Une fois toute ces contraintes vérifiées, l'adhésion est créée. Une transaction de type -``MembershipTransaction`` est automatiquement créée de la note de l'utilisateur vers la note du club, finalisant l'adhésion. +``MembershipTransaction`` est automatiquement créée de la note de l'utilisateur⋅rice vers la note du club, finalisant l'adhésion. Réadhésions ~~~~~~~~~~~ @@ -137,7 +137,7 @@ Il est possible de réadhérer si : * Il n'y a pas encore de réadhésion (pas d'adhésion au même club vérifiant ``new_membership.date_start`` >= ``club.membership_start``) Un bouton ``Réadhérer`` apparaît dans la liste des adhésions si le droit est permis et si ces contraintes sont vérifiées. -En réadhérant, une nouvelle adhésion est créée pour l'utilisateur avec les mêmes rôles, commençant le lendemain de la +En réadhérant, une nouvelle adhésion est créée pour l'utilisateur⋅rice avec les mêmes rôles, commençant le lendemain de la date d'expiration de la précédente adhésion. Si on réadhère le 16 août pour une adhésion finissant le 30 septembre, la nouvelle adhésion commencera le 1er octobre). diff --git a/docs/apps/note/consumptions.rst b/docs/apps/note/consumptions.rst index 8b2209fe..ace7c53a 100644 --- a/docs/apps/note/consumptions.rst +++ b/docs/apps/note/consumptions.rst @@ -7,23 +7,23 @@ Affichage La page de consommations est principalement une communication entre l'`API <../api>`_ et la page en JavaScript. Elle est disponible à l'adresse ``/note/consos/``, et l'onglet n'est visible que pour ceux ayant le droit de voir au moins un bouton. L'affichage, comme tout le reste de la page, est géré avec Boostrap 4. -Les boutons que l'utilisateur a le droit de voir sont triés par catégorie. +Les boutons que l'utilisateur⋅rice a le droit de voir sont triés par catégorie. Sélection des consommations --------------------------- -Lorsque l'utilisateur commence à taper un nom de note, un appel à l'API sur la page ``/api/note/alias`` est fait, -récupérant les 20 premiers aliases en accord avec la requête. Quand l'utilisateur survole un alias, un appel à la page +Lorsque l'utilisateur⋅rice commence à taper un nom de note, un appel à l'API sur la page ``/api/note/alias`` est fait, +récupérant les 20 premiers aliases en accord avec la requête. Quand l'utilisateur⋅rice survole un alias, un appel à la page ``/api/note/note//`` est fait pour récupérer plus d'infos sur la note telles que le solde, le vrai nom de la -note et la photo, si toutefois l'utilisateur a le droit de voir ceci. +note et la photo, si toutefois l'utilisateur⋅rice a le droit de voir ceci. -L'utilisateur peut cliquer sur des aliases pour ajouter des émetteurs, et sur des boutons pour ajouter des consommations. -Cliquer dans la liste des émetteurs supprime l'élément sélectionné. +L'utilisateur⋅rice peut cliquer sur des aliases pour ajouter des émetteur⋅rices, et sur des boutons pour ajouter des consommations. +Cliquer dans la liste des émetteur⋅rices supprime l'élément sélectionné. -Il ya deux possibilités pour faire consommer des adhérents : - - En mode **consommation simple** (mode par défaut), les consommations sont débitées dès que émetteurs et consommations +Il ya deux possibilités pour faire consommer des adhérent⋅es : + - En mode **consommation simple** (mode par défaut), les consommations sont débitées dès que émetteur⋅rices et consommations sont renseignées. - - En mode **consommation double**, l'utilisateur doit cliquer sur "Consommer !" pour débiter toutes les consommations. + - En mode **consommation double**, l'utilisateur⋅rice doit cliquer sur « **Consommer !** »" pour débiter toutes les consommations. Débit des consommations ----------------------- @@ -71,7 +71,7 @@ des types. Il vaut `42` lors de la rédaction de cette documentation, mais pourr Si une erreur survient lors de la requête (droits insuffisants), un message apparaîtra en haut de page. Dans tous les cas, tous les champs sont réinitialisés. -L'historique et la balance de l'utilisateur sont ensuite mis à jour via jQuery, qui permet de recharger une partie de page Web. +L'historique et le solde de l'utilisateur⋅rice sont ensuite mis à jour via jQuery, qui permet de recharger une partie de page Web. Validation/dévalidation des transactions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -86,4 +86,4 @@ une requête PATCH est faite à l'API sur l'adresse ``/api/note/transaction/tran "valid": false } -L'historique et la balance sont ensuite rafraîchis. Si une erreur survient, un message apparaîtra. +L'historique et le solde sont ensuite rafraîchis. Si une erreur survient, un message apparaîtra. diff --git a/docs/apps/note/index.rst b/docs/apps/note/index.rst index 1291dad9..fe35a759 100644 --- a/docs/apps/note/index.rst +++ b/docs/apps/note/index.rst @@ -1,12 +1,12 @@ Application Note ================ -L'application ``note`` gère tout ce qui est en lien avec les flux d'argent et les notes (balances) des utilisateurs. +L'application ``note`` gère tout ce qui est en lien avec les flux d'argent et les notes (soldes) des utilisateur⋅rices. La gestion des consommations s'effectue principalement via la page dédiée, dont le fonctionnement est expliqué dans la page `Consommations `_. -Le fonctionnnemnent des crédit/débit de note (avec le "monde extérieur" donc avec de l'argent réel) ainsi que les +Le fonctionnement des crédit/débit de note (avec le « monde extérieur »» donc avec de l'argent réel) ainsi que les transferts/dons entre notes est détaillé sur la page `Transferts `_. .. toctree:: diff --git a/docs/apps/note/transfers.rst b/docs/apps/note/transfers.rst index 5438665e..26236ca2 100644 --- a/docs/apps/note/transfers.rst +++ b/docs/apps/note/transfers.rst @@ -6,7 +6,7 @@ Affichage L'interface de la page de transferts est semblable à celles des consommations, et l'auto-complétion de note est géré de la même manière. La page se trouve à l'adresse ``/note/transfer/``. La liste des 20 transactions les plus récentes que -l'utilisateur a le droit de voir est également présente. +l'utilisateur⋅rice a le droit de voir est également présente. Des boutons ``Don``, ``Transfert``, ``Crédit``, ``Retrait`` sont présents, représentant les différents modes de transfert. Pour chaque transfert, un montant et une description sont attendus. @@ -23,7 +23,7 @@ Onglets Crédit et retrait Ces onglets ne sont visibles que par ceux qui ont le droit de voir les ``SpecialNote``. Une boîte supplémentaire apparaît, demandant en plus de la note, du montant et de la raison le nom, le prénom et -la banque de la personne à recharger/retirer. Lorsqu'une note est sélectionnée, les champs "nom" et "prénom" sont +la banque de la personne à recharger/retirer. Lorsqu'une note est sélectionnée, les champs « nom » et « prénom » sont remplis automatiquement. Par ailleurs, seule une note peut être choisie. Transfert diff --git a/docs/apps/permission.rst b/docs/apps/permission.rst index ac859151..f6c8d940 100644 --- a/docs/apps/permission.rst +++ b/docs/apps/permission.rst @@ -1,8 +1,8 @@ Droits ====== -Le système de droit par défault de django n'est pas suffisament granulaire pour les besoins de la NoteKfet2020. -Un système custom a donc été développé. +Le système de droit par défaut de Django n'est pas suffisamment granulaire pour les besoins de la Note Kfet 2020. +Un système personnalisé a donc été développé. Il permet la création de Permission, qui autorise ou non a faire une action précise sur un ou des objets de la base de données. @@ -22,12 +22,12 @@ Une permission est un Model Django dont les principaux attributs sont : * ``query`` : Requête sur la cible, encodé en JSON, traduit en un Q object (cf `Query <#compilation-de-la-query>`_) * ``field`` : le champ cible qui pourra être modifié. (tous les champs si vide) -Pour savoir si un utilisateur a le droit sur un modèle ou non, la requête est compilée (voir ci-dessous) en un filtre -de requête dans la base de données, un objet de la classe ``Q`` (En SQL l'objet Q s'interprete comme tout ce qui suit +Pour savoir si un⋅e utilisateur⋅rice a le droit sur un modèle ou non, la requête est compilée (voir ci-dessous) en un filtre +de requête dans la base de données, un objet de la classe ``Q`` (En SQL l'objet Q s'interprète comme tout ce qui suit un ``WHERE ...`` Ils peuvent être combiné à l'aide d'opérateurs logiques. Plus d'information sur les Q object dans la `documentation officielle `_. -Ce Q object sera donc utilisé pour savoir si l'instance que l'on veux modifier est concernée par notre permission. +Ce Q object sera donc utilisé pour savoir si l'instance que l'on veut modifier est concernée par notre permission. Exception faite sur l'ajout d'objets : l'objet n'existant pas encore en base de données, il est ajouté puis supprimé à la volée, en prenant soin de désactiver les signaux. @@ -36,7 +36,7 @@ Compilation de la query ----------------------- La query est enregistrée sous un format JSON, puis est traduite en requête ``Q`` récursivement en appliquant certains paramètres. -Le fonctionnemente de base des permission peux être décris avec les differents opérations : +Le fonctionnemente de base des permission peux être décris avec les différents opérations : +----------------+-----------------------------+-------------------------------------+ | opérations | JSON | Q object | @@ -64,7 +64,7 @@ Exemples {"is_superuser": true} - | si l'utilisateur cible est un super utilisateur. + | si l'utilisateur⋅rice cible est un⋅e super utilisateur⋅rice. * sur le model ``Note`` : @@ -74,7 +74,7 @@ Exemples ["user","note", "pk"] } - | si l'identifiant de la note cible est l'identifiant de l'utilisateur dont on regarde la permission. + | si l'identifiant de la note cible est l'identifiant de l'utilisateur⋅rice dont on regarde la permission. * sur le model ``Transaction``: @@ -87,7 +87,7 @@ Exemples ["user", "note", "balance"]} ] - | si la source est la note de l'utilisateur et si le montant est inférieur à son solde. + | si la source est la note de l'utilisateur⋅rice et si le montant est inférieur à son solde. * Sur le model ``Alias`` @@ -106,7 +106,7 @@ Exemples } ] - | si l'alias appartient à une note de club ou s'il appartient à la note d'un utilisateur membre du club Kfet. + | si l'alias appartient à une note de club ou s'il appartient à la note d'un⋅e utilisateur⋅rice membre du club Kfet. * sur le model ``Transaction`` @@ -130,19 +130,19 @@ Exemples Masques de permissions ---------------------- -Chaque permission est associée à un masque. À la connexion, l'utilisateur choisit le masque de droits avec lequel il -souhaite se connecter. Les masques sont ordonnés totalement, et l'utilisateur aura effectivement une permission s'il est +Chaque permission est associée à un masque. À la connexion, l'utilisateur⋅rice choisit le masque de droits avec lequel il +souhaite se connecter. Les masques sont ordonnés totalement, et l'utilisateur⋅rice aura effectivement une permission s'il est en droit d'avoir la permission et si son masque est suffisamment haut. -Par exemple, si la permission de voir toutes les transactions est associée au masque "Droits note uniquement", -se connecter avec le masque "Droits basiques" n'octroiera pas cette permission tandis que le masque "Tous mes droits" oui. +Par exemple, si la permission de voir toutes les transactions est associée au masque « Droits note uniquement », +se connecter avec le masque « Droits basiques » n'octroiera pas cette permission tandis que le masque « Tous mes droits » oui. Signaux ------- À chaque fois qu'un modèle est modifié, ajouté ou supprimé, les droits sont contrôlés. Si les droits ne sont pas suffisants, une erreur est lancée. Pour ce qui est de la modification, on ne contrôle que les champs réellement -modifiés en comparant l'ancienne et la nouvele instance. +modifiés en comparant l'ancienne et la nouvelle instance. Graphe des modèles ------------------ diff --git a/docs/apps/registration.rst b/docs/apps/registration.rst index c5947349..6db796f2 100644 --- a/docs/apps/registration.rst +++ b/docs/apps/registration.rst @@ -4,7 +4,7 @@ Inscriptions L'inscription a la note se fait via une application dédiée, sans toutefois avoir de modèle en base de données. Un formulaire d'inscription est disponible sur la page ``/registration/signup``, accessible depuis n'importe qui, -authentifié ou non. Les informations suivantes sont demandées : +authentifié⋅e ou non. Les informations suivantes sont demandées : * Prénom * Nom de famille @@ -15,7 +15,7 @@ authentifié ou non. Les informations suivantes sont demandées : * Département d'études * Promotion, année d'entrée à l'ENS * Adresse (optionnel) -* Payé (si la personne perçoit un salaire) +* Payé⋅e (si la personne perçoit un salaire) Le mot de passe doit vérifier des contraintes de longueur, de complexité et d'éloignement des autres informations personnelles. @@ -34,28 +34,28 @@ le compte sera enfin actif. Pour récapituler : compte actif = adresse e-mail validée + inscription validée par le BDE. Lors de la validation de l'inscription, le BDE peut (et doit même) faire un crédit initial sur la future note de -l'utilisateur. Il peut spécifier le type de crédit (carte bancaire/espèces/chèque/virement bancaire), le prénom, +l'utilisateur⋅rice. Il peut spécifier le type de crédit (carte bancaire/espèces/chèque/virement bancaire), le prénom, le nom et la banque comme un crédit normal. Cependant, il peut aussi cocher une case "Société générale", si le nouveau membre indique avoir ouvert un compte à la Société générale via le partenariat Société générale - BDE de l'ÉNS Paris-Saclay. Dans ce cas, tous les champs sont grisés. Une fois l'inscription validée, détail de ce qu'il se passe : -* Si crédit de la socitété générale, on mémorise que le fait que la personne ait demandé ce crédit (voir +* Si crédit de la société générale, on mémorise que le fait que la personne ait demandé ce crédit (voir `Trésorerie `_ section crédits de la société générale). Nécessairement, le club Kfet doit être rejoint. -* Sinon, on crédite la note du montant demandé par le nouveau membre (avec comme description "Crédit TYPE (Inscription)" +* Sinon, on crédite la note du montant demandé par læ nouvelleau membre (avec comme description "Crédit TYPE (Inscription)" où TYPE est le type de crédit), après avoir vérifié que le crédit est suffisant (on n'ouvre pas une note négative) -* On adhère la personne au BDE, l'adhésion commence aujourd'hui. Il dispose d'un unique rôle : "Adhérent BDE", +* On adhère la personne au BDE, l'adhésion commence aujourd'hui. Iel dispose d'un unique rôle : « Adhérent⋅e BDE », lui octroyant un faible nombre de permissions de base, telles que la visualisation de son compte. -* On adhère la personne au club Kfet si cela est demandé, l'adhésion commence aujourd'hui. Il dispose d'un unique rôle : - "Adhérent Kfet", lui octroyant un nombre un peu plus conséquent de permissions basiques, telles que la possibilité de - faire des transactions, d'accéder aux activités, au WEI, ... -* Si le nouveau membre a indiqué avoir ouvert un compte à la société générale, alors les transactions sont invalidées, +* On adhère la personne au club Kfet si cela est demandé, l'adhésion commence aujourd'hui. Iel dispose d'un unique rôle : + « Adhérent⋅e Kfet » , lui octroyant un nombre un peu plus conséquent de permissions basiques, telles que la possibilité de + faire des transactions, d'accéder aux activités, au WEI,… +* Si læ nouvelleau membre a indiqué avoir ouvert un compte à la société générale, alors les transactions sont invalidées, la note n'est pas débitée (commence alors à 0 €). Par ailleurs, le BDE peut supprimer la demande d'inscription sans problème via un bouton dédié. Cette opération n'est pas réversible. -L'utilisateur a enfin accès a sa note et peut faire des bêtises :) +L'utilisateur⋅rice a enfin accès a sa note et peut faire des bêtises :) L'inscription au BDE et à la Kfet est indépendante de l'inscription au WEI. Voir `WEI `_ pour l'inscription WEI. diff --git a/docs/apps/treasury.rst b/docs/apps/treasury.rst index 7c2a8746..8d269404 100644 --- a/docs/apps/treasury.rst +++ b/docs/apps/treasury.rst @@ -1,7 +1,7 @@ Application Trésorerie ====================== -L'application de Trésorerie facilite la vie des trésorier, et sert d'interface de création de facture. +L'application de Trésorerie facilite la vie des trésorièr⋅es, et sert d'interface de création de facture. Elle permet également le suivi des remises de chèques reçus par le BDE et des crédits de la Société générale. Factures @@ -90,7 +90,7 @@ présent à l'adresse suivante : On le remplit avec les données de la facture et les données du BDE, hard-codées. On copie le template rempli dans un ficher tex dans un dossier temporaire. On fait ensuite 2 appels à ``pdflatex`` pour générer la facture au format PDF. -Les deux appels sont nécessaires, il y a besoin d'un double rendu. Ensuite, le PDF est envoyé à l'utilisateur et on +Les deux appels sont nécessaires, il y a besoin d'un double rendu. Ensuite, le PDF est envoyé à l'utilisateur⋅rice et on supprime les données temporaires. On remarque que les PDF sont générés à la volée et ne sont pas sauvegardés. Niveau performances, cela prend du temps @@ -174,39 +174,39 @@ Modèle Cette sous-application dispose d'un unique modèle "SogeCredit" avec les champs suivant : -* ``user`` : ``OneToOneField`` vers ``User``, utilisateur associé à ce crédit (relation ``OneToOne`` car chaque - utilisateur ne peut bénéficier qu'une seule fois d'un crédit de la Société générale) +* ``user`` : ``OneToOneField`` vers ``User``, utilisateur⋅rice associé à ce crédit (relation ``OneToOne`` car chaque + utilisateur⋅rice ne peut bénéficier qu'une seule fois d'un crédit de la Société générale) * ``transactions`` : ``ManyToManyField`` vers ``MembershipTransaction``, liste des transactions d'adhésion associées à ce crédit, généralement adhésion BDE+Kfet+WEI même si cela n'est pas restreint * ``credit_transaction`` : ``OneToOneField`` vers ``SpecialTransaction``, peut être nulle, transaction de crédit de la - Société générale vers la note de l'utilisateur si celui-ci a été validé. C'est d'ailleurs le témoin + Société générale vers la note de l'utilisateur⋅rice si celui-ci a été validé. C'est d'ailleurs le témoin de validation du crédit. -On sait qu'un utilisateur a déjà demandé un crédit de la Société générale s'il existe un crédit associé à cet -utilisateur avec une transaction associée. Par ailleurs, le modèle ``Profile`` contient une propriété ``soge`` qui +On sait qu'un⋅e utilisateur⋅rice a déjà demandé un crédit de la Société générale s'il existe un crédit associé à cet⋅te +utilisateur⋅rice avec une transaction associée. Par ailleurs, le modèle ``Profile`` contient une propriété ``soge`` qui traduit exactement ceci, et qui vaut ``False`` si jamais l'application Trésorerie n'est pas chargée. -Si jamais l'utilisateur n'a pas encore demandé de crédit de la Société générale (ou que celui-ci n'est pas encore validé), -l'utilisateur peut demander un tel crédit lors de son adhésion BDE, de sa réadhésion BDE ou de son inscription au WEI. -Dans les deux premiers cas, il est invité à jumeler avec une nouvelle adhésion Kfet (merci de d'abord se réadhérer au +Si jamais l'utilisateur⋅rice n'a pas encore demandé de crédit de la Société générale (ou que celui-ci n'est pas encore validé), +l'utilisateur⋅rice peut demander un tel crédit lors de son adhésion BDE, de sa réadhésion BDE ou de son inscription au WEI. +Dans les deux premiers cas, iel est invité⋅e à jumeler avec une nouvelle adhésion Kfet (merci de d'abord se réadhérer au BDE avant la Kfet dans ce cas). Lorsqu'une telle demande est faite, l'adhésion est créée avec une transaction d'adhésion invalide. Cela implique que la note source n'est pas débitée et la note destination n'est pas créditée. -Sur son interface, le trésorier peut récupérer les crédits de Société générale invalides. Deux options s'offrent à lui : +Sur son interface, læ trésorièr⋅e peut récupérer les crédits de Société générale invalides. Deux options s'offrent à ellui : -* Supprimer la demande. Dans ce cas, les transactions vont être validées, la note de l'utilisateur sera débité, les - clubs seront crédités. Puisque la demande sera supprimée, l'utilisateur pourra à nouveau à l'avenir déclarer avoir - ouvert un compte à la Société générale. Cette option est utile dans le cas où l'utilisateur est un boulet (ou pas, +* Supprimer la demande. Dans ce cas, les transactions vont être validées, la note de l'utilisateur⋅rice sera débité, les + clubs seront crédités. Puisque la demande sera supprimée, l'utilisateur⋅rice pourra à nouveau à l'avenir déclarer avoir + ouvert un compte à la Société générale. Cette option est utile dans le cas où l'utilisateur⋅rice est un boulet (ou pas, pour d'autres raisons) et a déclaré vouloir ouvrir un compte à la Société générale sans ne rien faire. - Cette action est irréversible, et n'est pas possible si la note de l'utilisateur n'a pas un solde suffisant. + Cette action est irréversible, et n'est pas possible si la note de l'utilisateur⋅rice n'a pas un solde suffisant. -* Valider la demande. Dans ce cas, un crédit de la note "Virements bancaires" vers la note de l'utilisateur sera créé, +* Valider la demande. Dans ce cas, un crédit de la note "Virements bancaires" vers la note de l'utilisateur⋅rice sera créé, la transaction sera liée à la demande via le champ ``credit_note`` (et donc la demande déclarée valide), et toutes les transactions d'adhésion seront déclarées valides. -* Demander à un respo info s'il y a un problème pour le régler avant de faire des bêtises. Je l'admets, ça fait trois options. +* Demander à un⋅e respo info s'il y a un problème pour le régler avant de faire des bêtises. Je l'admets, ça fait trois options. La validité d'une transaction d'adhésion n'a aucune influence sur l'adhésion elle-même. Toutefois, cela se remarque rapidement ... diff --git a/docs/apps/wei.rst b/docs/apps/wei.rst index 51d3375b..43b8f0f1 100644 --- a/docs/apps/wei.rst +++ b/docs/apps/wei.rst @@ -23,10 +23,10 @@ Champs hérités de ``Club`` de l'application ``member`` : * ``membership_start`` : ``DateField``, date à partir de laquelle il est possible de s'inscrire au WEI. * ``membership_end`` : ``DateField``, date de fin d'adhésion possible au WEI. * ``membership_duration`` : ``PositiveIntegerField``, inutilisé dans le cas d'un WEI, vaut ``None``. -* ``membership_fee_paid`` : ``PositiveIntegerField``, montant de la cotisation (en centimes) pour qu'un élève normalien - (donc rémunéré) puisse adhérer. -* ``membership_fee_unpaid`` : ``PositiveIntegerField``, montant de la cotisation (en centimes) pour qu'un étudiant - normalien (donc non rémunéré) puisse adhérer. +* ``membership_fee_paid`` : ``PositiveIntegerField``, montant de la cotisation (en centimes) pour qu'un⋅e élève normalien⋅ne + (donc rémunéré⋅e) puisse adhérer. +* ``membership_fee_unpaid`` : ``PositiveIntegerField``, montant de la cotisation (en centimes) pour qu'un⋅e étudiant⋅e + normalien⋅ne (donc non rémunéré⋅e) puisse adhérer. * ``name`` : ``CharField``, nom du WEI. * ``require_memberships`` : ``BooleanField``, vaut toujours ``True`` pour le WEI. @@ -65,27 +65,27 @@ que de dissocier les rôles propres au WEI des rôles s'appliquant pour n'import WEIRegistration ~~~~~~~~~~~~~~~ -Inscription au WEI, contenant les informations avant validation. Ce modèle est créé dès lors que quelqu'un se pré-inscrit au WEI. +Inscription au WEI, contenant les informations avant validation. Ce modèle est créé dès lors que quelqu'un⋅e se pré-inscrit au WEI. -* ``user`` : ``ForeignKey(User)``, utilisateur qui s'est pré-inscrit. Ce champ est unique avec ``wei``. -* ``wei`` : ``ForeignKey(WEIClub)``, le WEI auquel l'utilisateur s'est pré-inscrit. Ce champ est unique avec ``user``. -* ``soge_credit`` : ``BooleanField``, indique si l'utilisateur a déclaré vouloir ouvrir un compte à la Société générale. -* ``caution_check`` : ``BooleanField``, indique si l'utilisateur (en 2ème année ou plus) a bien remis son chèque de +* ``user`` : ``ForeignKey(User)``, utilisateur⋅rice qui s'est pré-inscrit⋅e. Ce champ est unique avec ``wei``. +* ``wei`` : ``ForeignKey(WEIClub)``, le WEI auquel l'utilisateur⋅rice s'est pré-inscrit⋅e. Ce champ est unique avec ``user``. +* ``soge_credit`` : ``BooleanField``, indique si l'utilisateur⋅rice a déclaré vouloir ouvrir un compte à la Société générale. +* ``caution_check`` : ``BooleanField``, indique si l'utilisateur⋅rice (en 2ème année ou plus) a bien remis son chèque de caution auprès de la trésorerie. -* ``birth_date`` : ``DateField``, date de naissance de l'utilisateur. +* ``birth_date`` : ``DateField``, date de naissance de l'utilisateur⋅rice. * ``gender`` : ``CharField`` parmi ``male`` (Homme), ``female`` (Femme), ``non binary`` (Non binaire), genre de la personne. -* ``health_issues`` : ``TextField``, problèmes de santé déclarés par l'utilisateur. +* ``health_issues`` : ``TextField``, problèmes de santé déclarés par l'utilisateur⋅rice. * ``emergency_contact_name`` : ``CharField``, nom du contact en cas d'urgence. * ``emergency_contact_phone`` : ``CharField``, numéro de téléphone du contact en cas d'urgence. -* ``ml_events_registration`` : ``BooleanField``, déclare si l'utilisateur veut s'inscrire à la liste de diffusion des +* ``ml_events_registration`` : ``BooleanField``, déclare si l'utilisateur⋅rice veut s'inscrire à la liste de diffusion des événements du BDE (1A uniquement) -* ``ml_art_registration`` : ``BooleanField``, déclare si l'utilisateur veut s'inscrire à la liste de diffusion des +* ``ml_art_registration`` : ``BooleanField``, déclare si l'utilisateur⋅rice veut s'inscrire à la liste de diffusion des actualités du BDA (1A uniquement) -* ``ml_sport_registration`` : ``BooleanField``, déclare si l'utilisateur veut s'inscrire à la liste de diffusion des +* ``ml_sport_registration`` : ``BooleanField``, déclare si l'utilisateur⋅rice veut s'inscrire à la liste de diffusion des actualités du BDS (1A uniquement) -* ``first_year`` : ``BooleanField``, indique si l'inscription est d'un 1A ou non. Non modifiable par n'importe qui. +* ``first_year`` : ``BooleanField``, indique si l'inscription est d'un⋅e 1A ou non. Non modifiable par n'importe qui. * ``information_json`` : ``TextField`` non modifiable manuellement par n'importe qui stockant les informations du - questionnaire d'inscription au WEI pour les 1A, et stocke les demandes faites par un 2A+ concerant bus, équipes et rôles. + questionnaire d'inscription au WEI pour les 1A, et stocke les demandes faites par un⋅e 2A+ concernant bus, équipes et rôles. On utilise un ``TextField`` contenant des données au format JSON pour permettre de la modularité au fil des années, sans avoir à tout casser à chaque fois. @@ -94,19 +94,19 @@ WEIMembership Ce modèle hérite de ``Membership`` et contient les informations d'une adhésion au WEI. -* ``bus`` : ``ForeignKey(Bus)``, bus dans lequel se trouve l'utilisateur. +* ``bus`` : ``ForeignKey(Bus)``, bus dans lequel se trouve l'utilisateur⋅rice. * ``team`` : ``ForeignKey(BusTeam)`` pouvant être nulle (pour les chefs de bus et électrons libres), équipe dans laquelle - se trouve l'utilisateur. + se trouve l'utilisateur⋅rice. * ``registration`` : ``OneToOneField(WEIRegistration)``, informations de la pré-inscription. Champs hérités du modèle ``Membership`` : * ``club`` : ``ForeignKey(Club)``, club lié à l'adhésion. Doit être un ``WEIClub``. -* ``user`` : ``ForeignKey(User)``, utilisateur adhéré. +* ``user`` : ``ForeignKey(User)``, utilisateur⋅rice qui a adhéré. * ``date_start`` : ``DateField``, date de début d'adhésion. * ``date_end`` : ``DateField``, date de fin d'adhésion. * ``fee`` : ``PositiveIntegerField``, montant de la cotisation payée. -* ``roles`` : ``ManyToManyField(Role)``, liste des rôles endossés par l'adhérent. Les rôles doivent être des ``WEIRole``. +* ``roles`` : ``ManyToManyField(Role)``, liste des rôles endossés par l'adhérent⋅e. Les rôles doivent être des ``WEIRole``. Graphe des modèles ~~~~~~~~~~~~~~~~~~ @@ -123,32 +123,32 @@ Fonctionnement Création d'un WEI ~~~~~~~~~~~~~~~~~ -Seul un respo info peut créer un WEI. Pour cela, se rendre dans l'onglet WEI, puis "Liste des WEI" et enfin -"Créer un WEI". Diverses informations sont demandées, comme le nom du WEI, l'adresse mail de contact, l'année du WEI +Seul un⋅e respo info peut créer un WEI. Pour cela, se rendre dans l'onglet WEI, puis « Liste des WEI » et enfin +« Créer un WEI ». Diverses informations sont demandées, comme le nom du WEI, l'adresse mail de contact, l'année du WEI (doit être unique), les dates de début et de fin, et les dates pendant lesquelles les utilisateurs peuvent s'inscrire. Don des droits à un GC WEI ~~~~~~~~~~~~~~~~~~~~~~~~~~ -Le GC WEI peut gérer tout ce qui a un rapport avec le WEI. Il ne peut cependant pas créer le WEI, ce privilège est -réservé au respo info. Pour avoir ses droits, le GC WEI doit s'inscrire au WEI avec le rôle GC WEI, et donc payer -en premier sa cotisation. C'est donc au respo info de créer l'adhésion du GC WEI. Voir ci-dessous pour l'inscription au WEI. +Læ GC WEI peut gérer tout ce qui a un rapport avec le WEI. Iel ne peut cependant pas créer le WEI, ce privilège est +réservé aux respos info. Pour avoir ses droits, læ GC WEI doit s'inscrire au WEI avec le rôle GC WEI, et donc payer +en premièr⋅e sa cotisation. C'est donc aux respos info de créer l'adhésion du GC WEI. Voir ci-dessous pour l'inscription au WEI. S'inscrire au WEI ~~~~~~~~~~~~~~~~~ -N'importe quel utilisateur peut s'auto-inscrire au WEI, lorsque les dates d'adhésion le permettent. Ceux qui se sont -déjà inscrits peuvent également inscrire un 1A. Seuls les GC WEI et les respo info peuvent inscrire un autre 2A+. +N'importe quel⋅le utilisateur⋅rice peut s'auto-inscrire au WEI, lorsque les dates d'adhésion le permettent. Celleux qui se sont +déjà inscrit⋅es peuvent également inscrire un⋅e 1A. Seul⋅es les GC WEI et les respos info peuvent inscrire un⋅e autre 2A+. À tout moment, tant que le WEI n'est pas passé, l'inscription peut être modifiée, même après validation. -Inscription d'un 2A+ -^^^^^^^^^^^^^^^^^^^^ +Inscription d'un⋅e 2A+ +^^^^^^^^^^^^^^^^^^^^^^ -Comme indiqué, les 2A+ sont assez autonomes dans leur inscription au WEI. Ils remplissent le questionnaire et sont -ensuite pré-inscrits. Le questionnaire se compose de plusieurs champs (voir WEIRegistration) : +Comme indiqué, les 2A+ sont assez autonomes dans leur inscription au WEI. Iels remplissent le questionnaire et sont +ensuite pré-inscrit⋅es. Le questionnaire se compose de plusieurs champs (voir WEIRegistration) : -* Est-ce que l'utilisateur a déclaré avoir ouvert un compte à la Société générale ? (Option disponible uniquemement +* Est-ce que l'utilisateur⋅rice a déclaré avoir ouvert un compte à la Société générale ? (Option disponible uniquemement si cela n'a pas été fait une année avant) * Date de naissance * Genre (Homme/Femme/Non-binaire) @@ -159,17 +159,17 @@ ensuite pré-inscrits. Le questionnaire se compose de plusieurs champs (voir WEI * Équipes préférées (choix multiple éventuellement vide, vide pour les chefs de bus/staff) * Rôles souhaités -Les trois derniers champs n'ont aucun caractère définitif et sont simplement là en suggestion pour le GC WEI qui +Les trois derniers champs n'ont aucun caractère définitif et sont simplement là en suggestion pour læ GC WEI qui validera l'inscription. C'est utile si on hésite entre plusieurs bus. L'inscription est ensuite créée, le GC WEI devra ensuite la valider (voir plus bas). -Inscription d'un 1A -^^^^^^^^^^^^^^^^^^^ +Inscription d'un⋅e 1A +^^^^^^^^^^^^^^^^^^^^^ -N'importe quelle personne déjà inscrite au WEI peut inscrire un 1A. Le formulaire 1A est assez peu différent du formulaire 2A+ : +N'importe quelle personne déjà inscrite au WEI peut inscrire un⋅e 1A. Le formulaire 1A est assez peu différent du formulaire 2A+ : -* Est-ce que l'utilisateur a déclaré avoir ouvert un compte à la Société générale ? +* Est-ce que l'utilisateur⋅rice a déclaré avoir ouvert un compte à la Société générale ? * Date de naissance * Genre (Homme/Femme/Non-binaire) * Problèmes de santé @@ -179,10 +179,10 @@ N'importe quelle personne déjà inscrite au WEI peut inscrire un 1A. Le formula * S'inscrire à la ML BDA * S'inscrire à la ML BDS -Le 1A ne peut donc pas choisir de son bus et de son équipe, et peut s'inscrire aux listes de diffusion. +Læ 1A ne peut donc pas choisir de son bus et de son équipe, et peut s'inscrire aux listes de diffusion. Il y a néanmoins une différence majeure : une fois le formulaire rempli, un questionnaire se lance. Ce questionnaire peut varier au fil des années (voir section Questionnaire), et contient divers formulaires de collecte -de données qui serviront à déterminer quel est le meilleur bus pour ce nouvel utilisateur. +de données qui serviront à déterminer quel est le meilleur bus pour ce⋅tte nouvelleau utilisateur⋅rice. Questionnaire 1A ^^^^^^^^^^^^^^^^ @@ -200,7 +200,7 @@ Je veux changer d'algorithme de répartition, que faire ? Cette section est plus technique et s'adresse surtout aux respos info en cours de mandat. -Première règle : on ne supprime rien (sauf si vraiment c'est du mauvais boulot). En prenant exemple sur des fichiers déjà existant tels que ``apps/wei/forms/surveys/wei2020.py``, créer un nouveau fichier ``apps/wei/forms/surveys/wei20XY.py``. Ce fichier doit inclure les éléments suivants : +Première règle : on ne supprime rien (sauf si vraiment c'est du mauvais boulot). En prenant exemple sur des fichiers déjà existant tels que ``apps/wei/forms/surveys/wei2021.py``, créer un nouveau fichier ``apps/wei/forms/surveys/wei20XY.py``. Ce fichier doit inclure les éléments suivants : WEISurvey """"""""" @@ -223,7 +223,7 @@ Une classe héritant de ``wei.forms.surveys.base.WEISurvey``, comportant les él Naturellement, il est implicite qu'une fonction ayant pour premier argument ``cls`` doit être annotée par ``@classmethod``. Nativement, la classe ``WEISurvey`` comprend les informations suivantes : -* ``registration``, le modèle ``WEIRegistration`` de l'utilisateur qui remplit le questionnaire +* ``registration``, le modèle ``WEIRegistration`` de l'utilisateur⋅rice qui remplit le questionnaire * ``information``, instance de ``WEISurveyInformation``, contient les données du questionnaire en cours de remplissage. * ``get_wei(cls)``, renvoie le WEI correspondant à l'année du sondage. * ``save(self)``, enregistre les informations du sondage dans l'objet ``registration`` associé, qui est ensuite @@ -291,7 +291,7 @@ pour unique effet d'appeler la fonction ``run_algorithm`` décrite plus tôt. Un n'a pas été évoqué d'adhésion. L'adhésion est ensuite manuelle, l'algorithme ne fournit qu'une suggestion. Cette structure, complexe mais raisonnable, permet de gérer plus ou moins proprement la répartition des 1A, -en limitant très fortement le hard code. Ami nouveau développeur, merci de bien penser à la propreté du code :) +en limitant très fortement le hard code. Ami nouvelleeau développeur⋅se, merci de bien penser à la propreté du code :) En particulier, on évitera de mentionner dans le code le nom des bus, et profiter du champ ``information_json`` présent dans le modèle ``Bus``. @@ -300,34 +300,34 @@ Valider les inscriptions Cette partie est moins technique. -Une fois la pré-inscription faite, elle doit être validée par le BDE, afin de procéder au paiement. Le GC WEI a accès à +Une fois la pré-inscription faite, elle doit être validée par le BDE, afin de procéder au paiement. Læ GC WEI a accès à la liste des inscriptions non validées, soit sur la page de détails du WEI, soit sur un tableau plus large avec filtre. Une inscription non validée peut soit être validée, soit supprimée (la suppression est irréversible). -Lorsque le GC WEI veut valider une inscription, il a accès au récapitulatif de l'inscription ainsi qu'aux informations -personnelles de l'utilisateur. Il lui est proposé de les modifier si besoin (du moins les informations liées au WEI, -pas les informations personnelles). Il a enfin accès aux résultats du sondage et la sortie de l'algorithme s'il s'agit -d'un 1A, aux préférences d'un 2A+. Avant de valider, le GC WEI doit sélectionner un bus, éventuellement une équipe -et un rôle. Si c'est un 1A et que l'algorithme a tourné, ou si c'est un 2A+ qui n'a fait qu'un seul choix de bus, +Lorsque læ GC WEI veut valider une inscription, iel a accès au récapitulatif de l'inscription ainsi qu'aux informations +personnelles de l'utilisateur⋅rice. Il lui est proposé de les modifier si besoin (du moins les informations liées au WEI, +pas les informations personnelles). Iel a enfin accès aux résultats du sondage et la sortie de l'algorithme s'il s'agit +d'un⋅e 1A, aux préférences d'un⋅e 2A+. Avant de valider, læ GC WEI doit sélectionner un bus, éventuellement une équipe +et un rôle. Si c'est un⋅e 1A et que l'algorithme a tourné, ou si c'est un⋅e 2A+ qui n'a fait qu'un seul choix de bus, d'équipe, de rôles, les champs sont automatiquement pré-remplis. Quelques restrictions cependant : -* Si c'est un 2A+, le chèque de caution doit être déclaré déposé +* Si c'est un⋅e 2A+, le chèque de caution doit être déclaré déposé * Si l'inscription se fait via la Société générale, un message expliquant la situation apparaît : la transaction de - paiement sera créée mais invalidée, les trésoriers devront confirmer plus tard sur leur interface que le compte + paiement sera créée mais invalidée, les trésorièr⋅es devront confirmer plus tard sur leur interface que le compte à la Société générale a bien été créé avant de valider la transaction (voir `Trésorerie `_ section Crédit de la Société générale). -* Dans le cas contraire, l'utilisateur doit avoir le solde nécessaire sur sa note avant de pouvoir adhérer. -* L'utilisateur doit enfin être membre du club Kfet. Un lien est présent pour le faire adhérer ou réadhérer selon le cas. +* Dans le cas contraire, l'utilisateur⋅rice doit avoir le solde nécessaire sur sa note avant de pouvoir adhérer. +* L'utilisateur⋅rice doit enfin être membre du club Kfet. Un lien est présent pour le faire adhérer ou réadhérer selon le cas. -Si tout est bon, le GC WEI peut valider. L'utilisateur a bien payé son WEI, et son interface est un peu plus grande. -Il peut toujours changer ses paramètres au besoin. Un 1A ne voit rien de plus avant la fin du WEI. +Si tout est bon, læ GC WEI peut valider. L'utilisateur⋅rice a bien payé son WEI, et son interface est un peu plus grande. +Iel peut toujours changer ses paramètres au besoin. Un⋅e 1A ne voit rien de plus avant la fin du WEI. -Un adhérent WEI non 1A a accès à la liste des bus, des équipes et de leur descriptions. Les chefs de bus peuvent gérer -les bus et leurs équipes. Les chefs d'équipe peuvent gérer leurs équipes. Cela inclut avoir accès à la liste des membres +Un⋅e adhérent⋅e WEI non 1A a accès à la liste des bus, des équipes et de leur descriptions. Les chef⋅fes de bus peuvent gérer +les bus et leurs équipes. Les chef⋅fes d'équipe peuvent gérer leurs équipes. Cela inclut avoir accès à la liste des membres de ce bus / de cette équipe. -Un export au format PDF de la liste des membres *visibles* est disponible pour chacun. +Un export au format PDF de la liste des membres *visibles* est disponible pour chacun⋅e. -Bon WEI à tous ! +Bon WEI à toustes ! diff --git a/docs/external_services/cas.rst b/docs/external_services/cas.rst index 36dedf3e..474fb5ba 100644 --- a/docs/external_services/cas.rst +++ b/docs/external_services/cas.rst @@ -3,7 +3,7 @@ Service d'Authentification Centralisé (CAS) Un `CAS `_ est déployé sur la Note Kfet. Il est accessible à l'adresse ``_. -Il a pour but uniquement d'authentifier les utilisateurs via la note et ne communique +Il a pour but uniquement d'authentifier les utilisateur⋅rices via la note et ne communique que peu d'informations. Configuration diff --git a/docs/external_services/index.rst b/docs/external_services/index.rst index ab1539aa..f995a24d 100644 --- a/docs/external_services/index.rst +++ b/docs/external_services/index.rst @@ -12,9 +12,9 @@ Applications externes L'utilisation de la note par des services externes est actuellement en beta. Il est fort à parier que cette utilisation sera revue et améliorée à l'avenir. -Puisque la Note Kfet recense tous les comptes des adhérents BDE, les clubs ont alors +Puisque la Note Kfet recense tous les comptes des adhérent⋅es BDE, les clubs ont alors la possibilité de développer leurs propres applications et de les interfacer avec la -note. De cette façon, chaque application peut authentifier ses utilisateurs via la note, +note. De cette façon, chaque application peut authentifier ses utilisateur⋅rices via la note, et récupérer leurs adhésion, leur nom de note afin d'éventuellement faire des transferts via l'API. @@ -25,4 +25,4 @@ Deux protocoles d'authentification sont implémentées : À ce jour, il n'y a pas encore d'exemple d'utilisation d'application qui utilise ce mécanisme, mais on peut imaginer par exemple que la Mediatek ou l'AMAP implémentent -ces protocoles pour récupérer leurs adhérents. +ces protocoles pour récupérer leurs adhérent⋅es. diff --git a/docs/external_services/oauth2.rst b/docs/external_services/oauth2.rst index 6ee89621..76dead8b 100644 --- a/docs/external_services/oauth2.rst +++ b/docs/external_services/oauth2.rst @@ -2,12 +2,12 @@ OAuth2 ====== L'authentification `OAuth2 `_ est supportée par la -Note Kfet. Elle offre l'avantage non seulement d'identifier les utilisateurs, mais aussi -de transmettre des informations à un service tiers tels que des informations personnelles, -le solde de la note ou encore les adhésions de l'utilisateur, en l'avertissant sur -quelles données sont effectivement collectées. Ainsi, il est possible de développer des -appplications tierces qui peuvent se baser sur les données de la Note Kfet ou encore -faire des transactions. +Note Kfet. Elle offre l'avantage non seulement d'identifier les utilisateur⋅rices, mais +aussi de transmettre des informations à un service tiers tels que des informations +personnelles, le solde de la note ou encore les adhésions de l'utilisateur⋅rice, en +l'avertissant sur quelles données sont effectivement collectées. Ainsi, il est possible +de développer des appplications tierces qui peuvent se baser sur les données de la Note +Kfet ou encore faire des transactions. Configuration du serveur @@ -79,7 +79,7 @@ Il vous suffit de donner à votre application : * Les scopes, qui peuvent être récupérées sur cette page : ``_ * L'URL d'autorisation : ``_ * L'URL d'obtention de jeton : ``_ -* Si besoin, l'URL de récupération des informations de l'utilisateur : ``_ +* Si besoin, l'URL de récupération des informations de l'utilisateur⋅rice : ``_ N'hésitez pas à consulter la page ``_ pour s'imprégner du format renvoyé. @@ -88,14 +88,14 @@ du format renvoyé. Un petit mot sur les scopes : tel qu'implémenté, une scope est une permission unitaire (telle que décrite dans le modèle ``Permission``) associée à un club. Ainsi, un jeton - a accès à une scope si et seulement si le/la propriétaire du jeton dispose d'une adhésion + a accès à une scope si et seulement si læ propriétaire du jeton dispose d'une adhésion courante dans le club lié à la scope qui lui octroie cette permission. Par exemple, un jeton pourra avoir accès à la permission de créer des transactions en lien - avec un club si et seulement si le propriétaire du jeton est trésorier du club. + avec un club si et seulement si læ propriétaire du jeton est trésorièr⋅e du club. - La vérification des droits du propriétaire est faite systématiquement, afin de ne pas - faire confiance au jeton en cas de droits révoqués à son propriétaire. + La vérification des droits de læ propriétaire est faite systématiquement, afin de ne pas + faire confiance au jeton en cas de droits révoqués à saon propriétaire. Vous pouvez donc contrôler le plus finement possible les permissions octroyées à vos jetons. @@ -118,8 +118,8 @@ du format renvoyé. Par exemple, vous pourriez demander la permission d'accéder aux membres d'un club ou de faire des transactions, et agir - uniquement dans le cas où l'utilisateur connecté possède la - permission problématique. + uniquement dans le cas où l'utilisateur⋅rice connecté⋅e + possède la permission problématique. Avec Django-allauth ################### @@ -152,7 +152,7 @@ Le paramètre ``DOMAIN`` permet de changer d'instance de Note Kfet. Par défaut, se connectera à ``note.crans.org`` si vous ne renseignez rien. Le paramètre ``SCOPE`` permet de définir les scopes à demander. -Dans l'exemple ci-dessous, les permissions d'accéder à l'utilisateur +Dans l'exemple ci-dessous, les permissions d'accéder à l'utilisateur⋅rice et au profil sont demandées. En créant l'application sur la note, vous pouvez renseigner @@ -200,7 +200,7 @@ cas où elle n'est pas explicitement indiquée lors de l'autorisation. Lorsqu'un client veut s'authentifier via la Note Kfet, il va devoir accéder à une page d'authentification. La page d'autorisation est ``_, -c'est sur cette page qu'il faut rediriger les utilisateurs. Il faut mettre en paramètre GET : +c'est sur cette page qu'il faut rediriger les utilisateur⋅rices. Il faut mettre en paramètre GET : * ``client_id`` : l'identifiant client de l'application (public) ; * ``response_type`` : mettre ``code`` ; @@ -211,10 +211,10 @@ c'est sur cette page qu'il faut rediriger les utilisateurs. Il faut mettre en pa * ``state`` : optionnel, peut être utilisé pour permettre au client de détecter des requêtes provenant d'autres sites. -Sur cette page, les permissions demandées seront listées, et l'utilisateur aura le choix -d'accepter ou non. Dans les deux cas, l'utilisateur sera redirigée vers ``redirect_uri``, -avec pour paramètre GET soit le message d'erreur, soit un paramètre ``code`` correspondant -au code d'autorisation. +Sur cette page, les permissions demandées seront listées, et l'utilisateur⋅rice aura le +choix d'accepter ou non. Dans les deux cas, l'utilisateur⋅rice sera redirigée vers +``redirect_uri``, avec pour paramètre GET soit le message d'erreur, soit un paramètre +``code`` correspondant au code d'autorisation. Une fois ce code d'autorisation récupéré, il faut désormais récupérer le jeton d'accès. Il faut pour cela aller sur l'URL ``_, effectuer une diff --git a/docs/faq.rst b/docs/faq.rst index 18b8a4be..d8dbb1f7 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -19,13 +19,13 @@ Je souhaite consommer mais le solde de ma note est insuffisant -------------------------------------------------------------- .. note:: - Le BDE ne fait pas crédit à ses adhérents. Il est de ton devoir de t'assurer - d'avoir en permanence un solde positif sur ta note. Les permanenciers à la + Le BDE ne fait pas crédit à ses adhérent⋅es. Il est de ton devoir de t'assurer + d'avoir en permanence un solde positif sur ta note. Les permanencièr⋅es à la Kfet ont la possibilité de refuser une consommation qui fait passer en négatif, et ont obligation de refuser si la consommation est alcoolisée, en accord avec la règlementation en vigueur. - Les trésoriers connaissent la liste des personnes en situation irrégulière et + Les trésorièr⋅es connaissent la liste des personnes en situation irrégulière et n'hésiteront pas à faire des rappels pour recharger la note. @@ -34,9 +34,9 @@ Comment recharger ma note ? .. note:: Le solde de la note peut être rechargé soit par espèces, par chèque à l'ordre - de l'amicale des élèves de l'ENS Cachan, par carte bancaire via un terminal + de l'amicale des élèves de l'ENS Paris-Saclay, par carte bancaire via un terminal de paiement électronique ou encore par virement bancaire, dont les coordonnées - sont à demander auprès des trésoriers BDE. + sont à demander auprès des trésorièr⋅es BDE. Les trois premières options sont à faire directement dans la Kfet. @@ -47,7 +47,7 @@ Je pars en stage / en vacances. Puis-je bloquer ma note ? .. note:: Bien sûr : il te suffit de te rendre sur ton compte et de cliquer sur le bouton dédié. Ta note ne sera plus affichée par les autres personnes et les transferts - seront impossibles, sauf pour les trésoriers BDE et respo info. + seront impossibles, sauf pour les trésorièr⋅es BDE et respo info. Il est toutefois de ton devoir de rembourser tout ce que tu dois. @@ -56,36 +56,37 @@ Quelle est la limite maximale au nombre d'alias d'une note ? ------------------------------------------------------------ .. note:: - Certains parlent d'une dizaine d'alias par note. + Certain⋅es parlent d'une dizaine d'alias par note. Sois conscient⋅e qu'ajouter des alias ne peut qu'augmenter la probabilité de collisions avec une autre note, et peut aussi retarder la livraison de ta commande lors d'un perm bouffe. -Je suis trésorier d'un club, qu'ai-je le droit de faire ? ---------------------------------------------------------- +Je suis trésorièr⋅e d'un club, qu'ai-je le droit de faire ? +----------------------------------------------------------- .. note:: - Être trésorier d'un club donne la responsabilité de gérer la trésorerie du + Être trésorièr⋅e d'un club donne la responsabilité de gérer la trésorerie du club, et donc de gérer sa note. Vous obtenez donc le droit d'effectuer n'importe quelle transaction via la note en provenance ou à destination de la note de votre club. Vous pouvez également gérer les adhésions de votre club, - en permettant à n'importe quel adhérent BDE de rejoindre votre club, en prélevant - d'éventuels frais d'adhésion. Les paramètres du club peuvent être également modifiés. + en permettant à n'importe quel⋅le adhérent⋅e BDE de rejoindre votre club, en + prélevant d'éventuels frais d'adhésion. Les paramètres du club peuvent être + également modifiés. .. danger:: Avoir des droits sur la Note Kfet ne signifie pas que vous devez les utiliser. Chaque opération nécessitant des droits doit être fait pour une bonne raison, et doit avoir un lien avec votre club. Vous n'avez par exemple pas le droit - d'aller récupérer des informations personnelles d'adhérents pour une raison + d'aller récupérer des informations personnelles d'adhérent⋅es pour une raison personnelle. En revanche, faire le lien entre nom/prénom et nom de note est bien sûr permis pour faciliter des transferts. Tout abus de droits constaté pourra mener à des sanctions prises par le bureau du BDE. -Je suis trésorier d'un club, je n'arrive pas à voir le solde du club / faire des transactions ---------------------------------------------------------------------------------------------------- +Je suis trésorièr⋅e d'un club, je n'arrive pas à voir le solde du club / faire des transactions +----------------------------------------------------------------------------------------------------- .. note:: As-tu bien vérifié que tu t'es connecté⋅e initialement avec tous tes droits ? @@ -97,8 +98,8 @@ Je suis trésorier d'un club, je n'arrive pas à voir le solde du club / faire d opérations en empêchant l'accès à des opérations trop sensibles. -Je suis trésorier d'un club. Puis-je créer un bouton ? ------------------------------------------------------- +Je suis trésorièr⋅e d'un club. Puis-je créer un bouton ? +-------------------------------------------------------- .. note:: Oui bien sûr ! Tant qu'il redirige bien vers la note de ton club. @@ -114,20 +115,20 @@ Je suis trésorier d'un club. Puis-je créer un bouton ? devient accessible. -Après passation, je suis trésorier d'un club. Comment récupérer mes droits note ? ---------------------------------------------------------------------------------- +Après passation, je suis trésorièr⋅e d'un club. Comment récupérer mes droits note ? +----------------------------------------------------------------------------------- .. note:: - Tu dois pour cela contacter les trésoriers BDE (voir ci-dessous). Ils vous + Tu dois pour cela contacter les trésorièr⋅es BDE (voir ci-dessous). Iels vous expliqueront en détails vos droits et vos interdits et vous donneront les droits requis. -Je souhaite contacter un trésorier ----------------------------------- +Je souhaite contacter un⋅e trésorièr⋅e +-------------------------------------- .. note:: - Pour contacter un trésorier, il te suffit d'envoyer un mail à l'adresse + Pour contacter un⋅e trésorièr⋅e, il te suffit d'envoyer un mail à l'adresse `tresorerie.bde@lists.crans.org `_. Pense bien à donner ton nom de note, voire à envoyer un scan de ta carte d'identité si ta demande concerne un virement entre le compte du BDE et ton propre compte. @@ -137,9 +138,9 @@ J'ai trouvé un bug, comment le signaler ? ----------------------------------------- .. note:: - La Note Kfet est développée bénévolement par des membres du BDE. Malgré tous nos - efforts pour fournir une plateforme sans erreur et la plus ergonomique possible. - Toutefois, il n'est évidemment pas exclu que des bugs soient présents :) + La Note Kfet est développée bénévolement par des membres du BDE. Nous mettons + tous nos efforts pour fournir une plateforme sans erreur et la plus ergonomique + possible. Toutefois, il n'est évidemment pas exclu que des bugs soient présents :) Pour nous soumettre un bug, tu peux envoyer un mail à `notekfet2020@lists.crans.org `_ @@ -159,14 +160,14 @@ Je souhaite contribuer La Note Kfet est essentiellement développée par des responsables informatiques du BDE de l'ENS Paris-Saclay. Toutefois, si vous souhaitez contribuer, vous pouvez bien sûr le faire en accord avec la licence GPLv3 avec laquelle la Note Kfet est - distribuée. Pour cela, si vous êtes adhérent Crans, vous pouvez proposer une + distribuée. Pour cela, si vous êtes adhérent⋅e Crans, vous pouvez proposer une demande de fusion de votre code. Si ce n'est pas le cas, vous pouvez envoyer un mail à `notekfet2020@lists.crans.org `_. Dans les deux cas, merci de rejoindre le canal ``#note`` sur IRC :) -Contributeurs -------------- +Contributeur⋅rices +------------------ .. note:: La version 2020 de la Note Kfet a été développée sous le mandat de la @@ -183,15 +184,16 @@ Contributeurs * Yohann « ÿnérant » D'ANELLO * Benjamin « esum » GRAILLOT * Alexandre « erdnaxe » IOOSS + * Nicolas « nicomarg » MARGULIES Hébergement ----------- .. note:: - En accord entre de l'ENS Paris-Saclay et le Crans, l'instance de production présente - sur ``_ est hébergée sur l'un des serveurs du Crans. - Les données sont hébergées à l'adresse : + En accord entre le BDE de l'ENS Paris-Saclay et le Crans, l'instance de production + présente sur ``_ est hébergée sur l'un des serveurs du + Crans. Les données sont hébergées à l'adresse : .. code:: diff --git a/docs/getting_started.rst b/docs/getting_started.rst index 77b83ab4..e19c1781 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -1,12 +1,12 @@ La note, c'est quoi ? ===================== -La Note Kfet est un porte-monnaie virtuel proposé gratuitement à tous les adhérents BDE. -C'est le moyen de paiement privilégié au sein du campus, que ce soit pour payer des -activités du BDE, ou bien pour faire des remboursements entre amis. La note contient -également la base d'adhérents du BDE et contient de nombreux outils facilitant la vie -des différents bureaux de clubs, en particulier les trésoriers et surtout les trésoriers -BDE. +La Note Kfet est un porte-monnaie virtuel proposé gratuitement à toustes les +adhérent⋅es BDE. C'est le moyen de paiement privilégié au sein du campus, que ce soit +pour payer des activités du BDE, ou bien pour faire des remboursements entre ami⋅es. +La note contient également la base d'adhérent⋅es du BDE et contient de nombreux outils +facilitant la vie des différents bureaux de clubs, en particulier les trésorièr⋅es et +surtout les trésorièr⋅es BDE. La Note Kfet est accessible à l'adresse ``_. La version actuelle a été développée par le BDE 2020-2021, et est maintenue par les respos infos du BDE de @@ -23,7 +23,7 @@ Chaque adhérent⋅e BDE dispose d'un compte appelé « note », créé lors de Une note est associée à un solde en euros, et à un pseudo appelé « nom de note ». Le solde associé à la note correspond au solde de l'adhérent⋅e, avec lequel il est possible de payer tout ce qui est en lien avec le BDE. Le nom de note suffit à -identifier une personne, et il suffit par exemple de donner ce nom à un permanencier +identifier une personne, et il suffit par exemple de donner ce nom à un⋅e permanencièr⋅e à la Kfet pour acheter un produit. Faire une transaction @@ -34,10 +34,10 @@ d'un⋅e autre adhérent⋅e, pourvu que le montant de la transaction n'excède propre solde. Pour cela, il suffit d'aller sur la page de transferts, qui est la page par défaut après connexion : ``_ Le formulaire pour effectuer un transfert apparaît alors. En cliquant sur le bouton -« Je suis l'émetteur », le champ « Émetteurs » est directement complété avec votre -propre note. Il vous suffit alors de remplir le champ « Destinataires » avec le ou -les noms de note que vous voulez créditer, de spécifier le montant et la raison de -votre transfert, puis de cliquer sur le bouton « Virement ». Après quelques secondes, +« Je suis l'émetteur⋅rice », le champ « Émetteur⋅rices » est directement complété +avec votre propre note. Il vous suffit alors de remplir le champ « Destinataires » +avec le⋅s nom⋅s de note que vous voulez créditer, de spécifier le montant et la raison +de votre transfert, puis de cliquer sur le bouton « Virement ». Après quelques secondes, si votre solde est suffisant et que la transaction est acceptée, un message de confirmation apparaîtra et la transaction apparaîtra dans l'historique ci-dessous. @@ -49,7 +49,7 @@ Consulter ses données personnelles ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ La Note Kfet sert non seulement à faire des transactions d'argent virtuel au sein -du BDE, mais aussi à permettre au BDE et à ses clubs de gérer leurs adhérents. +du BDE, mais aussi à permettre au BDE et à ses clubs de gérer leurs adhérent⋅es. À cet effet, diverses informations personnelles sont collectées par la Note. Pour accéder à votre compte, une fois connecté⋅e, rendez-vous dans le menu en haut @@ -79,22 +79,22 @@ présentes sont : * Inscription aux listes de diffusion du BDE, du BDA et du BDS Les trois premières informations sont obligatoires pour pouvoir vous contacter -et pouvoir tenir un registre d'adhérent. +et pouvoir tenir un registre d'adhérent⋅es. Le numéro de téléphone et l'adresse ne sont utilisés uniquement en cas d'urgence, notamment en cas de WEI, et ne sont pas des champs obligatoires. De plus, promotion, département et section ne sont utilisés sérieusement que en cas de WEI, et ne sont pas utilisés sinon. -La distinction élève/étudiant permet de distinguer les achats qui peuvent avoir -des prix différents pour les élèves et pour les étudiants, notamment en cas de +La distinction élève/étudiant⋅e permet de distinguer les achats qui peuvent avoir +des prix différents pour les élèves et pour les étudiant⋅es, notamment en cas de transferts d'argent, de WEI ou d'adhésion à certains clubs. Hormis le pseudo, toutes ces informations ont un caractère confidentiel qui les -rend privées et inaccessible aux utilisateurs. Les trésoriers BDE et les respos +rend privées et inaccessible aux utilisateur⋅rices. Les trésorièr⋅es BDE et les respos info ont accès à toutes les informations (en cas de besoin uniquement, le cas contraire est considéré comme de l'abus de droit qui est punissable), et les -trésoriers de club ont accès au nom et au prénom afin de faciliter l'association +trésorièr⋅es de club ont accès au nom et au prénom afin de faciliter l'association à un nom de note. Dans la partie informations personnelles, il est également possible de modifier @@ -106,7 +106,7 @@ de nom de note. Le tableau des adhésions actives sur la partie du haut contient l'ensemble des clubs auxquels vous êtes adhérent⋅es, avec les dates de début, de fin, votre rôle au sein du club (généralement simple membre, mais cela peut également -être trésorier⋅ère par exemple) ainsi que la cotisation que vous avez éventuellement +être trésorièr⋅e par exemple) ainsi que la cotisation que vous avez éventuellement payée au club. L'historique des transactions contient l'ensemble des transactions qui ont fait diff --git a/docs/index.rst b/docs/index.rst index 2e7a2e2c..899c8277 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -3,7 +3,7 @@ Documentation de la Note Kfet 2020 Bienvenue sur la documentation de la Note Kfet 2020. Cette documentation est à la fois -destinée aux adhérents BDE pour découvrir le fonctionnement de la note, mais aussi aux +destinée aux adhérent⋅es BDE pour découvrir le fonctionnement de la note, mais aussi aux respos info qui souhaitent découvrir comment fonctionne la note sous le capot. Des informations complémentaires sont également disponibles sur le `Wiki Crans `_. diff --git a/docs/install-dev.rst b/docs/install-dev.rst index d3e616b2..a064d9e6 100644 --- a/docs/install-dev.rst +++ b/docs/install-dev.rst @@ -162,8 +162,8 @@ Ouvrez votre navigateur, tapez ``_, enjoy :) optimisé pour recevoir des requêtes en parallèle ou être utilisé en production. -Créer un super-utilisateur --------------------------- +Créer un⋅e super-utilisateur⋅rice +--------------------------------- -La commande ``./manage.py createsuperuser`` vous permettra de créer un super-utilisateur -initial. +La commande ``./manage.py createsuperuser`` vous permettra de créer un⋅e +super-utilisateur⋅rice initial⋅e. diff --git a/docs/install.rst b/docs/install.rst index b625bfae..4edf3bb0 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -15,7 +15,7 @@ version 1.11, qui n'est plus maintenue par Django depuis déjà quelques mois. Les versions stables de Django sont les versions 2.2 et 3.2, Debian Bullseye utilisant la version 2.2. -Afin de permettre à ses utilisateurs d'utiliser les dernières fonctionnalités de +Afin de permettre à ses utilisateur⋅rices d'utiliser les dernières fonctionnalités de certains paquets, Debian a créé une distribution particulière, appelée ``buster-backports``. Cette distribution contient des paquets de la distribution à venir « ``testing`` » (``bullseye`` à l'heure où cette documentation est écrite) @@ -187,7 +187,7 @@ clé sous forme de chaîne de caractère suffisamment longue (64 caractères par qui n'est pas à transmettre et qui évite d'autres sites malveillants de faire des requêtes directement sur la note. -Le champ ``CONTACT_EMAIL`` correspond l'adresse mail que les adhérent⋅e⋅s peuvent contacter +Le champ ``CONTACT_EMAIL`` correspond l'adresse mail que les adhérent⋅es peuvent contacter en cas de problème. C'est là où le champ ``Nous contacter`` redirigera. Le champ ``NOTE_URL`` correspond au nom de domaine autorisé à accéder au site. C'est également @@ -636,5 +636,5 @@ On peut enfin redémarrer le serveur Web. Les données ont bien été copiées. .. caution:: - On ne copiera **jamais** des données d'adhérent⋅e⋅s sur une machine personnelle. + On ne copiera **jamais** des données d'adhérent⋅es sur une machine personnelle. Ce type d'opération doit s'effectuer impérativement entre des serveurs du BDE. diff --git a/docs/scripts.rst b/docs/scripts.rst index 53545171..b128b863 100644 --- a/docs/scripts.rst +++ b/docs/scripts.rst @@ -139,8 +139,8 @@ de diffusion utiles. Il prend 2 options : * ``--type``, qui prend en argument ``members`` (défaut), ``clubs``, ``events``, ``art``, - ``sport``, qui permet respectivement de sortir la liste des adresses mails des adhérents - actuels (pour la liste ``adherents.bde@lists.crans.org), des clubs (pour + ``sport``, qui permet respectivement de sortir la liste des adresses mails des adhérent⋅es + actuel⋅les (pour la liste ``adherents.bde@lists.crans.org), des clubs (pour ``clubs@lists.crans.org``), des personnes à abonner à ``evenements@lists.crans.org``, à ``all.bda@lists.crans.org`` et enfin à ``bds@lists.crans.org``. * ``--lang``, qui prend en argument ``fr`` ou ``en``. N'est utile que pour la ML événements, @@ -157,8 +157,8 @@ malheureusement pas aussi simple que de simplement supposer que ces listes sont À terme, il pourrait être envisageable de synchroniser automatiquement les listes avec la note. -Suppression d'un utilisateur ----------------------------- +Suppression d'un⋅e utilisateur⋅rice +----------------------------------- Le script s'appelle ``force_delete_user``. @@ -167,7 +167,7 @@ Le script s'appelle ``force_delete_user``. Ce script est dangereux. À n'utiliser qu'avec de très grosses pincettes si vous savez ce que vous faites. Seul cas d'usage pour l'instant recensé : supprimer des comptes en double qui se sont malencontreusement retrouvés validés pour raison de Sogé et de mauvaise - communication au sein des trésorier⋅ère⋅s. + communication au sein des trésorièr⋅es. Il n'est certainement pas prévu de supprimer des vrais comptes existants via ce script. On ne supprime pas l'historique. Si jamais quelqu'un demanderait à supprimer son compte, @@ -175,8 +175,8 @@ Le script s'appelle ``force_delete_user``. Ce script est utile lorsqu'il faut supprimer un compte créer par erreur. Tant que la validation n'est pas faite, il suffit en général de cliquer sur le bouton « Supprimer le compte » sur -l'interface de validation. Cela supprimera l'utilisateur et le profil associé, sans toucher -à une quelconque note puisqu'elle ne sera pas créée. +l'interface de validation. Cela supprimera l'utilisateur⋅rice et le profil associé, sans +toucher à une quelconque note puisqu'elle ne sera pas créée. Ce script supprime donc un compte ainsi que toutes les données associées (note, alias, transactions). Il n'est donc pas à prendre à la légère, et vous devez savoir ce que vous @@ -192,8 +192,8 @@ pour supprimer tout ce qu'il faut, et une validation manuelle sera requise pour la suppression. L'option ``--doit`` évite cette confirmation manuelle. **Vous n'avez jamais à utiliser cette option en théorie.** -À la fin du processus, un mail est envoyé aux administrateurs pour les prévenir des -élements supprimés. +À la fin du processus, un mail est envoyé aux administrateur⋅rices pour les prévenir des +éléments supprimés. Des données réelles jamais tu ne supprimeras. @@ -210,14 +210,14 @@ la Note Kfet 2015. s'est déroulé. -Ajouter un super-utilisateur ----------------------------- +Ajouter un⋅e super-utilisateur⋅rice +----------------------------------- Le script s'appelle ``make_su``. Il prend en argument un pseudo. -Avec l'option ``--SUPER, -S``, la personne avec ce pseudo devient super-utilisateur, +Avec l'option ``--SUPER, -S``, la personne avec ce pseudo devient super-utilisateur⋅rice, et obtiens donc les pleins pouvoirs sur la note. À ne donner qu'aux respos info. Avec l'option ``--STAFF, -s``, la personne avec ce pseudo acquiert le statut équipe, @@ -264,20 +264,20 @@ Envoi des rappels de négatif Le script s'appelle ``send_mail_to_negative_balances``. -Il sert à rappeler aux adhérent⋅e⋅s et clubs en négatif qu'ils le sont, mais également -à envoyer aux trésorier⋅ère⋅s et respos info la liste des adhérent⋅e⋅s en négatif. +Il sert à rappeler aux adhérent⋅es et clubs en négatif qui le sont, mais également +à envoyer aux trésorierèr⋅es et respos info la liste des adhérent⋅es en négatif. Il prend les options suivantes : * ``--spam, -s`` : envoie à chaque adhérent⋅e en négatif un rappel par mail pour recharger -* ``--report, -r`` : envoie le rapport aux trésorier⋅ère⋅s et respos info +* ``--report, -r`` : envoie le rapport aux trésorierèr⋅es et respos info * ``--negative-amount,-n`` : définit le solde maximal en-dessous duquel les notes apparaitront sur le rapport / seront spammées -* ``--add-years, -y`` : ajoute également les adhérent⋅e⋅s des ``n`` dernières années +* ``--add-years, -y`` : ajoute également les adhérent⋅es des ``n`` dernières années -Ce script est appelé tous les mardis à 5h00 pour spammer les utilisateur⋅rice⋅s en -négatif et tous les 6 du mois pour envoyer le rapport des notes d'adhérent⋅e⋅s ou de -vieux/vieilles adhérent⋅e⋅s de moins d'un an sous -10 €. +Ce script est appelé tous les mardis à 5h00 pour spammer les utilisateur⋅ices en +négatif et tous les 6 du mois pour envoyer le rapport des notes d'adhérent⋅es ou de +vieilleux adhérent⋅es de moins d'un an sous -10 €. Envoi des rapports @@ -285,8 +285,8 @@ Envoi des rapports Le script s'appelle ``send_reports``. -Les utilisateurs ont la possibilité de recevoir sur demande un rapport à la fréquence de -leur choix (en jours) des transactions effectuées sur leur note. +Les utilisateur⋅rices ont la possibilité de recevoir sur demande un rapport à la +fréquence de leur choix (en jours) des transactions effectuées sur leur note. Le script prend 2 options : diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index 9ce95379..6542cc2a 100644 --- a/locale/de/LC_MESSAGES/django.po +++ b/locale/de/LC_MESSAGES/django.po @@ -1446,8 +1446,10 @@ msgid "trusted" msgstr "" #: apps/note/models/notes.py:243 -msgid "frienship" -msgstr "" +#, fuzzy +#| msgid "Manage aliases" +msgid "friendship" +msgstr "Aliases bearbeiten" #: apps/note/models/notes.py:248 #, python-brace-format diff --git a/locale/es/LC_MESSAGES/django.po b/locale/es/LC_MESSAGES/django.po index a5482763..73702a57 100644 --- a/locale/es/LC_MESSAGES/django.po +++ b/locale/es/LC_MESSAGES/django.po @@ -1433,8 +1433,10 @@ msgid "trusted" msgstr "amigo" #: apps/note/models/notes.py:243 -msgid "frienship" -msgstr "amistad" +#, fuzzy +#| msgid "friendships" +msgid "friendship" +msgstr "amistades" #: apps/note/models/notes.py:248 #, python-brace-format diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index 0caa0790..39b0874c 100644 --- a/locale/fr/LC_MESSAGES/django.po +++ b/locale/fr/LC_MESSAGES/django.po @@ -82,7 +82,7 @@ msgstr "peut inviter" #: apps/activity/models.py:44 #: apps/activity/templates/activity/includes/activity_info.html:46 msgid "guest entry fee" -msgstr "cotisation de l'entrée invitée" +msgstr "cotisation de l'entrée invité⋅e" #: apps/activity/models.py:49 msgid "activity type" @@ -119,7 +119,7 @@ msgstr "type" #: apps/wei/models.py:171 apps/wei/templates/wei/attribute_bus_1A.html:13 #: apps/wei/templates/wei/survey.html:15 msgid "user" -msgstr "utilisateur·ice" +msgstr "utilisateur⋅rice" #: apps/activity/models.py:96 #: apps/activity/templates/activity/includes/activity_info.html:36 @@ -366,7 +366,7 @@ msgstr "Toutes les activités" #: apps/activity/templates/activity/includes/activity_info.html:32 msgid "creater" -msgstr "créateur·ice" +msgstr "créateur⋅rice" #: apps/activity/templates/activity/includes/activity_info.html:53 msgid "opened" @@ -588,7 +588,7 @@ msgstr "Pas de rechargement" #: apps/member/forms.py:185 msgid "You can credit the note of the user." -msgstr "Vous pouvez créditer la note de l'utilisateur·ice avant l'adhésion." +msgstr "Vous pouvez créditer la note de l'utilisateur⋅rice avant l'adhésion." #: apps/member/forms.py:186 apps/registration/forms.py:85 #: apps/wei/forms/registration.py:97 @@ -603,7 +603,7 @@ msgstr "Banque" #: apps/member/forms.py:233 msgid "User" -msgstr "Utilisateur·ice" +msgstr "Utilisateur⋅rice" #: apps/member/forms.py:247 msgid "Roles" @@ -732,11 +732,11 @@ msgstr "adresse" #: apps/registration/templates/registration/future_profile_detail.html:43 #: apps/wei/templates/wei/weimembership_form.html:47 msgid "paid" -msgstr "payé·e" +msgstr "payé⋅e" #: apps/member/models.py:90 msgid "Tells if the user receive a salary." -msgstr "Indique si l'utilisateur·ice perçoit un salaire." +msgstr "Indique si l'utilisateur⋅rice perçoit un salaire." #: apps/member/models.py:99 apps/treasury/tables.py:143 msgid "No" @@ -763,7 +763,6 @@ msgid "" "Register on the mailing list to stay informed of the sport events of the " "campus (1 mail/week)" msgstr "" -"S'inscrire sur la liste de diffusion pour rester informé·e des actualités " "sportives sur le campus (1 mail par semaine)" #: apps/member/models.py:113 @@ -921,8 +920,8 @@ msgid "" "The user is not a member of the club·s %(clubs)s. Please create the required " "memberships, otherwise it will fail." msgstr "" -"Cet·te utilisateur·ice n'est pas membre du/des club·s parent·s %(clubs)s. Merci de " -"d'abord créer l'adhésion requise, sinon cette adhésion va échouer." +"Cet⋅te utilisateur⋅rice n'est pas membre du/des club·s parent·s %(clubs)s. " +"Merci de d'abord créer l'adhésion requise, sinon cette adhésion va échouer." #: apps/member/templates/member/add_members.html:29 #, python-format @@ -939,7 +938,7 @@ msgid "" "This club has parents %(clubs)s. Please make sure that the user is a member " "of this or these club·s, otherwise the creation of this membership will fail." msgstr "" -"Ce club a pour parents %(clubs)s. Merci de vous assurer que l'utilisateur·ice " +"Ce club a pour parents %(clubs)s. Merci de vous assurer que l'utilisateur⋅rice " "est membre de ce·s club·s, sinon la création de cette adhésion va échouer." #: apps/member/templates/member/base.html:17 @@ -988,8 +987,8 @@ msgid "" "If you use the force mode, the user won't be able to unlock the note by " "itself." msgstr "" -"Si vous verrouillez la note de force, l'utilisateur·ice ne pourra plus la " -"déverrouiller soi-même." +"Si vous verrouillez la note de force, l'utilisateur⋅rice ne pourra plus la " +"déverrouiller ellui-même." #: apps/member/templates/member/base.html:110 #: apps/member/templates/member/base.html:137 apps/treasury/forms.py:91 @@ -1132,7 +1131,7 @@ msgstr "Attention" #: apps/member/templates/member/manage_auth_tokens.html:44 msgid "Regenerate token" -msgstr "Regénérer le jeton" +msgstr "Régénérer le jeton" #: apps/member/templates/member/manage_auth_tokens.html:53 msgid "OAuth2 authentication" @@ -1170,7 +1169,7 @@ msgstr "Recadrer et envoyer" #: apps/registration/templates/registration/future_profile_detail.html:28 #: apps/wei/templates/wei/weimembership_form.html:26 msgid "This user doesn't have confirmed his/her e-mail address." -msgstr "Cet·te utilisateur·ice n'a pas encore confirmé son adresse e-mail." +msgstr "Cet⋅te utilisateur⋅rice n'a pas encore confirmé son adresse e-mail." #: apps/member/templates/member/profile_detail.html:13 #: apps/registration/templates/registration/future_profile_detail.html:29 @@ -1217,11 +1216,11 @@ msgstr "Cette adresse doit être valide." #: apps/member/views.py:139 msgid "Profile detail" -msgstr "Détails de l'utilisateur·ice" +msgstr "Détails de l'utilisateur⋅rice" #: apps/member/views.py:205 msgid "Search user" -msgstr "Chercher un·e utilisateur·ice" +msgstr "Chercher un·e utilisateur·rice" #: apps/member/views.py:253 msgid "Note friendships" @@ -1260,8 +1259,8 @@ msgid "" "This user don't have enough money to join this club, and can't have a " "negative balance." msgstr "" -"Cet·te utilisateur·ice n'a pas assez d'argent pour rejoindre ce club et ne peut pas " -"avoir un solde négatif." +"Cet⋅te utilisateur⋅rice n'a pas assez d'argent pour rejoindre ce club et ne " +"peut pas avoir un solde négatif." #: apps/member/views.py:725 msgid "The membership must start after {:%m-%d-%Y}." @@ -1273,7 +1272,7 @@ msgstr "L'adhésion doit commencer avant le {:%d/%m/%Y}." #: apps/member/views.py:880 msgid "Manage roles of an user in the club" -msgstr "Gérer les rôles d'un·e utilisateur·ice dans le club" +msgstr "Gérer les rôles d'un⋅e utilisateur⋅rice dans le club" #: apps/member/views.py:905 msgid "Members of the club" @@ -1384,8 +1383,8 @@ msgstr "" #: apps/note/models/notes.py:70 msgid "The note is blocked by the the BDE and can't be manually reactivated." msgstr "" -"La note est bloquée de force par le BDE et ne peut pas être débloquée par le·a " -"possesseur·ice de la note." +"La note est bloquée de force par le BDE et ne peut pas être débloquée par læ " +"propriétaire de la note." #: apps/note/models/notes.py:78 msgid "notes" @@ -1397,11 +1396,11 @@ msgstr "Cet alias est déjà pris." #: apps/note/models/notes.py:152 msgid "one's note" -msgstr "note d'un·e utilisateur·ice" +msgstr "note d'un·e utilisateur·rice" #: apps/note/models/notes.py:153 msgid "users note" -msgstr "notes des utilisateur·ice·s" +msgstr "notes des utilisateur·rice·s" #: apps/note/models/notes.py:159 #, python-format @@ -1438,7 +1437,7 @@ msgid "trusted" msgstr "ami·e" #: apps/note/models/notes.py:243 -msgid "frienship" +msgid "friendship" msgstr "amitié" #: apps/note/models/notes.py:248 @@ -1543,7 +1542,7 @@ msgid "" msgstr "" "Les montants des notes doivent se trouver entre - 92 233 720 368 547 758.08 " "€ et 92 233 720 368 547 758.07 €. Ne cherchez pas à capitaliser l'argent du " -"BDE." +"BDE, il est temps de penser à partager les richesses." #: apps/note/models/transactions.py:274 msgid "recurrent transaction" @@ -1558,7 +1557,7 @@ msgid "" "The destination of this transaction must equal to the destination of the " "template." msgstr "" -"Le·a destinataire de cette transaction doit être identique à celui du bouton " +"Læ destinataire de cette transaction doit être identique à cellui du bouton " "utilisé." #: apps/note/models/transactions.py:290 @@ -1587,7 +1586,7 @@ msgid "" "payment method and a User or a Club" msgstr "" "Une transaction spéciale n'est possible que entre une note associée à un " -"mode de paiement et un·e utilisateur·ice ou un club" +"mode de paiement et un⋅e utilisateur⋅rice ou un club" #: apps/note/models/transactions.py:357 apps/note/models/transactions.py:360 #: apps/note/models/transactions.py:363 apps/wei/views.py:978 @@ -1661,8 +1660,8 @@ msgstr "Consommer" #: apps/note/templates/note/conso_form.html:43 #: apps/note/templates/note/transaction_form.html:69 #: apps/note/templates/note/transaction_form.html:96 -msgid "Name or alias..." -msgstr "Pseudo ou alias ..." +msgid "Name or alias…" +msgstr "Pseudo ou alias…" #: apps/note/templates/note/conso_form.html:53 msgid "Select consumptions" @@ -1711,11 +1710,11 @@ msgstr "Mail généré par la Note Kfet le" #: apps/note/templates/note/transaction_form.html:58 #: apps/note/templates/note/transaction_form.html:178 msgid "Select emitters" -msgstr "Sélection des émetteur·ice·s" +msgstr "Sélection des émetteur·rice·s" #: apps/note/templates/note/transaction_form.html:73 msgid "I am the emitter" -msgstr "Je suis l'émetteur·ice" +msgstr "Je suis l'émetteur⋅rice" #: apps/note/templates/note/transaction_form.html:85 #: apps/note/templates/note/transaction_form.html:180 @@ -1740,11 +1739,11 @@ msgstr "Nom" #: apps/note/templates/note/transaction_form.html:177 msgid "Select emitter" -msgstr "Sélection de l'émetteur·ice" +msgstr "Sélection de l'émetteur⋅rice" #: apps/note/templates/note/transaction_form.html:179 msgid "Select receiver" -msgstr "Sélection du destinataire" +msgstr "Sélection de læ destinataire" #: apps/note/templates/note/transaction_form.html:181 msgid "Transfer type" @@ -1767,24 +1766,24 @@ msgid "Current price" msgstr "Prix actuel" #: apps/note/templates/note/transactiontemplate_list.html:13 -msgid "Name of the button..." -msgstr "Nom du bouton ..." +msgid "Name of the button…" +msgstr "Nom du bouton…" #: apps/note/templates/note/transactiontemplate_list.html:15 msgid "New button" msgstr "Nouveau bouton" #: apps/note/templates/note/transactiontemplate_list.html:22 -msgid "buttons listing " -msgstr "liste des boutons " +msgid "buttons listing" +msgstr "liste des boutons" #: apps/note/templates/note/transactiontemplate_list.html:73 -msgid "button successfully deleted " -msgstr "le bouton a bien été supprimé " +msgid "button successfully deleted" +msgstr "le bouton a bien été supprimé" #: apps/note/templates/note/transactiontemplate_list.html:77 -msgid "Unable to delete button " -msgstr "Impossible de supprimer le bouton " +msgid "Unable to delete button" +msgstr "Impossible de supprimer le bouton" #: apps/note/templates/note/transactiontemplate_list.html:95 msgid "Button hidden" @@ -1878,7 +1877,7 @@ msgid "" "is expired." msgstr "" "Indique si la permission doit être attribuée même si l'adhésion de " -"l'utilisateur·ice est expirée." +"l'utilisateur⋅rice est expirée." #: apps/permission/models.py:182 #: apps/permission/templates/permission/all_rights.html:89 @@ -1936,16 +1935,16 @@ msgstr "" #: apps/permission/templates/permission/all_rights.html:12 msgid "Users that have surnormal rights" -msgstr "Liste des utilisateur·ice·s ayant des droits surnormaux" +msgstr "Liste des utilisateur·rice·s ayant des droits surnormaux" #: apps/permission/templates/permission/all_rights.html:16 msgid "Superusers have all rights on everything, to manage the website." msgstr "" -"Les super-utilisateur·ice·s ont tous les droits sur tout, afin de gérer le site." +"Les super-utilisateur·rice·s ont tous les droits sur tout, afin de gérer le site." #: apps/permission/templates/permission/all_rights.html:21 msgid "Superusers" -msgstr "Super-utilisateur·ice·s" +msgstr "Super-utilisateur·rice·s" #: apps/permission/templates/permission/all_rights.html:45 msgid "Roles description" @@ -2026,7 +2025,7 @@ msgstr "inscription" #: apps/registration/forms.py:40 msgid "This email address is already used." -msgstr "Cet email est déjà pris." +msgstr "Cette adresse email est déjà prise." #: apps/registration/forms.py:60 msgid "Register to the WEI" @@ -2100,7 +2099,7 @@ msgstr "Valider le compte" #: apps/registration/templates/registration/future_profile_detail.html:63 msgid "" "The user declared that he/she opened a bank account in the Société générale." -msgstr "L'utilisateur·ice a déclaré avoir ouvert un compte à la société générale." +msgstr "L'utilisateur·rice a déclaré avoir ouvert un compte à la société générale." #: apps/registration/templates/registration/future_profile_detail.html:73 #: apps/wei/templates/wei/weimembership_form.html:127 @@ -2110,7 +2109,7 @@ msgstr "Valider l'inscription" #: apps/registration/templates/registration/future_user_list.html:9 msgid "New user" -msgstr "Nouvel·le utilisateur·ice" +msgstr "Nouvel⋅le utilisateur⋅rice" #: apps/registration/templates/registration/mails/email_validation_email.html:12 #: apps/registration/templates/registration/mails/email_validation_email.txt:3 @@ -2154,7 +2153,7 @@ msgstr "L'équipe de la Note Kfet." #: apps/registration/views.py:41 msgid "Register new user" -msgstr "Enregistrer un·e nouvel·le utilisateur·ice" +msgstr "Enregistrer un⋅e nouvel⋅le utilisateur⋅rice" #: apps/registration/views.py:99 msgid "Email validation" @@ -2178,11 +2177,11 @@ msgstr "Renvoyer le lien de validation" #: apps/registration/views.py:182 msgid "Pre-registered users list" -msgstr "Liste des utilisateur·ice·s en attente d'inscription" +msgstr "Liste des utilisateur⋅rices en attente d'inscription" #: apps/registration/views.py:206 msgid "Unregistered users" -msgstr "Utilisateur·ice·s en attente d'inscription" +msgstr "Utilisateur·rice·s en attente d'inscription" #: apps/registration/views.py:219 msgid "Registration detail" @@ -2370,14 +2369,14 @@ msgstr "Crédits de la Société générale" #: apps/treasury/models.py:315 #, python-brace-format msgid "Soge credit for {user}" -msgstr "Crédit de la société générale pour l'utilisateur·ice {user}" +msgstr "Crédit de la société générale pour l'utilisateur·rice {user}" #: apps/treasury/models.py:445 msgid "" "This user doesn't have enough money to pay the memberships with its note. " "Please ask her/him to credit the note before invalidating this credit." msgstr "" -"Cet·te utilisateur·ice n'a pas assez d'argent pour payer les adhésions avec sa " +"Cet·te utilisateur·rice n'a pas assez d'argent pour payer les adhésions avec sa " "note. Merci de lui demander de recharger sa note avant d'invalider ce crédit." #: apps/treasury/tables.py:20 @@ -2430,7 +2429,7 @@ msgid "" "implies regenerate it. Be careful if you manipulate old invoices." msgstr "" "Attention : le template LaTeX est enregistré avec cet objet. Modifier la " -"facture implique la regénérer. Faites attention si vous manipulez de " +"facture implique la régénérer. Faites attention si vous manipulez de " "vieilles factures." #: apps/treasury/templates/treasury/invoice_form.html:69 @@ -2529,7 +2528,7 @@ msgid "" "If this credit is validated, then the user won't be able to ask for a credit " "from the Société générale." msgstr "" -"Si ce crédit est validé, alors l'utilisateur·ice ne pourra plus demander d'être " +"Si ce crédit est validé, alors l'utilisateur·rice ne pourra plus demander d'être " "crédité·e par la Société générale à l'avenir." #: apps/treasury/templates/treasury/sogecredit_detail.html:44 @@ -2545,13 +2544,13 @@ msgid "" "Warning: if you don't validate this credit, the note of the user doesn't " "have enough money to pay its memberships." msgstr "" -"Attention : si vous ne validez pas ce crédit, la note de l'utilisateur·ice n'a " +"Attention : si vous ne validez pas ce crédit, la note de l'utilisateur·rice n'a " "pas assez d'argent pour payer les adhésions." #: apps/treasury/templates/treasury/sogecredit_detail.html:56 msgid "Please ask the user to credit its note before deleting this credit." msgstr "" -"Merci de demander à l'utilisateur·ice de recharger sa note avant de supprimer la " +"Merci de demander à l'utilisateur·rice de recharger sa note avant de supprimer la " "demande de crédit." #: apps/treasury/templates/treasury/sogecredit_detail.html:63 @@ -2570,7 +2569,7 @@ msgstr "Filtrer avec uniquement les crédits non valides" #: apps/treasury/templates/treasury/sogecredit_list.html:50 msgid "There is no matched user that have asked for a Société générale credit." msgstr "" -"Il n'y a pas d'utilisateur·ice trouvé·e ayant demandé un crédit de la Société " +"Il n'y a pas d'utilisateur·rice trouvé·e ayant demandé un crédit de la Société " "générale." #: apps/treasury/templates/treasury/sogecredit_list.html:63 @@ -2631,7 +2630,7 @@ msgstr "WEI" #: apps/wei/forms/registration.py:35 msgid "The selected user is not validated. Please validate its account first" msgstr "" -"L'utilisateur·ice sélectionné·e n'est pas validé·e. Merci de d'abord valider son " +"L'utilisateur·rice sélectionné·e n'est pas validé·e. Merci de d'abord valider son " "compte" #: apps/wei/forms/registration.py:59 apps/wei/models.py:126 @@ -2644,7 +2643,7 @@ msgid "" "This choice is not definitive. The WEI organizers are free to attribute for " "you a bus and a team, in particular if you are a free eletron." msgstr "" -"Ce choix n'est pas définitif. Les organisateur·ice·s du WEI sont libres de vous " +"Ce choix n'est pas définitif. Les organisateur·rice·s du WEI sont libres de vous " "attribuer un bus et une équipe, en particulier si vous êtes un·e électron " "libre." @@ -2797,7 +2796,7 @@ msgstr "première année" #: apps/wei/models.py:249 msgid "Tells if the user is new in the school." -msgstr "Indique si l'utilisateur·ice est nouveau dans l'école." +msgstr "Indique si l'utilisateur⋅rice est nouvelleeau dans l'école." #: apps/wei/models.py:254 msgid "registration information" @@ -2837,19 +2836,19 @@ msgstr "Adhésions au WEI" #: apps/wei/tables.py:105 msgid "The user does not have enough money." -msgstr "L'utilisateur·ice n'a pas assez d'argent." +msgstr "L'utilisateur⋅rice n'a pas assez d'argent." #: apps/wei/tables.py:108 msgid "" "The user is in first year. You may validate the credit, the algorithm will " "run later." msgstr "" -"L'utilisateur·ice est en première année, vous pouvez valider le crédit, " +"L'utilisateur·rice est en première année, vous pouvez valider le crédit, " "l'algorithme tournera plus tard." #: apps/wei/tables.py:111 msgid "The user has enough money, you can validate the registration." -msgstr "L'utilisateur·ice a assez d'argent, l'inscription est possible." +msgstr "L'utilisateur⋅rice a assez d'argent, l'inscription est possible." #: apps/wei/tables.py:143 msgid "Year" @@ -2922,7 +2921,7 @@ msgstr "L'adhésion au BDE est offerte avec l'inscription au WEI." #: apps/wei/templates/wei/base.html:51 msgid "WEI fee (unpaid students)" -msgstr "Prix du WEI (étudiants)" +msgstr "Prix du WEI (étudiant⋅es)" #: apps/wei/templates/wei/base.html:76 msgid "WEI list" @@ -2930,11 +2929,11 @@ msgstr "Liste des WEI" #: apps/wei/templates/wei/base.html:81 apps/wei/views.py:528 msgid "Register 1A" -msgstr "Inscrire un 1A" +msgstr "Inscrire un⋅e 1A" #: apps/wei/templates/wei/base.html:85 apps/wei/views.py:614 msgid "Register 2A+" -msgstr "Inscrire un 2A+" +msgstr "Inscrire un⋅e 2A+" #: apps/wei/templates/wei/base.html:93 msgid "Add bus" @@ -3062,7 +3061,7 @@ msgstr "L'inscription a déjà été validée et ne peut pas être dévalidée." #: apps/wei/templates/wei/weimembership_form.html:132 msgid "The user joined the bus" -msgstr "L'utilisateur·ice a rejoint le bus" +msgstr "L'utilisateur⋅rice a rejoint le bus" #: apps/wei/templates/wei/weimembership_form.html:133 msgid "in the team" @@ -3107,7 +3106,7 @@ msgstr "" #: apps/wei/templates/wei/weimembership_form.html:166 msgid "The user didn't give her/his caution check." -msgstr "L'utilisateur·ice n'a pas donné son chèque de caution." +msgstr "L'utilisateur⋅rice n'a pas donné son chèque de caution." #: apps/wei/templates/wei/weimembership_form.html:174 msgid "" @@ -3115,13 +3114,13 @@ msgid "" "membership will be processed automatically, the WEI registration includes " "the membership fee." msgstr "" -"Cet·te utilisateur·ice n'est pas membre du club Kfet pour l'année à venir. " +"Cet⋅te utilisateur⋅rice n'est pas membre du club Kfet pour l'année à venir. " "L'adhésion va être faite automatiquement, l'inscription au WEI inclut le " "coût d'adhésion." #: apps/wei/templates/wei/weimembership_list.html:27 -msgid "View unvalidated registrations..." -msgstr "Voir les inscriptions non validées ..." +msgid "View unvalidated registrations…" +msgstr "Voir les inscriptions non validées…" #: apps/wei/templates/wei/weiregistration_confirm_delete.html:16 msgid "This registration is already validated and can't be deleted." @@ -3141,8 +3140,8 @@ msgid "There is no pre-registration found with this pattern." msgstr "Il n'y a pas de pré-inscription en attente avec cette entrée." #: apps/wei/templates/wei/weiregistration_list.html:27 -msgid "View validated memberships..." -msgstr "Voir les adhésions validées ..." +msgid "View validated memberships…" +msgstr "Voir les adhésions validées…" #: apps/wei/views.py:58 msgid "Search WEI" @@ -3198,7 +3197,7 @@ msgstr "Gérer l'équipe WEI" #: apps/wei/views.py:492 msgid "Register first year student to the WEI" -msgstr "Inscrire un 1A au WEI" +msgstr "Inscrire un⋅e 1A au WEI" #: apps/wei/views.py:550 apps/wei/views.py:649 msgid "This user is already registered to this WEI." @@ -3209,12 +3208,12 @@ msgid "" "This user can't be in her/his first year since he/she has already " "participated to a WEI." msgstr "" -"Cet·te utilisateur·ice ne peut pas être en première année puisqu'iel a déjà " +"Cet⋅te utilisateur⋅rice ne peut pas être en première année puisqu'iel a déjà " "participé à un WEI." #: apps/wei/views.py:578 msgid "Register old student to the WEI" -msgstr "Inscrire un 2A+ au WEI" +msgstr "Inscrire un⋅e 2A+ au WEI" #: apps/wei/views.py:633 apps/wei/views.py:721 msgid "You already opened an account in the Société générale." @@ -3311,7 +3310,7 @@ msgstr "" "Désolé, une erreur est survenue lors de l'analyse de votre requête. Un email " "a été envoyé aux responsables de la plateforme avec les détails de cette " "erreur, qui sera corrigée rapidement. Vous pouvez désormais aller boire une " -"bière." +"bière, avec modération." #: note_kfet/templates/autocomplete_model.html:15 msgid "Reset" @@ -3323,7 +3322,7 @@ msgstr "La note du BDE de l'ENS Paris-Saclay." #: note_kfet/templates/base.html:78 msgid "Users" -msgstr "Utilisateur·ice·s" +msgstr "Utilisateur·rice·s" #: note_kfet/templates/base.html:84 msgid "Clubs" @@ -3404,7 +3403,7 @@ msgstr "Charte Info (FR)" #: note_kfet/templates/base_search.html:15 msgid "Search by attribute such as name…" -msgstr "Chercher par un attribut tel que le nom …" +msgstr "Chercher par un attribut tel que le nom…" #: note_kfet/templates/base_search.html:23 msgid "There is no results." @@ -3624,7 +3623,7 @@ msgid "" "Kfet and pay the registration fee. You must also validate your email address " "by following the link you received." msgstr "" -"Si vous vous êtes déjà inscrit·e·s, votre inscription a bien été prise en " +"Si vous vous êtes déjà inscrit·e, votre inscription a bien été prise en " "compte. Le BDE doit d'abord valider votre compte avant que vous puissiez " "vous connecter. Vous devez vous rendre à la Kfet et payer les frais " "d'adhésion. Vous devez également valider votre adresse email en suivant le " From 734f5b242db27f9e77234391caa8b4ae191765de Mon Sep 17 00:00:00 2001 From: Emmy D'ANELLO Date: Mon, 29 Aug 2022 13:22:01 +0200 Subject: [PATCH 19/33] C'est pas moi Signed-off-by: Emmy D'ANELLO --- docs/_static/img/create_transaction.png | Bin 146074 -> 153146 bytes docs/faq.rst | 2 +- locale/de/LC_MESSAGES/djangojs.po | 6 +++--- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/_static/img/create_transaction.png b/docs/_static/img/create_transaction.png index 4805b1319fec15e888d388c0c87e12cf567ae2f8..05ce4b42a30de85e22e60b477091d34381c6bf2c 100644 GIT binary patch literal 153146 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

  • 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 diff --git a/docs/faq.rst b/docs/faq.rst index d8dbb1f7..2d80f24a 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -181,7 +181,7 @@ Contributeur⋅rices Liste des contributeurs majeurs, par ordre alphabétique : * Pierre-André « PAC » COMBY - * Yohann « ÿnérant » D'ANELLO + * Emmy « ÿnérant » D'ANELLO * Benjamin « esum » GRAILLOT * Alexandre « erdnaxe » IOOSS * Nicolas « nicomarg » MARGULIES diff --git a/locale/de/LC_MESSAGES/djangojs.po b/locale/de/LC_MESSAGES/djangojs.po index 35648a6e..f8e4ea95 100644 --- a/locale/de/LC_MESSAGES/djangojs.po +++ b/locale/de/LC_MESSAGES/djangojs.po @@ -9,9 +9,9 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-10-07 09:07+0200\n" "PO-Revision-Date: 2020-11-16 20:21+0000\n" -"Last-Translator: Yohann D'ANELLO \n" -"Language-Team: German \n" +"Last-Translator: Emmy D'ANELLO \n" +"Language-Team: German " +"\n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" From d595d908c65dc032783087884c13a6b3769f3564 Mon Sep 17 00:00:00 2001 From: Emmy D'ANELLO Date: Mon, 29 Aug 2022 14:52:34 +0200 Subject: [PATCH 20/33] Fix tests Signed-off-by: Emmy D'ANELLO --- apps/member/tests/test_memberships.py | 2 +- docs/apps/treasury.rst | 2 +- docs/faq.rst | 2 +- docs/scripts.rst | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/member/tests/test_memberships.py b/apps/member/tests/test_memberships.py index de9f3d3d..1a59c253 100644 --- a/apps/member/tests/test_memberships.py +++ b/apps/member/tests/test_memberships.py @@ -291,7 +291,7 @@ class TestMemberships(TestCase): response = self.client.post(reverse("member:club_manage_roles", args=(self.membership.pk,)), data=dict( roles=[role.id for role in Role.objects.filter( - Q(name="Membre de club") | Q(name="Trésorier·ère de club") | Q(name="Bureau de club")).all()], + Q(name="Membre de club") | Q(name="Trésorièr⋅e de club") | Q(name="Bureau de club")).all()], )) self.assertRedirects(response, self.user.profile.get_absolute_url(), 302, 200) self.membership.refresh_from_db() diff --git a/docs/apps/treasury.rst b/docs/apps/treasury.rst index 8d269404..6da6a73a 100644 --- a/docs/apps/treasury.rst +++ b/docs/apps/treasury.rst @@ -155,7 +155,7 @@ Relations ~~~~~~~~~ * Toute transaction qui n'est pas attachée à une remise d'un bon type peut être attachée à une remise. Cela se passe - par le biais d'un formulaire, où le trésorier peut vérifier et corriger au besoin nom, prénom, banque émettrice et montant. + par le biais d'un formulaire, où læ trésorièr⋅e peut vérifier et corriger au besoin nom, prénom, banque émettrice et montant. * Toute transaction attachée à une remise encore ouverte peut être retirée. * Pour clore une remise, il faut au moins 1 transaction associée. diff --git a/docs/faq.rst b/docs/faq.rst index 2d80f24a..591052ae 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -5,7 +5,7 @@ Des transactions anormales sont apparues sur mon compte. -------------------------------------------------------- .. note:: - Tu dois immédiatement contacter les trésoriers du BDE (voir ci-dessous) pour + Tu dois immédiatement contacter les trésorièr⋅es du BDE (voir ci-dessous) pour signaler l'incident. Précise bien ton nom de note, l'heure de la transaction ainsi que l'alias utilisé pour faire la transaction (en plaçant ta souris sur ton pseudo sur la ligne de transaction, l'alias utilisé apparaît). La raison diff --git a/docs/scripts.rst b/docs/scripts.rst index b128b863..d114ca47 100644 --- a/docs/scripts.rst +++ b/docs/scripts.rst @@ -265,12 +265,12 @@ Envoi des rappels de négatif Le script s'appelle ``send_mail_to_negative_balances``. Il sert à rappeler aux adhérent⋅es et clubs en négatif qui le sont, mais également -à envoyer aux trésorierèr⋅es et respos info la liste des adhérent⋅es en négatif. +à envoyer aux trésorièr⋅es et respos info la liste des adhérent⋅es en négatif. Il prend les options suivantes : * ``--spam, -s`` : envoie à chaque adhérent⋅e en négatif un rappel par mail pour recharger -* ``--report, -r`` : envoie le rapport aux trésorierèr⋅es et respos info +* ``--report, -r`` : envoie le rapport aux trésorièr⋅es et respos info * ``--negative-amount,-n`` : définit le solde maximal en-dessous duquel les notes apparaitront sur le rapport / seront spammées * ``--add-years, -y`` : ajoute également les adhérent⋅es des ``n`` dernières années From 9d1024024b946a6bdf4bfcc93d2697c51aa61fe2 Mon Sep 17 00:00:00 2001 From: korenstin Date: Tue, 30 Jul 2024 21:42:45 +0200 Subject: [PATCH 21/33] Each table can be sorted (with a few exceptions) --- .../templates/activity/activity_form.html | 6 +- apps/activity/views.py | 52 ++++++----- apps/member/views.py | 61 +++++++++---- apps/permission/views.py | 40 ++++++--- apps/treasury/views.py | 89 +++++++++---------- apps/wei/views.py | 45 +++++----- 6 files changed, 164 insertions(+), 129 deletions(-) diff --git a/apps/activity/templates/activity/activity_form.html b/apps/activity/templates/activity/activity_form.html index 8032faae..20a6cbd9 100644 --- a/apps/activity/templates/activity/activity_form.html +++ b/apps/activity/templates/activity/activity_form.html @@ -23,19 +23,19 @@ SPDX-License-Identifier: GPL-3.0-or-later +