diff --git a/cof/admin.py b/cof/admin.py index 95ac77ed..eabb400c 100644 --- a/cof/admin.py +++ b/cof/admin.py @@ -1,9 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import division -from __future__ import print_function -from __future__ import unicode_literals - from django import forms from django.contrib import admin from django.utils.translation import ugettext_lazy as _ @@ -104,89 +100,29 @@ class EventAdmin(admin.ModelAdmin): ] -class CofProfileInline(admin.StackedInline): - model = CofProfile +class ProfileInline(admin.StackedInline): + model = Profile inline_classes = ("collapse open",) -class FkeyLookup(object): - def __init__(self, fkeydecl, short_description=None, - admin_order_field=None): - self.fk, fkattrs = fkeydecl.split('__', 1) - self.fkattrs = fkattrs.split('__') - - self.short_description = short_description or self.fkattrs[-1] - self.admin_order_field = admin_order_field or fkeydecl - - def __get__(self, obj, klass): - if obj is None: - """ - hack required to make Django validate (if obj is - None, then we're a class, and classes are callable - ) - """ - return self - item = getattr(obj, self.fk) - for attr in self.fkattrs: - item = getattr(item, attr) - return item - - -def ProfileInfo(field, short_description, boolean=False): - def getter(self): - try: - return getattr(self.profile, field) - except Profile.DoesNotExist: - return "" - getter.short_description = short_description - getter.boolean = boolean - return getter - -User.profile_login_clipper = FkeyLookup("profile__login_clipper", - "Login clipper") -User.profile_num = FkeyLookup("profile__cofprofile__num", - "Numéro") -User.profile_phone = ProfileInfo("phone", "Téléphone") -User.profile_occupation = ProfileInfo("occupation", "Occupation") -User.profile_departement = ProfileInfo("departement", "Departement") -User.profile_mailing_cof = ProfileInfo("cof__mailing", "ML COF", True) -User.profile_mailing_bda = ProfileInfo("cof__mailing_bda", "ML BdA", True) -User.profile_mailing_bda_revente = ProfileInfo("cof__mailing_bda_revente", - "ML BdA-R", True) - - class UserProfileAdmin(UserAdmin): - def is_buro(self, obj): - try: - return obj.profile.is_buro - except CofProfile.DoesNotExist: - return False - is_buro.short_description = 'Membre du Buro' - is_buro.boolean = True + def login_clipper(self, obj): + return obj.profile.login_clipper - def is_cof(self, obj): - try: - return obj.profile.is_cof - except CofProfile.DoesNotExist: - return False - is_cof.short_description = 'Membre du COF' - is_cof.boolean = True + def phone(self, obj): + return obj.profile.phone - list_display = ('profile_num',) + UserAdmin.list_display \ - + ('profile_login_clipper', 'profile_phone', 'profile_occupation', - 'profile_mailing_cof', 'profile_mailing_bda', - 'profile_mailing_bda_revente', 'is_buro', ) + def occupation(self, obj): + return obj.profile.occupation + + list_display = ( + UserAdmin.list_display + ('login_clipper', 'phone', 'occupation') + ) list_display_links = ('username', 'email', 'first_name', 'last_name') - list_filter = UserAdmin.list_filter \ - + ( - # 'profile__cof__is_cof', - 'profile__cof__is_buro', - 'profile__cof__mailing', - 'profile__cof__mailing_bda') - search_fields = UserAdmin.search_fields + ('profile__phone',) - # inlines = [ - # CofProfileInline, - # ] + search_fields = UserAdmin.search_fields + ('profile__phone', ) + inlines = [ + ProfileInline, + ] staff_fieldsets = [ (None, {'fields': ['username', 'password']}), diff --git a/cof/decorators.py b/cof/decorators.py index a7ced8f7..bfa1a6a2 100644 --- a/cof/decorators.py +++ b/cof/decorators.py @@ -1,29 +1,8 @@ # -*- coding: utf-8 -*- -from __future__ import division -from __future__ import print_function -from __future__ import unicode_literals +from django.contrib.auth.decorators import permission_required -from django_cas_ng.decorators import user_passes_test - - -def is_cof(user): - try: - cofprofile = user.profile.cof - return cofprofile.is_cof - except: - return False - -cof_required = user_passes_test(lambda u: is_cof(u)) -cof_required_customdenied = user_passes_test(lambda u: is_cof(u), - login_url="cof-denied") - - -def is_buro(user): - try: - cofprofile = user.profile.cof - return cofprofile.is_buro - except: - return False - -buro_required = user_passes_test(lambda u: is_buro(u)) +cof_required = permission_required('cof.member') +cof_required_customdenied = permission_required('cof.member', + login_url="cof-denied") +buro_required = permission_required('cof.buro') diff --git a/cof/forms.py b/cof/forms.py index 0b0ae5a8..eac9f2ed 100644 --- a/cof/forms.py +++ b/cof/forms.py @@ -222,7 +222,7 @@ class RegistrationCofProfileForm(forms.ModelForm): class Meta: model = CofProfile fields = [ - "num", "type_cotiz", "is_buro", + "num", "type_cotiz", "mailing", "mailing_bda", "mailing_bda_revente", ] diff --git a/cof/migrations/0009_generic_profiles.py b/cof/migrations/0009_generic_profiles.py index c3fb1c13..673202b8 100644 --- a/cof/migrations/0009_generic_profiles.py +++ b/cof/migrations/0009_generic_profiles.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals +from django.contrib.auth.models import Group, Permission from django.db import migrations, models @@ -21,9 +22,36 @@ def create_profile(apps, schema_editor): p.save() +def preserve_perms(apps, schema_editor): + from django.contrib.auth.management import create_permissions + + apps.models_module = True + create_permissions(apps, verbosity=0) + apps.models_module = None + + CofProfile = apps.get_model("cof", "CofProfile") + memberp = Permission.objects.get(codename='member') + burop = Permission.objects.get(codename='buro') + + # creates the groups for COF members and + member = Group.objects.create(name='cof_members') + buro = Group.objects.create(name='cof_buro') + + # associate permissions to the respective groups. + buro.permissions = [burop, memberp] + member.permissions = [memberp] + + for cofp in CofProfile.objects.filter(is_cof=True): + cofp.profile.user.groups.add(member) + for cofp in CofProfile.objects.filter(is_buro=True): + cofp.profile.user.groups.add(buro) + + def remove_profile(apps, schema_editor): raise NotImplementedError +fuckup_perms = remove_profile + class Migration(migrations.Migration): @@ -48,7 +76,23 @@ class Migration(migrations.Migration): ), preserve_default=False, ), + migrations.AlterModelOptions( + name='cofprofile', + options={ + 'permissions': (('member', 'Is a COF member'), + ('buro', 'Is part of COF staff')), + 'verbose_name': 'Profil COF', + 'verbose_name_plural': 'Profils COF'}, + ), migrations.RunPython(create_profile, remove_profile), + migrations.AlterField( + model_name='cofprofile', + name='profile', + field=models.OneToOneField( + to='gestion.Profile', + related_name='cof' + ), + ), migrations.RemoveField( model_name='cofprofile', name='comments', @@ -69,13 +113,14 @@ class Migration(migrations.Migration): model_name='cofprofile', name='phone', ), - migrations.AlterField( + migrations.RunPython(preserve_perms, fuckup_perms), + migrations.RemoveField( model_name='cofprofile', - name='profile', - field=models.OneToOneField( - to='gestion.Profile', - related_name='cof' - ), + name='is_cof', + ), + migrations.RemoveField( + model_name='cofprofile', + name='is_buro', ), migrations.RemoveField( model_name='cofprofile', diff --git a/cof/migrations/0011_create_cof_group.py b/cof/migrations/0010_create_cof_group.py similarity index 59% rename from cof/migrations/0011_create_cof_group.py rename to cof/migrations/0010_create_cof_group.py index 6c93a137..f2ce104a 100644 --- a/cof/migrations/0011_create_cof_group.py +++ b/cof/migrations/0010_create_cof_group.py @@ -9,12 +9,18 @@ def create_cof_group(apps, schema_editor): Group.objects.get_or_create(name="cof_members") +def create_buro_group(apps, schema_editor): + Group = apps.get_model("auth", "Group") + Group.objects.get_or_create(name="cof_buro") + + class Migration(migrations.Migration): dependencies = [ - ('cof', '0010_remove_cofprofile_is_cof'), + ('cof', '0009_generic_profiles'), ] operations = [ - migrations.RunPython(create_cof_group, migrations.RunPython.noop) + migrations.RunPython(create_cof_group, migrations.RunPython.noop), + migrations.RunPython(create_buro_group, migrations.RunPython.noop), ] diff --git a/cof/migrations/0010_remove_cofprofile_is_cof.py b/cof/migrations/0011_delete_clipper_and_custommail.py similarity index 54% rename from cof/migrations/0010_remove_cofprofile_is_cof.py rename to cof/migrations/0011_delete_clipper_and_custommail.py index 13bbc2ec..92ff4d40 100644 --- a/cof/migrations/0010_remove_cofprofile_is_cof.py +++ b/cof/migrations/0011_delete_clipper_and_custommail.py @@ -7,12 +7,14 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('cof', '0009_generic_profiles'), + ('cof', '0010_create_cof_group'), ] operations = [ - migrations.RemoveField( - model_name='cofprofile', - name='is_cof', + migrations.DeleteModel( + name='Clipper', + ), + migrations.DeleteModel( + name='CustomMail', ), ] diff --git a/cof/models.py b/cof/models.py index 06e6b073..3db48091 100644 --- a/cof/models.py +++ b/cof/models.py @@ -35,8 +35,6 @@ class CofProfile(models.Model): max_length=choices_length( TYPE_COTIZ_CHOICES)) mailing = models.BooleanField("Recevoir les mails COF", default=False) - # XXX. remove the following and use django auth. - is_buro = models.BooleanField("Membre du Burô", default=False) # XXX. remove the following and put in a BDA profile mailing_bda = models.BooleanField("Recevoir les mails BdA", default=False) mailing_bda_revente = models.BooleanField( @@ -48,9 +46,17 @@ class CofProfile(models.Model): _("Remarques et précisions pour les petits cours"), blank=True, default="") - # is_cof = models.BooleanField("Membre du COF", default=False) + class Meta: + verbose_name = "Profil COF" + verbose_name_plural = "Profils COF" + permissions = ( + ('member', 'Is a COF member'), + ('buro', 'Is part of COF staff'), + ) + @property def is_cof(self): + print("Coucou") return self.profile.user.has_perm('cof.member') @is_cof.setter @@ -59,9 +65,16 @@ class CofProfile(models.Model): g = Group.objects.get(name='cof_members') self.profile.user.groups.add(g) - class Meta: - verbose_name = "Profil COF" - verbose_name_plural = "Profils COF" + # XXX. remove the following and use django auth. + @property + def is_buro(self): + return self.profile.user.has_perm('cof.buro') + + @is_buro.setter + def is_buro(self, really): + if really: + g = Group.objects.get(name='cof_buro') + self.profile.user.groups.add(g) def __str__(self): return self.profile.user.username diff --git a/cof/tests.py b/cof/tests.py index 15106223..0f5a89e8 100644 --- a/cof/tests.py +++ b/cof/tests.py @@ -6,30 +6,20 @@ from cof.models import CofProfile from gestion.tests import create_profile + def create_cofprofile(username): p = create_profile(username) return CofProfile.objects.create(profile=p) + class TestCofProfile(TestCase): def test_str(self): - # creates a group of cof members - group = Group.objects.create(name='cof_members') - - # create a specific permission for all COF members. - ct = ContentType.objects.get(app_label='cof', model='CofProfile') - perm = Permission.objects.create(name='Cof Member', - codename='member', - content_type=ct) - - # bind the two mutherfucker. - group.permissions = [perm] - - # now test it for real cofp = create_cofprofile('foo') # XXX. should by default new CofProfiles be COF members? self.assertFalse(cofp.profile.user.has_perm('cof.member')) # adding/removing a user from the group should impact the # permission + group = Group.objects.get(name='cof_members') cofp.profile.user.groups.add(group) cofp.save() diff --git a/cof/views.py b/cof/views.py index e8567c58..e1c0e394 100644 --- a/cof/views.py +++ b/cof/views.py @@ -532,7 +532,7 @@ def export_members(request): response['Content-Disposition'] = 'attachment; filename=membres_cof.csv' writer = unicodecsv.writer(response) - for profile in CofProfile.objects.filter(is_cof=True).all(): + for profile in CofProfile.objects.filter(profile__user__groups__name='cof_members').all(): user = profile.user bits = [profile.num, user.username, user.first_name, user.last_name, user.email, profile.phone, profile.occupation, @@ -641,7 +641,7 @@ def utile_bda(request): @buro_required def liste_bdadiff(request): titre = "BdA diffusion" - personnes = CofProfile.objects.filter(mailing_bda=True, is_cof=True).all() + personnes = CofProfile.objects.filter(mailing_bda=True, profile__user__groups__name='cof_members').all() return render(request, "liste_mails.html", {"titre": titre, "personnes": personnes}) @@ -650,7 +650,7 @@ def liste_bdadiff(request): def liste_bdarevente(request): titre = "BdA revente" personnes = CofProfile.objects.filter(mailing_bda_revente=True, - is_cof=True).all() + profile__user__groups__name='cof_members').all() return render(request, "liste_mails.html", {"titre": titre, "personnes": personnes}) @@ -658,7 +658,7 @@ def liste_bdarevente(request): @buro_required def liste_diffcof(request): titre = "Diffusion COF" - personnes = CofProfile.objects.filter(mailing_cof=True, is_cof=True).all() + personnes = CofProfile.objects.filter(mailing_cof=True, user__groups__name='cof_members').all() return render(request, "liste_mails.html", {"titre": titre, "personnes": personnes})