1
0
mirror of https://gitlab.crans.org/bde/nk20 synced 2025-08-13 17:39:36 +02:00

Permmissions

This commit is contained in:
Ehouarn
2025-08-13 15:21:27 +02:00
parent 85b857976a
commit f13a44702a
7 changed files with 417 additions and 26 deletions

View File

@@ -16,9 +16,11 @@ SPDX-License-Identifier: GPL-3.0-or-later
<a href="#" class="btn btn-sm btn-outline-primary active"> <a href="#" class="btn btn-sm btn-outline-primary active">
{% trans "Challenges" %} {% trans "Challenges" %}
</a> </a>
{% if can_manage %}
<a href="{% url "family:manage" %}" class="btn btn-sm btn-outline-primary"> <a href="{% url "family:manage" %}" class="btn btn-sm btn-outline-primary">
{% trans "Manage" %} {% trans "Manage" %}
</a> </a>
{% endif %}
</div> </div>
</div> </div>
</div> </div>

View File

@@ -7,6 +7,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% load i18n perms %} {% load i18n perms %}
{% block profile_content %} {% block profile_content %}
{% if member_list.data %}
<div class="card"> <div class="card">
<div class="card-header position-relative" id="clubListHeading"> <div class="card-header position-relative" id="clubListHeading">
<i class="fa fa-users"></i> {% trans "Family members" %} <i class="fa fa-users"></i> {% trans "Family members" %}
@@ -15,11 +16,14 @@ SPDX-License-Identifier: GPL-3.0-or-later
</div> </div>
<div class="my-4"></div> <div class="my-4"></div>
{% endif %}
{% if achievement_list.data %}
<div class="card"> <div class="card">
<div class="card-header position-relative"> <div class="card-header position-relative">
<i class="fa fa-trophy"></i> {% trans "Completed challenges" %} <i class="fa fa-trophy"></i> {% trans "Completed challenges" %}
</div> </div>
{% render_table achievement_list %} {% render_table achievement_list %}
</div> </div>
{% endif %}
{% endblock %} {% endblock %}

View File

@@ -16,9 +16,11 @@ SPDX-License-Identifier: GPL-3.0-or-later
<a href="{% url "family:challenge_list" %}" class="btn btn-sm btn-outline-primary"> <a href="{% url "family:challenge_list" %}" class="btn btn-sm btn-outline-primary">
{% trans "Challenges" %} {% trans "Challenges" %}
</a> </a>
{% if can_manage %}
<a href="{% url "family:manage" %}" class="btn btn-sm btn-outline-primary"> <a href="{% url "family:manage" %}" class="btn btn-sm btn-outline-primary">
{% trans "Manage" %} {% trans "Manage" %}
</a> </a>
{% endif %}
</div> </div>
</div> </div>
</div> </div>

View File

@@ -26,6 +26,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
<div class="row mb-3"> <div class="row mb-3">
<div class='col-sm-5 col-xl-6' id="infos_div"> <div class='col-sm-5 col-xl-6' id="infos_div">
{% if can_add_achievement %}
<div class="row justify-content-center justify-content-md-end"> <div class="row justify-content-center justify-content-md-end">
{# Family details column #} {# Family details column #}
<div class="col picture-col"> <div class="col picture-col">
@@ -81,8 +82,10 @@ SPDX-License-Identifier: GPL-3.0-or-later
</div> </div>
</div> </div>
</div> </div>
{% endif %}
{# Create family/challenge buttons #} {# Create family/challenge buttons #}
{% if can_add_family or can_add_challenge %}
<div class="card bg-light border-success mb-4"> <div class="card bg-light border-success mb-4">
<h3 class="card-header font-weight-bold text-center"> <h3 class="card-header font-weight-bold text-center">
{% trans "Create a family or challenge" %} {% trans "Create a family or challenge" %}
@@ -100,10 +103,12 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% endif %} {% endif %}
</div> </div>
</div> </div>
{% endif %}
</div> </div>
{# Buttons column #} {# Buttons column #}
<div class="col"> <div class="col">
{% if can_add_achievement %}
<div class="card bg-light border-primary text-center mb-4"> <div class="card bg-light border-primary text-center mb-4">
{# Tabs for list and search #} {# Tabs for list and search #}
<div class="card-header"> <div class="card-header">
@@ -149,10 +154,12 @@ SPDX-License-Identifier: GPL-3.0-or-later
</div> </div>
</div> </div>
{% endif %}
</div> </div>
</div> </div>
{# achievement history #} {# achievement history #}
{% if table.data %}
<div class="card"> <div class="card">
<div class="card-header position-relative" id="historyListHeading"> <div class="card-header position-relative" id="historyListHeading">
<a class="stretched-link font-weight-bold" <a class="stretched-link font-weight-bold"
@@ -191,7 +198,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
</div> </div>
</div> </div>
</div> </div>
{% endif %}
{% endblock %} {% endblock %}

View File

@@ -6,6 +6,7 @@ from datetime import date
from django.conf import settings from django.conf import settings
from django.shortcuts import redirect from django.shortcuts import redirect
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.exceptions import PermissionDenied
from django.db import transaction from django.db import transaction
from django.views.generic import DetailView, UpdateView, ListView from django.views.generic import DetailView, UpdateView, ListView
from django.views.generic.edit import DeleteView, FormMixin from django.views.generic.edit import DeleteView, FormMixin
@@ -51,6 +52,24 @@ class FamilyListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
table_class = FamilyTable table_class = FamilyTable
extra_context = {"title": _('Families list')} extra_context = {"title": _('Families list')}
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
fake_family = Family(name="", description="")
fake_challenge = Challenge(name="", description="", points=0)
can_add_family = PermissionBackend.check_perm(self.request, "family.add_family", fake_family)
can_add_challenge = PermissionBackend.check_perm(self.request, "family.add_challenge", fake_challenge)
if Family.objects.exists() and Challenge.objects.exists():
fake_achievement = Achievement(family=Family.objects.first(), challenge=Challenge.objects.first(), valid=False)
can_add_achievement = PermissionBackend.check_perm(self.request, "family.add_achievement", fake_achievement)
else:
can_add_achievement = False
context["can_manage"] = can_add_family or can_add_challenge or can_add_achievement
return context
class FamilyDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView): class FamilyDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
""" """
@@ -231,6 +250,24 @@ class ChallengeListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableVie
table_class = ChallengeTable table_class = ChallengeTable
extra_context = {"title": _('Challenges list')} extra_context = {"title": _('Challenges list')}
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
fake_family = Family(name="", description="")
fake_challenge = Challenge(name="", description="", points=0)
can_add_family = PermissionBackend.check_perm(self.request, "family.add_family", fake_family)
can_add_challenge = PermissionBackend.check_perm(self.request, "family.add_challenge", fake_challenge)
if Family.objects.exists() and Challenge.objects.exists():
fake_achievement = Achievement(family=Family.objects.first(), challenge=Challenge.objects.first(), valid=False)
can_add_achievement = PermissionBackend.check_perm(self.request, "family.add_achievement", fake_achievement)
else:
can_add_achievement = False
context["can_manage"] = can_add_family or can_add_challenge or can_add_achievement
return context
class ChallengeDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView): class ChallengeDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
""" """
@@ -283,6 +320,11 @@ class FamilyManageView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView
if not request.user.is_authenticated: if not request.user.is_authenticated:
return self.handle_no_permission() return self.handle_no_permission()
perm = PermissionBackend.has_model_perm(self.request, Achievement(), "add")
perm = perm or PermissionBackend.has_model_perm(self.request, Challenge(), "add")
perm = perm or PermissionBackend.has_model_perm(self.request, Family(), "add")
if not perm:
raise PermissionDenied(_("You are not able to manage families and challenges."))
return super().dispatch(request, *args, **kwargs) return super().dispatch(request, *args, **kwargs)
def get_queryset(self, **kwargs): def get_queryset(self, **kwargs):
@@ -298,8 +340,9 @@ class FamilyManageView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView
PermissionBackend.filter_queryset(self.request, Challenge, "view") PermissionBackend.filter_queryset(self.request, Challenge, "view")
).order_by('name') ).order_by('name')
context["can_add_family"] = PermissionBackend.check_perm(self.request, "family.family_create") context["can_add_family"] = PermissionBackend.has_model_perm(self.request, Family(), "add")
context["can_add_challenge"] = PermissionBackend.check_perm(self.request, "family.challenge_create") context["can_add_challenge"] = PermissionBackend.has_model_perm(self.request, Challenge(), "add")
context["can_add_achievement"] = PermissionBackend.has_model_perm(self.request, Achievement(), "add")
# Get the user's family if they have one # Get the user's family if they have one
try: try:
@@ -316,6 +359,13 @@ class FamilyManageView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView
table.orderable = False table.orderable = False
return table return table
def get_table_data(self, **kwargs):
qs = super().get_queryset(**kwargs)
qs = qs.filter(PermissionBackend.filter_queryset(self.request, Achievement, "view"))
return qs
class AchievementListView(ProtectQuerysetMixin, LoginRequiredMixin, MultiTableMixin, ListView): class AchievementListView(ProtectQuerysetMixin, LoginRequiredMixin, MultiTableMixin, ListView):
""" """
@@ -325,6 +375,14 @@ class AchievementListView(ProtectQuerysetMixin, LoginRequiredMixin, MultiTableMi
tables = [AchievementTable, AchievementTable, ] tables = [AchievementTable, AchievementTable, ]
extra_context = {'title': _('Achievement list')} extra_context = {'title': _('Achievement list')}
def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated:
return self.handle_no_permission()
if not PermissionBackend.has_model_perm(self.request, Achievement(), "change"):
raise PermissionDenied(_("You are not able to see the achievement validation interface."))
return super().dispatch(request, *args, **kwargs)
def get_tables(self, **kwargs): def get_tables(self, **kwargs):
tables = super().get_tables(**kwargs) tables = super().get_tables(**kwargs)
@@ -355,6 +413,19 @@ class AchievementValidateView(ProtectQuerysetMixin, LoginRequiredMixin, Template
""" """
template_name = 'family/achievement_confirm_validate.html' template_name = 'family/achievement_confirm_validate.html'
def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated:
return self.handle_no_permission()
fake_achievement = Achievement(
family=Family.objects.first(),
challenge=Challenge.objects.first(),
valid=False,
)
if not PermissionBackend.check_perm(self.request, "family.change_achievement_valid", fake_achievement):
raise PermissionDenied()
return super().dispatch(request, *args, **kwargs)
def post(self, request, pk): def post(self, request, pk):
achievement = Achievement.objects.get(pk=pk) achievement = Achievement.objects.get(pk=pk)
@@ -370,5 +441,18 @@ class AchievementDeleteView(ProtectQuerysetMixin, LoginRequiredMixin, DeleteView
""" """
model = Achievement model = Achievement
def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated:
return self.handle_no_permission()
fake_achievement = Achievement(
family=Family.objects.first(),
challenge=Challenge.objects.first(),
valid=False,
)
if not PermissionBackend.check_perm(self.request, "family.change_achievement_valid", fake_achievement):
raise PermissionDenied()
return super().dispatch(request, *args, **kwargs)
def get_success_url(self): def get_success_url(self):
return reverse_lazy('family:achievement_list') return reverse_lazy('family:achievement_list')

View File

@@ -17,7 +17,6 @@ def save_user_profile(instance, created, raw, **_kwargs):
def update_wei_registration_fee_on_membership_creation(sender, instance, created, **kwargs): def update_wei_registration_fee_on_membership_creation(sender, instance, created, **kwargs):
if not hasattr(instance, "_no_signal") and created: if not hasattr(instance, "_no_signal") and created:
print('update_wei_registration_fee_on_membership_creation')
from wei.models import WEIRegistration from wei.models import WEIRegistration
if instance.club.id == 1 or instance.club.id == 2: if instance.club.id == 1 or instance.club.id == 2:
registrations = WEIRegistration.objects.filter( registrations = WEIRegistration.objects.filter(

View File

@@ -4430,6 +4430,262 @@
"description": "Modifier le type de caution de mon inscription WEI tant qu'elle n'est pas validée" "description": "Modifier le type de caution de mon inscription WEI tant qu'elle n'est pas validée"
} }
}, },
{
"model": "permission.permission",
"pk": 311,
"fields": {
"model": [
"family",
"family"
],
"query": "{}",
"type": "view",
"mask": 1,
"field": "",
"permanent": false,
"description": "Voir toutes les familles"
}
},
{
"model": "permission.permission",
"pk": 312,
"fields": {
"model": [
"family",
"family"
],
"query": "{}",
"type": "add",
"mask": 2,
"field": "",
"permanent": false,
"description": "Créer une famille"
}
},
{
"model": "permission.permission",
"pk": 313,
"fields": {
"model": [
"family",
"family"
],
"query": "{}",
"type": "change",
"mask": 2,
"field": "",
"permanent": false,
"description": "Modifier n'importe quelle famille"
}
},
{
"model": "permission.permission",
"pk": 314,
"fields": {
"model": [
"family",
"family"
],
"query": "{\"pk\": [\"user\", \"family_memberships\", \"family\", \"pk\"]}",
"type": "change",
"mask": 2,
"field": "",
"permanent": false,
"description": "Modifier ma famille"
}
},
{
"model": "permission.permission",
"pk": 315,
"fields": {
"model": [
"family",
"familymembership"
],
"query": "{}",
"type": "view",
"mask": 2,
"field": "",
"permanent": false,
"description": "Voir les membres de n'importe quelle famille"
}
},
{
"model": "permission.permission",
"pk": 316,
"fields": {
"model": [
"family",
"familymembership"
],
"query": "{\"family\": [\"user\", \"family_memberships\", \"family\"]}",
"type": "view",
"mask": 1,
"field": "",
"permanent": false,
"description": "Voir les membres de ma famille"
}
},
{
"model": "permission.permission",
"pk": 317,
"fields": {
"model": [
"family",
"familymembership"
],
"query": "{}",
"type": "add",
"mask": 2,
"field": "",
"permanent": false,
"description": "Ajouter un membre à n'importe quelle famille"
}
},
{
"model": "permission.permission",
"pk": 318,
"fields": {
"model": [
"family",
"familymembership"
],
"query": "{\"family\": [\"user\", \"family_memberships\", \"family\"]}",
"type": "add",
"mask": 2,
"field": "",
"permanent": false,
"description": "Ajouter un membre à ma famille"
}
},
{
"model": "permission.permission",
"pk": 319,
"fields": {
"model": [
"family",
"challenge"
],
"query": "{}",
"type": "view",
"mask": 1,
"field": "",
"permanent": false,
"description": "Voir tous les défis"
}
},
{
"model": "permission.permission",
"pk": 320,
"fields": {
"model": [
"family",
"challenge"
],
"query": "{}",
"type": "add",
"mask": 2,
"field": "",
"permanent": false,
"description": "Créer un défi"
}
},
{
"model": "permission.permission",
"pk": 321,
"fields": {
"model": [
"family",
"challenge"
],
"query": "{}",
"type": "change",
"mask": 2,
"field": "",
"permanent": false,
"description": "Modifier un défi"
}
},
{
"model": "permission.permission",
"pk": 322,
"fields": {
"model": [
"family",
"challenge"
],
"query": "{}",
"type": "delete",
"mask": 2,
"field": "{}",
"permanent": false,
"description": "Supprimer un défi"
}
},
{
"model": "permission.permission",
"pk": 323,
"fields": {
"model": [
"family",
"achievement"
],
"query": "{}",
"type": "view",
"mask": 1,
"field": "",
"permanent": false,
"description": "Voir tous les succès"
}
},
{
"model": "permission.permission",
"pk": 324,
"fields": {
"model": [
"family",
"achievement"
],
"query": "{}",
"type": "add",
"mask": 2,
"field": "",
"permanent": false,
"description": "Créer un succès"
}
},
{
"model": "permission.permission",
"pk": 325,
"fields": {
"model": [
"family",
"achievement"
],
"query": "{}",
"type": "change",
"mask": 1,
"field": "valid",
"permanent": false,
"description": "Valider un succès"
}
},
{
"model": "permission.permission",
"pk": 326,
"fields": {
"model": [
"family",
"achievement"
],
"query": "{}",
"type": "delete",
"mask": 1,
"field": "",
"permanent": false,
"description": "Supprimer un succès"
}
},
{ {
"model": "permission.role", "model": "permission.role",
"pk": 1, "pk": 1,
@@ -4482,9 +4738,13 @@
206, 206,
248, 248,
249, 249,
255, 255,
256, 256,
257 257,
311,
316,
319,
323
] ]
} }
}, },
@@ -5008,7 +5268,7 @@
216 216
] ]
} }
}, },
{ {
"model": "permission.role", "model": "permission.role",
"pk": 23, "pk": 23,
@@ -5021,7 +5281,7 @@
32 32
] ]
} }
}, },
{ {
"model": "permission.role", "model": "permission.role",
"pk": 24, "pk": 24,
@@ -5030,7 +5290,7 @@
"name": "Staffeur⋅euse (S&L,Respo Tech,...)", "name": "Staffeur⋅euse (S&L,Respo Tech,...)",
"permissions": [] "permissions": []
} }
}, },
{ {
"model": "permission.role", "model": "permission.role",
"pk": 25, "pk": 25,
@@ -5056,7 +5316,7 @@
293 293
] ]
} }
}, },
{ {
"model": "permission.role", "model": "permission.role",
"pk": 28, "pk": 28,
@@ -5086,7 +5346,7 @@
269 269
] ]
} }
}, },
{ {
"model": "permission.role", "model": "permission.role",
"pk": 30, "pk": 30,
@@ -5094,15 +5354,15 @@
"for_club": 10, "for_club": 10,
"name": "Respo sorties", "name": "Respo sorties",
"permissions": [ "permissions": [
49, 49,
62, 62,
141, 141,
241, 241,
242, 242,
243 243
] ]
} }
}, },
{ {
"model": "permission.role", "model": "permission.role",
"pk": 31, "pk": 31,
@@ -5114,7 +5374,7 @@
244 244
] ]
} }
}, },
{ {
"model": "permission.role", "model": "permission.role",
"pk": 32, "pk": 32,
@@ -5126,7 +5386,7 @@
245 245
] ]
} }
}, },
{ {
"model": "permission.role", "model": "permission.role",
"pk": 33, "pk": 33,
@@ -5134,15 +5394,48 @@
"for_club": 10, "for_club": 10,
"name": "Respo Jam", "name": "Respo Jam",
"permissions": [ "permissions": [
247, 247,
250, 250,
251, 251,
252, 252,
253, 253,
254 254
] ]
} }
}, },
{
"model": "permission.role",
"pk": 34,
"fields": {
"for_club": 1,
"name": "Chef·fe de famille",
"permissions": [
314,
318,
324
]
}
},
{
"model": "permission.role",
"pk": 35,
"fields": {
"for_club": 1,
"name": "Respo familles",
"permissions": [
312,
313,
315,
317,
320,
321,
322,
324,
325,
326
]
}
},
{ {
"model": "wei.weirole", "model": "wei.weirole",
"pk": 12, "pk": 12,