1
0
Parcourir la source

TODO: ne pas pouvoir ajouter un abo à n'importe qui, readme, notifs au bureau, ne pas pouvoir chger un user d'un abo, check daimrod place date inscription et fin, faire tester la secu, migrations propres

SimonBoulier il y a 7 ans
Parent
commit
436fc8a999
3 fichiers modifiés avec 95 ajouts et 42 suppressions
  1. 60 39
      coin/members/admin.py
  2. 24 2
      coin/members/models.py
  3. 11 1
      coin/offers/admin.py

+ 60 - 39
coin/members/admin.py

@@ -5,7 +5,7 @@ from django.shortcuts import render, get_object_or_404
 from django.contrib import admin
 from django.contrib import admin
 from django.contrib import messages
 from django.contrib import messages
 from django.contrib.auth.admin import UserAdmin
 from django.contrib.auth.admin import UserAdmin
-from django.contrib.auth.models import Group
+from django.contrib.auth.models import Group, Permission
 from django.http import HttpResponseRedirect
 from django.http import HttpResponseRedirect
 from django.conf.urls import url
 from django.conf.urls import url
 from django.db.models.query import QuerySet
 from django.db.models.query import QuerySet
@@ -13,7 +13,7 @@ from django.core.urlresolvers import reverse
 from django.utils.html import format_html
 from django.utils.html import format_html
 
 
 from coin.members.models import (
 from coin.members.models import (
-    Member, CryptoKey, LdapUser, MembershipFee, OfferSubscription)
+    Member, CryptoKey, LdapUser, MembershipFee, OfferSubscription, RowLevelPermission)
 from coin.members.membershipfee_filter import MembershipFeeFilter
 from coin.members.membershipfee_filter import MembershipFeeFilter
 from coin.members.forms import MemberChangeForm, MemberCreationForm
 from coin.members.forms import MemberChangeForm, MemberCreationForm
 from coin.utils import delete_selected
 from coin.utils import delete_selected
@@ -68,42 +68,46 @@ class MemberAdmin(UserAdmin):
     form = MemberChangeForm
     form = MemberChangeForm
     add_form = MemberCreationForm
     add_form = MemberCreationForm
 
 
-    fieldsets = (
-        ('Adhérent', {'fields': (
-            ('status', 'resign_date'),
-            'type',
-            ('first_name', 'last_name', 'nickname'),
-            'organization_name',
-            'comments')}),
-        ('Coordonnées', {'fields': (
+    def get_fieldsets(self, request, obj=None):
+        coord_fieldset = ('Coordonnées', {'fields': (
             'email',
             'email',
             ('home_phone_number', 'mobile_phone_number'),
             ('home_phone_number', 'mobile_phone_number'),
             'address',
             'address',
-            ('postal_code', 'city', 'country'))}),
-        ('Authentification', {'fields': (
-            ('username', 'password'))}),
-        ('Permissions', {'fields': (
-            ('is_active', 'is_staff', 'is_superuser'))}),
-        (None, {'fields': ('date_last_call_for_membership_fees_email',)})
-    )
-
-    add_fieldsets = (
-        ('Adhérent', {'fields': (
-            'status',
-            'type',
-            ('first_name', 'last_name', 'nickname'),
-            'organization_name',
-            'comments')}),
-        ('Coordonnées', {'fields': (
-            'email',
-            ('home_phone_number', 'mobile_phone_number'),
-            'address',
-            ('postal_code', 'city', 'country'))}),
-        ('Authentification', {'fields': (
-            ('username', 'password'),)}),
-        ('Permissions', {'fields': (
-            ('is_active', 'is_staff', 'is_superuser', 'date_joined'))})
-    )
+            ('postal_code', 'city', 'country'))})
+        if request.user.is_superuser:
+            auth_fieldset = ('Authentification', {'fields': (
+                ('username', 'password'))})
+        else:
+            auth_fieldset = ('Authentification', {'fields': (
+                ('username',))})
+        perm_fieldset = ('Permissions', {'fields': (
+            ('is_active', 'is_staff', 'is_superuser', 'groups'))})
+        
+        if obj:
+            return (
+                ('Adhérent', {'fields': (
+                    ('status', 'date_joined', 'resign_date'),
+                    'type',
+                    ('first_name', 'last_name', 'nickname'),
+                    'organization_name',
+                    'comments')}),
+                coord_fieldset,
+                auth_fieldset,
+                perm_fieldset,
+                (None, {'fields': ('date_last_call_for_membership_fees_email',)})
+            )
+        else:
+            return (
+                ('Adhérent', {'fields': (
+                    ('status', 'date_joined'),
+                    'type',
+                    ('first_name', 'last_name', 'nickname'),
+                    'organization_name',
+                    'comments')}),
+                coord_fieldset,
+                auth_fieldset,
+                perm_fieldset
+            )
 
 
     radio_fields = {"type": admin.HORIZONTAL}
     radio_fields = {"type": admin.HORIZONTAL}
 
 
@@ -111,16 +115,27 @@ class MemberAdmin(UserAdmin):
 
 
     inlines = [CryptoKeyInline, MembershipFeeInline, OfferSubscriptionInline]
     inlines = [CryptoKeyInline, MembershipFeeInline, OfferSubscriptionInline]
 
 
+    def get_queryset(self, request):
+        qs = super(MemberAdmin, self).get_queryset(request)
+        if request.user.is_superuser:
+            return qs
+        else:
+            offers = RowLevelPermission.get_manageable_offers(request.user)
+            return qs.filter(offersubscription__offer__in=offers).distinct()
+
     def get_readonly_fields(self, request, obj=None):
     def get_readonly_fields(self, request, obj=None):
+        readonly_fields = []
         if obj:
         if obj:
             # Remove help_text for readonly field (can't do that in the Form
             # Remove help_text for readonly field (can't do that in the Form
             # django seems to user help_text from model for readonly fields)
             # django seems to user help_text from model for readonly fields)
             username_field = [
             username_field = [
                 f for f in obj._meta.fields if f.name == 'username']
                 f for f in obj._meta.fields if f.name == 'username']
             username_field[0].help_text = ''
             username_field[0].help_text = ''
-            return ['username', ]
-        else:
-            return []
+
+            readonly_fields.append('username')
+        if not request.user.is_superuser:
+            readonly_fields += ['is_active', 'is_staff', 'is_superuser', 'groups', 'date_last_call_for_membership_fees_email']
+        return readonly_fields
 
 
     def set_as_member(self, request, queryset):
     def set_as_member(self, request, queryset):
         rows_updated = queryset.update(status='member')
         rows_updated = queryset.update(status='member')
@@ -218,7 +233,13 @@ class MembershipFeeAdmin(admin.ModelAdmin):
                     'payment_date')
                     'payment_date')
     form = autocomplete_light.modelform_factory(MembershipFee, fields='__all__')
     form = autocomplete_light.modelform_factory(MembershipFee, fields='__all__')
 
 
+
+class PermisionAdmin(admin.ModelAdmin):
+    pass
+
+
 admin.site.register(Member, MemberAdmin)
 admin.site.register(Member, MemberAdmin)
 admin.site.register(MembershipFee, MembershipFeeAdmin)
 admin.site.register(MembershipFee, MembershipFeeAdmin)
-admin.site.unregister(Group)
+# admin.site.unregister(Group)
 # admin.site.register(LdapUser, LdapUserAdmin)
 # admin.site.register(LdapUser, LdapUserAdmin)
+admin.site.register(RowLevelPermission)

+ 24 - 2
coin/members/models.py

@@ -9,14 +9,15 @@ from django.db import models
 from django.db.models import Q, Max
 from django.db.models import Q, Max
 from django.db.models.signals import pre_save
 from django.db.models.signals import pre_save
 from django.dispatch import receiver
 from django.dispatch import receiver
-from django.contrib.auth.models import AbstractUser
+from django.contrib.auth.models import AbstractUser, Permission
+from django.contrib.contenttypes.models import ContentType
 from django.conf import settings
 from django.conf import settings
 from django.core.validators import RegexValidator
 from django.core.validators import RegexValidator
 from django.core.exceptions import ValidationError
 from django.core.exceptions import ValidationError
 from django.utils import timezone
 from django.utils import timezone
 from ldapdb.models.fields import CharField, IntegerField, ListField
 from ldapdb.models.fields import CharField, IntegerField, ListField
 
 
-from coin.offers.models import OfferSubscription
+from coin.offers.models import Offer, OfferSubscription
 from coin.mixins import CoinLdapSyncMixin
 from coin.mixins import CoinLdapSyncMixin
 from coin import utils
 from coin import utils
 
 
@@ -486,6 +487,27 @@ class LdapUser(ldapdb.models.Model):
 # managed = False  # Indique à Django de ne pas intégrer ce model en base
 # managed = False  # Indique à Django de ne pas intégrer ce model en base
 
 
 
 
+class RowLevelPermission(Permission):
+    offer = models.ForeignKey(
+        'offers.Offer', null=True, verbose_name="Offre",
+        help_text="Offre dont l'utilisateur est autorisé à voir et modifier les membres et les abonnements.")
+    description = models.TextField(blank=True)
+
+    @classmethod
+    def get_manageable_offers(cls, user):
+        """" Renvoie la liste des offres dont l'utilisateur est autorisé à
+        voir les membres et les abonnements dans l'interface d'administration.
+        """
+        # toutes les permissions appliquées à cet utilisateur
+        perms = user.get_all_permissions()
+        # les RowLevelpermission qui correspondent et qui sont relatives à des OfferSubscription
+        rowperms = [p for p in cls.objects.filter(content_type=ContentType.objects.get_for_model(OfferSubscription))
+                   if ('offers.' + p.codename) in perms]
+        # les offres correspondantes
+        offers = [p.offer for p in rowperms]
+        return offers
+
+
 @receiver(pre_save, sender=Member)
 @receiver(pre_save, sender=Member)
 def define_username(sender, instance, **kwargs):
 def define_username(sender, instance, **kwargs):
     """
     """

+ 11 - 1
coin/offers/admin.py

@@ -2,8 +2,10 @@
 from __future__ import unicode_literals
 from __future__ import unicode_literals
 
 
 from django.contrib import admin
 from django.contrib import admin
+from django.db.models import Q
 from polymorphic.admin import PolymorphicChildModelAdmin
 from polymorphic.admin import PolymorphicChildModelAdmin
 
 
+from coin.members.models import RowLevelPermission
 from coin.offers.models import Offer, OfferSubscription
 from coin.offers.models import Offer, OfferSubscription
 from coin.offers.offersubscription_filter import\
 from coin.offers.offersubscription_filter import\
             OfferSubscriptionTerminationFilter,\
             OfferSubscriptionTerminationFilter,\
@@ -36,7 +38,7 @@ class OfferSubscriptionAdmin(admin.ModelAdmin):
                     'offer', 'member')
                     'offer', 'member')
     search_fields = ['member__first_name', 'member__last_name', 'member__email',
     search_fields = ['member__first_name', 'member__last_name', 'member__email',
                      'member__nickname']
                      'member__nickname']
-    
+
     fields = (
     fields = (
                 'member',
                 'member',
                 'offer',
                 'offer',
@@ -47,6 +49,14 @@ class OfferSubscriptionAdmin(admin.ModelAdmin):
              )
              )
     form = autocomplete_light.modelform_factory(OfferSubscription, fields='__all__')
     form = autocomplete_light.modelform_factory(OfferSubscription, fields='__all__')
 
 
+    def get_queryset(self, request):
+        qs = super(OfferSubscriptionAdmin, self).get_queryset(request)
+        if request.user.is_superuser:
+            return qs
+        else:
+            offers = RowLevelPermission.get_manageable_offers(request.user)
+            return qs.filter(offer__in=offers)
+
     def get_inline_instances(self, request, obj=None):
     def get_inline_instances(self, request, obj=None):
         """
         """
         Si en edition, alors affiche en inline le formulaire de la configuration
         Si en edition, alors affiche en inline le formulaire de la configuration