diff --git a/apps/member/admin.py b/apps/member/admin.py index c7c3ead3..2e50e8dc 100644 --- a/apps/member/admin.py +++ b/apps/member/admin.py @@ -6,7 +6,7 @@ from django.contrib.auth.admin import UserAdmin from django.contrib.auth.models import User from .forms import ProfileForm -from .models import Club, Membership, Profile, Role +from .models import Club, Membership, Profile class ProfileInline(admin.StackedInline): @@ -39,4 +39,3 @@ admin.site.register(User, CustomUserAdmin) # Add other models admin.site.register(Club) admin.site.register(Membership) -admin.site.register(Role) diff --git a/apps/member/api/serializers.py b/apps/member/api/serializers.py index a956a46b..19b2ff67 100644 --- a/apps/member/api/serializers.py +++ b/apps/member/api/serializers.py @@ -3,7 +3,7 @@ from rest_framework import serializers -from ..models import Profile, Club, Role, Membership +from ..models import Profile, Club, Membership class ProfileSerializer(serializers.ModelSerializer): @@ -29,17 +29,6 @@ class ClubSerializer(serializers.ModelSerializer): fields = '__all__' -class RoleSerializer(serializers.ModelSerializer): - """ - REST API Serializer for Roles. - The djangorestframework plugin will analyse the model `Role` and parse all fields in the API. - """ - - class Meta: - model = Role - fields = '__all__' - - class MembershipSerializer(serializers.ModelSerializer): """ REST API Serializer for Memberships. diff --git a/apps/member/api/urls.py b/apps/member/api/urls.py index 15bb83ca..5fa54472 100644 --- a/apps/member/api/urls.py +++ b/apps/member/api/urls.py @@ -1,7 +1,7 @@ # Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later -from .views import ProfileViewSet, ClubViewSet, RoleViewSet, MembershipViewSet +from .views import ProfileViewSet, ClubViewSet, MembershipViewSet def register_members_urls(router, path): @@ -10,5 +10,4 @@ def register_members_urls(router, path): """ router.register(path + '/profile', ProfileViewSet) router.register(path + '/club', ClubViewSet) - router.register(path + '/role', RoleViewSet) router.register(path + '/membership', MembershipViewSet) diff --git a/apps/member/api/views.py b/apps/member/api/views.py index 57c216a1..3dc07fe1 100644 --- a/apps/member/api/views.py +++ b/apps/member/api/views.py @@ -4,8 +4,8 @@ from rest_framework.filters import SearchFilter from api.viewsets import ReadProtectedModelViewSet -from .serializers import ProfileSerializer, ClubSerializer, RoleSerializer, MembershipSerializer -from ..models import Profile, Club, Role, Membership +from .serializers import ProfileSerializer, ClubSerializer, MembershipSerializer +from ..models import Profile, Club, Membership class ProfileViewSet(ReadProtectedModelViewSet): @@ -30,18 +30,6 @@ class ClubViewSet(ReadProtectedModelViewSet): search_fields = ['$name', ] -class RoleViewSet(ReadProtectedModelViewSet): - """ - REST API View set. - The djangorestframework plugin will get all `Role` objects, serialize it to JSON with the given serializer, - then render it on /api/members/role/ - """ - queryset = Role.objects.all() - serializer_class = RoleSerializer - filter_backends = [SearchFilter] - search_fields = ['$name', ] - - class MembershipViewSet(ReadProtectedModelViewSet): """ REST API View set. diff --git a/apps/member/forms.py b/apps/member/forms.py index e546d652..4bf3b738 100644 --- a/apps/member/forms.py +++ b/apps/member/forms.py @@ -7,9 +7,9 @@ from django.contrib.auth.models import User from django.utils.translation import gettext_lazy as _ from note.models import NoteSpecial from note_kfet.inputs import Autocomplete, AmountInput, DatePickerInput -from permission.models import PermissionMask +from permission.models import PermissionMask, Role -from .models import Profile, Club, Membership, Role +from .models import Profile, Club, Membership class CustomAuthenticationForm(AuthenticationForm): diff --git a/apps/member/models.py b/apps/member/models.py index 17b8f044..1972002d 100644 --- a/apps/member/models.py +++ b/apps/member/models.py @@ -247,24 +247,6 @@ class Club(models.Model): return reverse_lazy('member:club_detail', args=(self.pk,)) -class Role(models.Model): - """ - Role that an :model:`auth.User` can have in a :model:`member.Club` - """ - name = models.CharField( - verbose_name=_('name'), - max_length=255, - unique=True, - ) - - class Meta: - verbose_name = _('role') - verbose_name_plural = _('roles') - - def __str__(self): - return str(self.name) - - class Membership(models.Model): """ Register the membership of a user to a club, including roles and membership duration. @@ -284,7 +266,7 @@ class Membership(models.Model): ) roles = models.ManyToManyField( - Role, + "permission.Role", verbose_name=_("roles"), ) diff --git a/apps/member/views.py b/apps/member/views.py index 40e0fb0c..ddd5d084 100644 --- a/apps/member/views.py +++ b/apps/member/views.py @@ -22,10 +22,11 @@ from note.models import Alias, NoteUser from note.models.transactions import Transaction, SpecialTransaction from note.tables import HistoryTable, AliasTable from permission.backends import PermissionBackend +from permission.models import Role from permission.views import ProtectQuerysetMixin from .forms import ProfileForm, ClubForm, MembershipForm, CustomAuthenticationForm -from .models import Club, Membership, Role +from .models import Club, Membership from .tables import ClubTable, UserTable, MembershipTable diff --git a/apps/permission/admin.py b/apps/permission/admin.py index 4312f4b0..41e59695 100644 --- a/apps/permission/admin.py +++ b/apps/permission/admin.py @@ -3,7 +3,7 @@ from django.contrib import admin -from .models import Permission, PermissionMask, RolePermissions +from .models import Permission, PermissionMask, Role @admin.register(PermissionMask) @@ -22,9 +22,9 @@ class PermissionAdmin(admin.ModelAdmin): list_display = ('type', 'model', 'field', 'mask', 'description', ) -@admin.register(RolePermissions) -class RolePermissionsAdmin(admin.ModelAdmin): +@admin.register(Role) +class RoleAdmin(admin.ModelAdmin): """ - Admin customisation for RolePermissions + Admin customisation for Role """ - list_display = ('role', ) + list_display = ('name', ) diff --git a/apps/permission/api/serializers.py b/apps/permission/api/serializers.py index e30ed7dc..d0823e19 100644 --- a/apps/permission/api/serializers.py +++ b/apps/permission/api/serializers.py @@ -3,7 +3,7 @@ from rest_framework import serializers -from ..models import Permission, RolePermissions +from ..models import Permission, Role class PermissionSerializer(serializers.ModelSerializer): @@ -17,12 +17,12 @@ class PermissionSerializer(serializers.ModelSerializer): fields = '__all__' -class RolePermissionsSerializer(serializers.ModelSerializer): +class RoleSerializer(serializers.ModelSerializer): """ - REST API Serializer for RolePermissions types. - The djangorestframework plugin will analyse the model `RolePermissions` and parse all fields in the API. + REST API Serializer for Role types. + The djangorestframework plugin will analyse the model `Role` and parse all fields in the API. """ class Meta: - model = RolePermissions + model = Role fields = '__all__' diff --git a/apps/permission/api/urls.py b/apps/permission/api/urls.py index b5d53466..b1fdb199 100644 --- a/apps/permission/api/urls.py +++ b/apps/permission/api/urls.py @@ -1,7 +1,7 @@ # Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later -from .views import PermissionViewSet, RolePermissionsViewSet +from .views import PermissionViewSet, RoleViewSet def register_permission_urls(router, path): @@ -9,4 +9,4 @@ def register_permission_urls(router, path): Configure router for permission REST API. """ router.register(path + "/permission", PermissionViewSet) - router.register(path + "/roles", RolePermissionsViewSet) + router.register(path + "/roles", RoleViewSet) diff --git a/apps/permission/api/views.py b/apps/permission/api/views.py index 6a068225..1ec67aa3 100644 --- a/apps/permission/api/views.py +++ b/apps/permission/api/views.py @@ -4,8 +4,8 @@ from django_filters.rest_framework import DjangoFilterBackend from api.viewsets import ReadOnlyProtectedModelViewSet -from .serializers import PermissionSerializer, RolePermissionsSerializer -from ..models import Permission, RolePermissions +from .serializers import PermissionSerializer, RoleSerializer +from ..models import Permission, Role class PermissionViewSet(ReadOnlyProtectedModelViewSet): @@ -20,13 +20,13 @@ class PermissionViewSet(ReadOnlyProtectedModelViewSet): filterset_fields = ['model', 'type', ] -class RolePermissionsViewSet(ReadOnlyProtectedModelViewSet): +class RoleViewSet(ReadOnlyProtectedModelViewSet): """ REST API View set. The djangorestframework plugin will get all `RolePermission` objects, serialize it to JSON with the given serializer then render it on /api/permission/roles/ """ - queryset = RolePermissions.objects.all() - serializer_class = RolePermissionsSerializer + queryset = Role.objects.all() + serializer_class = RoleSerializer filter_backends = [DjangoFilterBackend] filterset_fields = ['role', ] diff --git a/apps/permission/backends.py b/apps/permission/backends.py index 2446f211..9dc69d3d 100644 --- a/apps/permission/backends.py +++ b/apps/permission/backends.py @@ -37,17 +37,17 @@ class PermissionBackend(ModelBackend): return Permission.objects.none() qs = Permission.objects.annotate( - club=F("rolepermissions__role__membership__club"), - membership=F("rolepermissions__role__membership"), + club=F("role__role__membership__club"), + membership=F("role__role__membership"), ).filter( ( Q( - rolepermissions__role__membership__date_start__lte=timezone.now().today(), - rolepermissions__role__membership__date_end__gte=timezone.now().today(), + role__role__membership__date_start__lte=timezone.now().today(), + role__role__membership__date_end__gte=timezone.now().today(), ) | Q(permanent=True) ) - & Q(rolepermissions__role__membership__user=user) + & Q(role__role__membership__user=user) & Q(type=t) & Q(mask__rank__lte=get_current_session().get("permission_mask", 0)) ) diff --git a/apps/permission/fixtures/initial.json b/apps/permission/fixtures/initial.json index 25509b56..0b2df73e 100644 --- a/apps/permission/fixtures/initial.json +++ b/apps/permission/fixtures/initial.json @@ -1,165 +1,4 @@ [ - { - "model": "member.role", - "pk": 1, - "fields": { - "name": "Adh\u00e9rent BDE" - } - }, - { - "model": "member.role", - "pk": 2, - "fields": { - "name": "Adh\u00e9rent Kfet" - } - }, - { - "model": "member.role", - "pk": 3, - "fields": { - "name": "Membre de club" - } - }, - { - "model": "member.role", - "pk": 4, - "fields": { - "name": "Bureau de club" - } - }, - { - "model": "member.role", - "pk": 5, - "fields": { - "name": "Pr\u00e9sident\u00b7e de club" - } - }, - { - "model": "member.role", - "pk": 6, - "fields": { - "name": "Tr\u00e9sorier\u00b7\u00e8re de club" - } - }, - { - "model": "member.role", - "pk": 7, - "fields": { - "name": "Pr\u00e9sident\u00b7e BDE" - } - }, - { - "model": "member.role", - "pk": 8, - "fields": { - "name": "Tr\u00e9sorier\u00b7\u00e8re BDE" - } - }, - { - "model": "member.role", - "pk": 9, - "fields": { - "name": "Respo info" - } - }, - { - "model": "member.role", - "pk": 10, - "fields": { - "name": "GC Kfet" - } - }, - { - "model": "member.role", - "pk": 11, - "fields": { - "name": "Res[pot]" - } - }, - { - "model": "member.role", - "pk": 12, - "fields": { - "name": "GC WEI" - } - }, - { - "model": "member.role", - "pk": 13, - "fields": { - "name": "Chef de bus" - } - }, - { - "model": "member.role", - "pk": 14, - "fields": { - "name": "Chef d'\u00e9quipe" - } - }, - { - "model": "member.role", - "pk": 15, - "fields": { - "name": "\u00c9lectron libre" - } - }, - { - "model": "member.role", - "pk": 16, - "fields": { - "name": "\u00c9lectron libre (avec perm)" - } - }, - { - "model": "member.role", - "pk": 17, - "fields": { - "name": "1A" - } - }, - { - "model": "member.role", - "pk": 18, - "fields": { - "name": "Adhérent WEI" - } - }, - { - "model": "wei.weirole", - "pk": 12, - "fields": {} - }, - { - "model": "wei.weirole", - "pk": 13, - "fields": {} - }, - { - "model": "wei.weirole", - "pk": 14, - "fields": {} - }, - { - "model": "wei.weirole", - "pk": 15, - "fields": {} - }, - { - "model": "wei.weirole", - "pk": 16, - "fields": {} - }, - { - "model": "wei.weirole", - "pk": 17, - "fields": {} - }, - { - "model": "wei.weirole", - "pk": 18, - "fields": {} - }, { "model": "permission.permissionmask", "pk": 1, @@ -2217,10 +2056,10 @@ } }, { - "model": "permission.rolepermissions", + "model": "permission.role", "pk": 1, "fields": { - "role": 1, + "name": "Adh\u00e9rent BDE", "permissions": [ 1, 2, @@ -2241,10 +2080,10 @@ } }, { - "model": "permission.rolepermissions", + "model": "permission.role", "pk": 2, "fields": { - "role": 2, + "name": "Adh\u00e9rent Kfet", "permissions": [ 34, 35, @@ -2267,10 +2106,17 @@ } }, { - "model": "permission.rolepermissions", + "model": "permission.role", + "pk": 3, + "fields": { + "name": "Membre de club" + } + }, + { + "model": "permission.role", "pk": 4, "fields": { - "role": 4, + "name": "Bureau de club", "permissions": [ 22, 47, @@ -2279,10 +2125,10 @@ } }, { - "model": "permission.rolepermissions", + "model": "permission.role", "pk": 5, "fields": { - "role": 5, + "name": "Pr\u00e9sident\u00b7e de club", "permissions": [ 50, 51, @@ -2291,10 +2137,10 @@ } }, { - "model": "permission.rolepermissions", + "model": "permission.role", "pk": 6, "fields": { - "role": 6, + "name": "Tr\u00e9sorier\u00b7\u00e8re de club", "permissions": [ 59, 19, @@ -2309,10 +2155,10 @@ } }, { - "model": "permission.rolepermissions", + "model": "permission.role", "pk": 7, "fields": { - "role": 7, + "name": "Pr\u00e9sident\u00b7e BDE", "permissions": [ 24, 25, @@ -2323,10 +2169,10 @@ } }, { - "model": "permission.rolepermissions", + "model": "permission.role", "pk": 8, "fields": { - "role": 8, + "name": "Tr\u00e9sorier\u00b7\u00e8re BDE", "permissions": [ 23, 24, @@ -2359,10 +2205,10 @@ } }, { - "model": "permission.rolepermissions", + "model": "permission.role", "pk": 9, "fields": { - "role": 9, + "name": "Respo info", "permissions": [ 1, 2, @@ -2494,10 +2340,10 @@ } }, { - "model": "permission.rolepermissions", + "model": "permission.role", "pk": 10, "fields": { - "role": 10, + "name": "GC Kfet", "permissions": [ 32, 33, @@ -2521,10 +2367,10 @@ } }, { - "model": "permission.rolepermissions", + "model": "permission.role", "pk": 11, "fields": { - "role": 11, + "name": "Res[pot]", "permissions": [ 37, 38, @@ -2538,10 +2384,10 @@ } }, { - "model": "permission.rolepermissions", + "model": "permission.role", "pk": 12, "fields": { - "role": 12, + "name": "GC WEI", "permissions": [ 76, 80, @@ -2571,10 +2417,10 @@ } }, { - "model": "permission.rolepermissions", + "model": "permission.role", "pk": 13, "fields": { - "role": 13, + "name": "Chef de bus", "permissions": [ 117, 118, @@ -2586,10 +2432,10 @@ } }, { - "model": "permission.rolepermissions", + "model": "permission.role", "pk": 14, "fields": { - "role": 14, + "name": "Chef d'\u00e9quipe", "permissions": [ 116, 123, @@ -2599,10 +2445,31 @@ } }, { - "model": "permission.rolepermissions", + "model": "permission.role", + "pk": 15, + "fields": { + "name": "\u00c9lectron libre" + } + }, + { + "model": "permission.role", "pk": 16, "fields": { - "role": 18, + "name": "\u00c9lectron libre (avec perm)" + } + }, + { + "model": "permission.role", + "pk": 17, + "fields": { + "name": "1A" + } + }, + { + "model": "permission.role", + "pk": 18, + "fields": { + "name": "Adhérent WEI", "permissions": [ 97, 99, @@ -2618,5 +2485,40 @@ 95 ] } + }, + { + "model": "wei.weirole", + "pk": 12, + "fields": {} + }, + { + "model": "wei.weirole", + "pk": 13, + "fields": {} + }, + { + "model": "wei.weirole", + "pk": 14, + "fields": {} + }, + { + "model": "wei.weirole", + "pk": 15, + "fields": {} + }, + { + "model": "wei.weirole", + "pk": 16, + "fields": {} + }, + { + "model": "wei.weirole", + "pk": 17, + "fields": {} + }, + { + "model": "wei.weirole", + "pk": 18, + "fields": {} } ] diff --git a/apps/permission/models.py b/apps/permission/models.py index ed4a90d0..77aacff7 100644 --- a/apps/permission/models.py +++ b/apps/permission/models.py @@ -10,7 +10,6 @@ from django.core.exceptions import ValidationError from django.db import models from django.db.models import F, Q, Model from django.utils.translation import gettext_lazy as _ -from member.models import Role class InstancedPermission: @@ -307,23 +306,22 @@ class Permission(models.Model): return self.description -class RolePermissions(models.Model): +class Role(models.Model): """ Permissions associated with a Role """ - role = models.OneToOneField( - Role, - on_delete=models.PROTECT, - related_name='permissions', - verbose_name=_('role'), + name = models.CharField( + max_length=255, + verbose_name=_("name"), ) + permissions = models.ManyToManyField( Permission, verbose_name=_("permissions"), ) def __str__(self): - return str(self.role) + return self.name class Meta: verbose_name = _("role permissions") diff --git a/apps/permission/views.py b/apps/permission/views.py index cbd26a19..f3ed5641 100644 --- a/apps/permission/views.py +++ b/apps/permission/views.py @@ -5,9 +5,10 @@ from datetime import date from django.forms import HiddenInput from django.utils.translation import gettext_lazy as _ from django.views.generic import UpdateView, TemplateView -from member.models import Role, Membership +from member.models import Membership from .backends import PermissionBackend +from .models import Role class ProtectQuerysetMixin: diff --git a/apps/registration/views.py b/apps/registration/views.py index a0e62202..bca0d217 100644 --- a/apps/registration/views.py +++ b/apps/registration/views.py @@ -15,10 +15,11 @@ from django.views.generic import CreateView, TemplateView, DetailView from django.views.generic.edit import FormMixin from django_tables2 import SingleTableView from member.forms import ProfileForm -from member.models import Membership, Club, Role +from member.models import Membership, Club from note.models import SpecialTransaction from note.templatetags.pretty_money import pretty_money from permission.backends import PermissionBackend +from permission.models import Role from permission.views import ProtectQuerysetMixin from .forms import SignUpForm, ValidationForm diff --git a/apps/wei/models.py b/apps/wei/models.py index 6153a870..d2afa57f 100644 --- a/apps/wei/models.py +++ b/apps/wei/models.py @@ -8,8 +8,9 @@ from django.conf import settings from django.contrib.auth.models import User from django.db import models from django.utils.translation import gettext_lazy as _ -from member.models import Role, Club, Membership +from member.models import Club, Membership from note.models import MembershipTransaction +from permission.models import Role class WEIClub(Club):