Better management of roles in ClubMemberForm

This commit is contained in:
imperosol
2025-09-13 18:37:53 +02:00
parent 63125edeaa
commit c76ff92c30
5 changed files with 64 additions and 27 deletions

View File

@@ -26,6 +26,7 @@ from django import forms
from django.conf import settings from django.conf import settings
from django.db.models import Exists, OuterRef, Q from django.db.models import Exists, OuterRef, Q
from django.db.models.functions import Lower from django.db.models.functions import Lower
from django.utils.functional import cached_property
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from club.models import Club, Mailing, MailingSubscription, Membership from club.models import Club, Mailing, MailingSubscription, Membership
@@ -217,20 +218,36 @@ class ClubMemberForm(forms.ModelForm):
fields = ["user", "role", "description"] fields = ["user", "role", "description"]
widgets = {"user": AutoCompleteSelectUser} widgets = {"user": AutoCompleteSelectUser}
def __init__( def __init__(self, *args, club: Club, request_user: User, **kwargs):
self,
*args,
club: Club,
request_user: User,
**kwargs,
):
self.club = club self.club = club
self.request_user = request_user self.request_user = request_user
self.request_user_membership = self.club.get_membership_for(self.request_user) self.request_user_membership = self.club.get_membership_for(self.request_user)
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.fields["role"].required = True self.fields["role"].required = True
self.fields["role"].choices = [
(value, name)
for value, name in settings.SITH_CLUB_ROLES.items()
if value <= self.max_available_role
]
self.instance.club = club self.instance.club = club
@cached_property
def max_available_role(self):
"""The greatest role that will be obtainable with this form.
Admins and the club president can attribute any role.
Board members can attribute roles lower than their own.
Other users can attribute curious and member roles.
"""
if self.request_user.has_perm("club.add_subscription"):
return settings.SITH_CLUB_ROLES_ID["President"]
membership = self.request_user_membership
if membership is not None and membership.role > settings.SITH_MAXIMUM_FREE_ROLE:
if membership.role == settings.SITH_CLUB_ROLES_ID["President"]:
return membership.role
return membership.role - 1
return settings.SITH_MAXIMUM_FREE_ROLE
def clean_user(self): def clean_user(self):
"""Check that the user is not trying to add a user already in the club. """Check that the user is not trying to add a user already in the club.
@@ -248,16 +265,21 @@ class ClubMemberForm(forms.ModelForm):
return user return user
def clean(self): def clean(self):
"""Check user rights for adding an user.""" """Check user rights for adding a user."""
cleaned_data = super().clean() cleaned_data = super().clean()
if "role" not in cleaned_data: if "role" not in cleaned_data:
return cleaned_data return cleaned_data
request_user = self.request_user if (
membership = self.request_user_membership self.request_user_membership is None
if not ( or self.request_user_membership.role <= settings.SITH_MAXIMUM_FREE_ROLE
cleaned_data["role"] <= settings.SITH_MAXIMUM_FREE_ROLE ) and not self.request_user.has_perm("club.add_membership"):
or (membership is not None and membership.role >= cleaned_data["role"]) raise forms.ValidationError(
or request_user.has_perm("club.add_subscription") _(
): "You cannot add other users to a club "
"if you are not in the club board."
),
code="invalid",
)
if cleaned_data["role"] > self.max_available_role:
raise forms.ValidationError(_("You do not have the permission to do that")) raise forms.ValidationError(_("You do not have the permission to do that"))
return cleaned_data return cleaned_data

View File

@@ -12,11 +12,13 @@
{% block content %} {% block content %}
<h2>{% trans %}Club members{% endtrans %}</h2> <h2>{% trans %}Club members{% endtrans %}</h2>
<br />
<h4>{% trans %}Add a new member{% endtrans %}</h4>
{{ add_member_fragment }} {% if add_member_fragment %}
<br /> <br />
<h4>{% trans %}Add a new member{% endtrans %}</h4>
{{ add_member_fragment }}
<br />
{% endif %}
{% if members %} {% if members %}
<form action="{{ url('club:club_members', club_id=club.id) }}" id="members_old" method="post"> <form action="{{ url('club:club_members', club_id=club.id) }}" id="members_old" method="post">
{% csrf_token %} {% csrf_token %}

View File

@@ -353,7 +353,7 @@ class TestMembership(TestClub):
assert not form.is_valid() assert not form.is_valid()
assert form.errors == { assert form.errors == {
"__all__": ["Vous n'avez pas la permission de faire cela"] "role": ["Sélectionnez un choix valide. 10 n\u2019en fait pas partie."]
} }
self.club.refresh_from_db() self.club.refresh_from_db()
assert nb_memberships == self.club.members.count() assert nb_memberships == self.club.members.count()

View File

@@ -69,7 +69,7 @@ from com.views import (
from core.auth.mixins import CanCreateMixin, CanEditMixin from core.auth.mixins import CanCreateMixin, CanEditMixin
from core.models import PageRev from core.models import PageRev
from core.views import DetailFormView, PageEditViewBase, UseFragmentsMixin from core.views import DetailFormView, PageEditViewBase, UseFragmentsMixin
from core.views.mixins import FragmentMixin, TabedViewMixin from core.views.mixins import FragmentMixin, FragmentRenderer, TabedViewMixin
from counter.models import Selling from counter.models import Selling
@@ -301,9 +301,14 @@ class ClubMembersView(
form_class = ClubOldMemberForm form_class = ClubOldMemberForm
template_name = "club/club_members.jinja" template_name = "club/club_members.jinja"
current_tab = "members" current_tab = "members"
fragments = {"add_member_fragment": ClubAddMembersFragment}
permission_required = "club.view_club" permission_required = "club.view_club"
def get_fragments(self) -> dict[str, type[FragmentMixin] | FragmentRenderer]:
membership = self.object.get_membership_for(self.request.user)
if membership and membership.role <= settings.SITH_MAXIMUM_FREE_ROLE:
return {}
return {"add_member_fragment": ClubAddMembersFragment}
def get_fragment_data(self) -> dict[str, Any]: def get_fragment_data(self) -> dict[str, Any]:
return {"add_member_fragment": {"club": self.object}} return {"add_member_fragment": {"club": self.object}}

View File

@@ -6,7 +6,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-09-13 15:18+0200\n" "POT-Creation-Date: 2025-09-13 18:32+0200\n"
"PO-Revision-Date: 2016-07-18\n" "PO-Revision-Date: 2016-07-18\n"
"Last-Translator: Maréchal <thomas.girod@utbm.fr\n" "Last-Translator: Maréchal <thomas.girod@utbm.fr\n"
"Language-Team: AE info <ae.info@utbm.fr>\n" "Language-Team: AE info <ae.info@utbm.fr>\n"
@@ -173,6 +173,13 @@ msgstr "L'utilisateur doit être cotisant pour faire partie d'un club"
msgid "You can not add the same user twice" msgid "You can not add the same user twice"
msgstr "Vous ne pouvez pas ajouter deux fois le même utilisateur" msgstr "Vous ne pouvez pas ajouter deux fois le même utilisateur"
#: club/forms.py
msgid ""
"You cannot add other users to a club if you are not in the club board."
msgstr ""
"Vous ne pouvez pas ajouter d'autres utilisateurs dans un club si vous "
"ne faites pas partie de son bureau."
#: club/forms.py sas/forms.py #: club/forms.py sas/forms.py
msgid "You do not have the permission to do that" msgid "You do not have the permission to do that"
msgstr "Vous n'avez pas la permission de faire cela" msgstr "Vous n'avez pas la permission de faire cela"
@@ -326,10 +333,6 @@ msgstr "Membres du club"
msgid "Add a new member" msgid "Add a new member"
msgstr "Ajouter un nouveau membre" msgstr "Ajouter un nouveau membre"
#: club/templates/club/club_members.jinja
msgid "Current club members"
msgstr "Membres actuels du club"
#: club/templates/club/club_members.jinja #: club/templates/club/club_members.jinja
#: club/templates/club/club_old_members.jinja #: club/templates/club/club_old_members.jinja
#: core/templates/core/user_clubs.jinja #: core/templates/core/user_clubs.jinja
@@ -684,6 +687,11 @@ msgstr "Listes de diffusion"
msgid "Posters list" msgid "Posters list"
msgstr "Liste d'affiches" msgstr "Liste d'affiches"
#: club/views.py
#, python-format
msgid "%(user)s has been added to club."
msgstr "%(user)s a été ajouté au club."
#: com/forms.py #: com/forms.py
msgid "Format: 16:9 | Resolution: 1920x1080" msgid "Format: 16:9 | Resolution: 1920x1080"
msgstr "Format : 16:9 | Résolution : 1920x1080" msgstr "Format : 16:9 | Résolution : 1920x1080"