Merge Role and RolePermissions

This commit is contained in:
Yohann D'ANELLO 2020-07-25 19:40:30 +02:00
parent 0b6cb4ef19
commit fb5e2578af
17 changed files with 135 additions and 274 deletions

View File

@ -6,7 +6,7 @@ from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User from django.contrib.auth.models import User
from .forms import ProfileForm from .forms import ProfileForm
from .models import Club, Membership, Profile, Role from .models import Club, Membership, Profile
class ProfileInline(admin.StackedInline): class ProfileInline(admin.StackedInline):
@ -39,4 +39,3 @@ admin.site.register(User, CustomUserAdmin)
# Add other models # Add other models
admin.site.register(Club) admin.site.register(Club)
admin.site.register(Membership) admin.site.register(Membership)
admin.site.register(Role)

View File

@ -3,7 +3,7 @@
from rest_framework import serializers from rest_framework import serializers
from ..models import Profile, Club, Role, Membership from ..models import Profile, Club, Membership
class ProfileSerializer(serializers.ModelSerializer): class ProfileSerializer(serializers.ModelSerializer):
@ -29,17 +29,6 @@ class ClubSerializer(serializers.ModelSerializer):
fields = '__all__' 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): class MembershipSerializer(serializers.ModelSerializer):
""" """
REST API Serializer for Memberships. REST API Serializer for Memberships.

View File

@ -1,7 +1,7 @@
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later # 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): def register_members_urls(router, path):
@ -10,5 +10,4 @@ def register_members_urls(router, path):
""" """
router.register(path + '/profile', ProfileViewSet) router.register(path + '/profile', ProfileViewSet)
router.register(path + '/club', ClubViewSet) router.register(path + '/club', ClubViewSet)
router.register(path + '/role', RoleViewSet)
router.register(path + '/membership', MembershipViewSet) router.register(path + '/membership', MembershipViewSet)

View File

@ -4,8 +4,8 @@
from rest_framework.filters import SearchFilter from rest_framework.filters import SearchFilter
from api.viewsets import ReadProtectedModelViewSet from api.viewsets import ReadProtectedModelViewSet
from .serializers import ProfileSerializer, ClubSerializer, RoleSerializer, MembershipSerializer from .serializers import ProfileSerializer, ClubSerializer, MembershipSerializer
from ..models import Profile, Club, Role, Membership from ..models import Profile, Club, Membership
class ProfileViewSet(ReadProtectedModelViewSet): class ProfileViewSet(ReadProtectedModelViewSet):
@ -30,18 +30,6 @@ class ClubViewSet(ReadProtectedModelViewSet):
search_fields = ['$name', ] 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): class MembershipViewSet(ReadProtectedModelViewSet):
""" """
REST API View set. REST API View set.

View File

@ -7,9 +7,9 @@ from django.contrib.auth.models import User
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from note.models import NoteSpecial from note.models import NoteSpecial
from note_kfet.inputs import Autocomplete, AmountInput, DatePickerInput 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): class CustomAuthenticationForm(AuthenticationForm):

View File

@ -247,24 +247,6 @@ class Club(models.Model):
return reverse_lazy('member:club_detail', args=(self.pk,)) 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): class Membership(models.Model):
""" """
Register the membership of a user to a club, including roles and membership duration. 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( roles = models.ManyToManyField(
Role, "permission.Role",
verbose_name=_("roles"), verbose_name=_("roles"),
) )

View File

@ -22,10 +22,11 @@ from note.models import Alias, NoteUser
from note.models.transactions import Transaction, SpecialTransaction from note.models.transactions import Transaction, SpecialTransaction
from note.tables import HistoryTable, AliasTable from note.tables import HistoryTable, AliasTable
from permission.backends import PermissionBackend from permission.backends import PermissionBackend
from permission.models import Role
from permission.views import ProtectQuerysetMixin from permission.views import ProtectQuerysetMixin
from .forms import ProfileForm, ClubForm, MembershipForm, CustomAuthenticationForm from .forms import ProfileForm, ClubForm, MembershipForm, CustomAuthenticationForm
from .models import Club, Membership, Role from .models import Club, Membership
from .tables import ClubTable, UserTable, MembershipTable from .tables import ClubTable, UserTable, MembershipTable

View File

@ -3,7 +3,7 @@
from django.contrib import admin from django.contrib import admin
from .models import Permission, PermissionMask, RolePermissions from .models import Permission, PermissionMask, Role
@admin.register(PermissionMask) @admin.register(PermissionMask)
@ -22,9 +22,9 @@ class PermissionAdmin(admin.ModelAdmin):
list_display = ('type', 'model', 'field', 'mask', 'description', ) list_display = ('type', 'model', 'field', 'mask', 'description', )
@admin.register(RolePermissions) @admin.register(Role)
class RolePermissionsAdmin(admin.ModelAdmin): class RoleAdmin(admin.ModelAdmin):
""" """
Admin customisation for RolePermissions Admin customisation for Role
""" """
list_display = ('role', ) list_display = ('name', )

View File

@ -3,7 +3,7 @@
from rest_framework import serializers from rest_framework import serializers
from ..models import Permission, RolePermissions from ..models import Permission, Role
class PermissionSerializer(serializers.ModelSerializer): class PermissionSerializer(serializers.ModelSerializer):
@ -17,12 +17,12 @@ class PermissionSerializer(serializers.ModelSerializer):
fields = '__all__' fields = '__all__'
class RolePermissionsSerializer(serializers.ModelSerializer): class RoleSerializer(serializers.ModelSerializer):
""" """
REST API Serializer for RolePermissions types. REST API Serializer for Role types.
The djangorestframework plugin will analyse the model `RolePermissions` and parse all fields in the API. The djangorestframework plugin will analyse the model `Role` and parse all fields in the API.
""" """
class Meta: class Meta:
model = RolePermissions model = Role
fields = '__all__' fields = '__all__'

View File

@ -1,7 +1,7 @@
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from .views import PermissionViewSet, RolePermissionsViewSet from .views import PermissionViewSet, RoleViewSet
def register_permission_urls(router, path): def register_permission_urls(router, path):
@ -9,4 +9,4 @@ def register_permission_urls(router, path):
Configure router for permission REST API. Configure router for permission REST API.
""" """
router.register(path + "/permission", PermissionViewSet) router.register(path + "/permission", PermissionViewSet)
router.register(path + "/roles", RolePermissionsViewSet) router.register(path + "/roles", RoleViewSet)

View File

@ -4,8 +4,8 @@
from django_filters.rest_framework import DjangoFilterBackend from django_filters.rest_framework import DjangoFilterBackend
from api.viewsets import ReadOnlyProtectedModelViewSet from api.viewsets import ReadOnlyProtectedModelViewSet
from .serializers import PermissionSerializer, RolePermissionsSerializer from .serializers import PermissionSerializer, RoleSerializer
from ..models import Permission, RolePermissions from ..models import Permission, Role
class PermissionViewSet(ReadOnlyProtectedModelViewSet): class PermissionViewSet(ReadOnlyProtectedModelViewSet):
@ -20,13 +20,13 @@ class PermissionViewSet(ReadOnlyProtectedModelViewSet):
filterset_fields = ['model', 'type', ] filterset_fields = ['model', 'type', ]
class RolePermissionsViewSet(ReadOnlyProtectedModelViewSet): class RoleViewSet(ReadOnlyProtectedModelViewSet):
""" """
REST API View set. REST API View set.
The djangorestframework plugin will get all `RolePermission` objects, serialize it to JSON with the given serializer The djangorestframework plugin will get all `RolePermission` objects, serialize it to JSON with the given serializer
then render it on /api/permission/roles/ then render it on /api/permission/roles/
""" """
queryset = RolePermissions.objects.all() queryset = Role.objects.all()
serializer_class = RolePermissionsSerializer serializer_class = RoleSerializer
filter_backends = [DjangoFilterBackend] filter_backends = [DjangoFilterBackend]
filterset_fields = ['role', ] filterset_fields = ['role', ]

View File

@ -37,17 +37,17 @@ class PermissionBackend(ModelBackend):
return Permission.objects.none() return Permission.objects.none()
qs = Permission.objects.annotate( qs = Permission.objects.annotate(
club=F("rolepermissions__role__membership__club"), club=F("role__role__membership__club"),
membership=F("rolepermissions__role__membership"), membership=F("role__role__membership"),
).filter( ).filter(
( (
Q( Q(
rolepermissions__role__membership__date_start__lte=timezone.now().today(), role__role__membership__date_start__lte=timezone.now().today(),
rolepermissions__role__membership__date_end__gte=timezone.now().today(), role__role__membership__date_end__gte=timezone.now().today(),
) )
| Q(permanent=True) | Q(permanent=True)
) )
& Q(rolepermissions__role__membership__user=user) & Q(role__role__membership__user=user)
& Q(type=t) & Q(type=t)
& Q(mask__rank__lte=get_current_session().get("permission_mask", 0)) & Q(mask__rank__lte=get_current_session().get("permission_mask", 0))
) )

View File

@ -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", "model": "permission.permissionmask",
"pk": 1, "pk": 1,
@ -2217,10 +2056,10 @@
} }
}, },
{ {
"model": "permission.rolepermissions", "model": "permission.role",
"pk": 1, "pk": 1,
"fields": { "fields": {
"role": 1, "name": "Adh\u00e9rent BDE",
"permissions": [ "permissions": [
1, 1,
2, 2,
@ -2241,10 +2080,10 @@
} }
}, },
{ {
"model": "permission.rolepermissions", "model": "permission.role",
"pk": 2, "pk": 2,
"fields": { "fields": {
"role": 2, "name": "Adh\u00e9rent Kfet",
"permissions": [ "permissions": [
34, 34,
35, 35,
@ -2267,10 +2106,17 @@
} }
}, },
{ {
"model": "permission.rolepermissions", "model": "permission.role",
"pk": 3,
"fields": {
"name": "Membre de club"
}
},
{
"model": "permission.role",
"pk": 4, "pk": 4,
"fields": { "fields": {
"role": 4, "name": "Bureau de club",
"permissions": [ "permissions": [
22, 22,
47, 47,
@ -2279,10 +2125,10 @@
} }
}, },
{ {
"model": "permission.rolepermissions", "model": "permission.role",
"pk": 5, "pk": 5,
"fields": { "fields": {
"role": 5, "name": "Pr\u00e9sident\u00b7e de club",
"permissions": [ "permissions": [
50, 50,
51, 51,
@ -2291,10 +2137,10 @@
} }
}, },
{ {
"model": "permission.rolepermissions", "model": "permission.role",
"pk": 6, "pk": 6,
"fields": { "fields": {
"role": 6, "name": "Tr\u00e9sorier\u00b7\u00e8re de club",
"permissions": [ "permissions": [
59, 59,
19, 19,
@ -2309,10 +2155,10 @@
} }
}, },
{ {
"model": "permission.rolepermissions", "model": "permission.role",
"pk": 7, "pk": 7,
"fields": { "fields": {
"role": 7, "name": "Pr\u00e9sident\u00b7e BDE",
"permissions": [ "permissions": [
24, 24,
25, 25,
@ -2323,10 +2169,10 @@
} }
}, },
{ {
"model": "permission.rolepermissions", "model": "permission.role",
"pk": 8, "pk": 8,
"fields": { "fields": {
"role": 8, "name": "Tr\u00e9sorier\u00b7\u00e8re BDE",
"permissions": [ "permissions": [
23, 23,
24, 24,
@ -2359,10 +2205,10 @@
} }
}, },
{ {
"model": "permission.rolepermissions", "model": "permission.role",
"pk": 9, "pk": 9,
"fields": { "fields": {
"role": 9, "name": "Respo info",
"permissions": [ "permissions": [
1, 1,
2, 2,
@ -2494,10 +2340,10 @@
} }
}, },
{ {
"model": "permission.rolepermissions", "model": "permission.role",
"pk": 10, "pk": 10,
"fields": { "fields": {
"role": 10, "name": "GC Kfet",
"permissions": [ "permissions": [
32, 32,
33, 33,
@ -2521,10 +2367,10 @@
} }
}, },
{ {
"model": "permission.rolepermissions", "model": "permission.role",
"pk": 11, "pk": 11,
"fields": { "fields": {
"role": 11, "name": "Res[pot]",
"permissions": [ "permissions": [
37, 37,
38, 38,
@ -2538,10 +2384,10 @@
} }
}, },
{ {
"model": "permission.rolepermissions", "model": "permission.role",
"pk": 12, "pk": 12,
"fields": { "fields": {
"role": 12, "name": "GC WEI",
"permissions": [ "permissions": [
76, 76,
80, 80,
@ -2571,10 +2417,10 @@
} }
}, },
{ {
"model": "permission.rolepermissions", "model": "permission.role",
"pk": 13, "pk": 13,
"fields": { "fields": {
"role": 13, "name": "Chef de bus",
"permissions": [ "permissions": [
117, 117,
118, 118,
@ -2586,10 +2432,10 @@
} }
}, },
{ {
"model": "permission.rolepermissions", "model": "permission.role",
"pk": 14, "pk": 14,
"fields": { "fields": {
"role": 14, "name": "Chef d'\u00e9quipe",
"permissions": [ "permissions": [
116, 116,
123, 123,
@ -2599,10 +2445,31 @@
} }
}, },
{ {
"model": "permission.rolepermissions", "model": "permission.role",
"pk": 15,
"fields": {
"name": "\u00c9lectron libre"
}
},
{
"model": "permission.role",
"pk": 16, "pk": 16,
"fields": { "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": [ "permissions": [
97, 97,
99, 99,
@ -2618,5 +2485,40 @@
95 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": {}
} }
] ]

View File

@ -10,7 +10,6 @@ from django.core.exceptions import ValidationError
from django.db import models from django.db import models
from django.db.models import F, Q, Model from django.db.models import F, Q, Model
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from member.models import Role
class InstancedPermission: class InstancedPermission:
@ -307,23 +306,22 @@ class Permission(models.Model):
return self.description return self.description
class RolePermissions(models.Model): class Role(models.Model):
""" """
Permissions associated with a Role Permissions associated with a Role
""" """
role = models.OneToOneField( name = models.CharField(
Role, max_length=255,
on_delete=models.PROTECT, verbose_name=_("name"),
related_name='permissions',
verbose_name=_('role'),
) )
permissions = models.ManyToManyField( permissions = models.ManyToManyField(
Permission, Permission,
verbose_name=_("permissions"), verbose_name=_("permissions"),
) )
def __str__(self): def __str__(self):
return str(self.role) return self.name
class Meta: class Meta:
verbose_name = _("role permissions") verbose_name = _("role permissions")

View File

@ -5,9 +5,10 @@ from datetime import date
from django.forms import HiddenInput from django.forms import HiddenInput
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.views.generic import UpdateView, TemplateView from django.views.generic import UpdateView, TemplateView
from member.models import Role, Membership from member.models import Membership
from .backends import PermissionBackend from .backends import PermissionBackend
from .models import Role
class ProtectQuerysetMixin: class ProtectQuerysetMixin:

View File

@ -15,10 +15,11 @@ from django.views.generic import CreateView, TemplateView, DetailView
from django.views.generic.edit import FormMixin from django.views.generic.edit import FormMixin
from django_tables2 import SingleTableView from django_tables2 import SingleTableView
from member.forms import ProfileForm 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.models import SpecialTransaction
from note.templatetags.pretty_money import pretty_money from note.templatetags.pretty_money import pretty_money
from permission.backends import PermissionBackend from permission.backends import PermissionBackend
from permission.models import Role
from permission.views import ProtectQuerysetMixin from permission.views import ProtectQuerysetMixin
from .forms import SignUpForm, ValidationForm from .forms import SignUpForm, ValidationForm

View File

@ -8,8 +8,9 @@ from django.conf import settings
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.db import models from django.db import models
from django.utils.translation import gettext_lazy as _ 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 note.models import MembershipTransaction
from permission.models import Role
class WEIClub(Club): class WEIClub(Club):