forked from DGNum/gestioCOF
Merge branch 'Kerl/supportBDS/migrations' into 'aureplop/supportBDS/migrations'
Kerl/support bds/migrations - merge supportBDS - rajoute des classes `Meta` disparues et autres renommages See merge request !266
This commit is contained in:
commit
5621c6f81e
9 changed files with 193 additions and 68 deletions
40
bds/apps.py
40
bds/apps.py
|
@ -1,36 +1,22 @@
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
from django.db.models.signals import post_migrate
|
from django.db.models.signals import post_migrate
|
||||||
|
|
||||||
|
from gestion.apps import setup_assoc_perms
|
||||||
def setup_groups(sender, apps, **kwargs):
|
|
||||||
"""
|
|
||||||
Add the appropriate permissions to the "member" and "buro" groups after the
|
|
||||||
`post_migrate` signal since the permissions will only be inserted in the
|
|
||||||
database at the very end of the migrations.
|
|
||||||
"""
|
|
||||||
Group = apps.get_model("auth", "Group")
|
|
||||||
Permission = apps.get_model("auth", "Permission")
|
|
||||||
|
|
||||||
# Buro members have perms bds.* and gestion.*
|
|
||||||
buro, _ = Group.objects.get_or_create(name="bds_buro")
|
|
||||||
app_perms = Permission.objects.filter(
|
|
||||||
content_type__app_label__in=["cof", "gestion"]
|
|
||||||
)
|
|
||||||
buro.permissions.add(*app_perms)
|
|
||||||
|
|
||||||
# Members have perm bds.member
|
|
||||||
members, _ = Group.objects.get_or_create(name="bds_members")
|
|
||||||
perm = Permission.objects.get(
|
|
||||||
codename="member",
|
|
||||||
content_type__app_label="bds"
|
|
||||||
)
|
|
||||||
members.permissions.add(perm)
|
|
||||||
|
|
||||||
|
|
||||||
class BDSConfig(AppConfig):
|
class BDSConfig(AppConfig):
|
||||||
name = "bds"
|
name = "bds"
|
||||||
verbose_name = "Application de gestion du BDS"
|
verbose_name = "Application de gestion du BDS"
|
||||||
|
|
||||||
def ready(self):
|
|
||||||
# https://docs.djangoproject.com/en/1.11/ref/signals/#post-migrate
|
def setup_bds_perms(sender, apps, **kwargs):
|
||||||
post_migrate.connect(setup_groups, sender=self)
|
from bds.models import get_bds_assoc
|
||||||
|
setup_assoc_perms(
|
||||||
|
apps, get_bds_assoc,
|
||||||
|
buro_of_apps=['gestion', 'bds'],
|
||||||
|
perms=["custommail.add_custommail", "custommail.change_custommail"]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Setup permissions of defaults groups of BDS association after Permission
|
||||||
|
# instances have been created, i.e. after applying migrations.
|
||||||
|
post_migrate.connect(setup_bds_perms)
|
||||||
|
|
|
@ -3,7 +3,11 @@ import os.path
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
from gestion.models import Profile
|
from gestion.models import Association, Profile
|
||||||
|
|
||||||
|
|
||||||
|
def get_bds_assoc():
|
||||||
|
return Association.objects.get(name='BDS')
|
||||||
|
|
||||||
|
|
||||||
class BdsProfile(models.Model):
|
class BdsProfile(models.Model):
|
||||||
|
|
40
cof/apps.py
40
cof/apps.py
|
@ -1,36 +1,22 @@
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
from django.db.models.signals import post_migrate
|
from django.db.models.signals import post_migrate
|
||||||
|
|
||||||
|
from gestion.apps import setup_assoc_perms
|
||||||
def setup_groups(sender, apps, **kwargs):
|
|
||||||
"""
|
|
||||||
Add the appropriate permissions to the "member" and "buro" groups after the
|
|
||||||
`post_migrate` signal since the permissions will only be inserted in the
|
|
||||||
database at the very end of the migrations.
|
|
||||||
"""
|
|
||||||
Group = apps.get_model("auth", "Group")
|
|
||||||
Permission = apps.get_model("auth", "Permission")
|
|
||||||
|
|
||||||
# Buro members have perms cof.* and gestion.*
|
|
||||||
buro, _ = Group.objects.get_or_create(name="cof_buro")
|
|
||||||
app_perms = Permission.objects.filter(
|
|
||||||
content_type__app_label__in=["cof", "gestion"]
|
|
||||||
)
|
|
||||||
buro.permissions.add(*app_perms)
|
|
||||||
|
|
||||||
# Members have perm cof.member
|
|
||||||
members, _ = Group.objects.get_or_create(name="cof_members")
|
|
||||||
perm = Permission.objects.get(
|
|
||||||
codename="member",
|
|
||||||
content_type__app_label="cof"
|
|
||||||
)
|
|
||||||
members.permissions.add(perm)
|
|
||||||
|
|
||||||
|
|
||||||
class COFConfig(AppConfig):
|
class COFConfig(AppConfig):
|
||||||
name = "cof"
|
name = "cof"
|
||||||
verbose_name = "Application de gestion du COF"
|
verbose_name = "Application de gestion du COF"
|
||||||
|
|
||||||
def ready(self):
|
|
||||||
# https://docs.djangoproject.com/en/1.11/ref/signals/#post-migrate
|
def setup_cof_perms(sender, apps, **kwargs):
|
||||||
post_migrate.connect(setup_groups, sender=self)
|
from cof.models import get_cof_assoc
|
||||||
|
setup_assoc_perms(
|
||||||
|
apps, get_cof_assoc,
|
||||||
|
buro_of_apps=['gestion', 'cof'],
|
||||||
|
perms=["custommail.add_custommail", "custommail.change_custommail"]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Setup permissions of defaults groups of BDS association after Permission
|
||||||
|
# instances have been created, i.e. after applying migrations.
|
||||||
|
post_migrate.connect(setup_cof_perms)
|
||||||
|
|
|
@ -6,11 +6,16 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
from django.utils.encoding import python_2_unicode_compatible
|
||||||
import django.utils.six as six
|
import django.utils.six as six
|
||||||
|
|
||||||
from gestion.models import Profile
|
from gestion.models import Association, Profile
|
||||||
from bda.models import Spectacle
|
from bda.models import Spectacle
|
||||||
|
|
||||||
from .petits_cours_models import choices_length
|
from .petits_cours_models import choices_length
|
||||||
|
|
||||||
|
|
||||||
|
def get_cof_assoc():
|
||||||
|
return Association.objects.get(name='COF')
|
||||||
|
|
||||||
|
|
||||||
TYPE_COTIZ_CHOICES = (
|
TYPE_COTIZ_CHOICES = (
|
||||||
('etudiant', _("Normalien étudiant")),
|
('etudiant', _("Normalien étudiant")),
|
||||||
('normalien', _("Normalien élève")),
|
('normalien', _("Normalien élève")),
|
||||||
|
|
1
cof/settings/secret.py
Symbolic link
1
cof/settings/secret.py
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
secret_example.py
|
|
@ -4,3 +4,14 @@ from django.apps import AppConfig
|
||||||
class GestionConfig(AppConfig):
|
class GestionConfig(AppConfig):
|
||||||
name = "gestion"
|
name = "gestion"
|
||||||
verbose_name = "Gestion des outils communs COF/BDS"
|
verbose_name = "Gestion des outils communs COF/BDS"
|
||||||
|
|
||||||
|
|
||||||
|
def setup_assoc_perms(apps, assoc_getter, buro_of_apps=[], perms=[]):
|
||||||
|
try:
|
||||||
|
# Association and Permission models are required to be ready to setup
|
||||||
|
# perms.
|
||||||
|
apps.get_app_config('gestion')
|
||||||
|
apps.get_app_config('auth')
|
||||||
|
except LookupError:
|
||||||
|
return
|
||||||
|
assoc_getter().setup_perms(buro_of_apps=buro_of_apps, perms=perms)
|
||||||
|
|
|
@ -54,8 +54,8 @@ class Migration(migrations.Migration):
|
||||||
('id', models.AutoField(primary_key=True, verbose_name='ID', auto_created=True, serialize=False)),
|
('id', models.AutoField(primary_key=True, verbose_name='ID', auto_created=True, serialize=False)),
|
||||||
('name', models.CharField(unique=True, max_length=200, verbose_name='nom')),
|
('name', models.CharField(unique=True, max_length=200, verbose_name='nom')),
|
||||||
('description', models.TextField(verbose_name='description', blank=True)),
|
('description', models.TextField(verbose_name='description', blank=True)),
|
||||||
('cotiz_price', models.DecimalField(verbose_name='cotisation (€)', decimal_places=2, default=0, blank=True, max_digits=5)),
|
('price', models.DecimalField(verbose_name='cotisation (€)', decimal_places=2, default=0, blank=True, max_digits=5)),
|
||||||
('cotiz_frequency', models.CharField(choices=[('ANN', 'Annuelle'), ('SEM', 'Semestrielle'), ('COU', 'Au cours')], max_length=3, verbose_name='fréquence de la cotisation', default='ANN', blank=True)),
|
('cotisation_frequency', models.CharField(choices=[('ANN', 'Annuel'), ('SEM', 'Semestriel'), ('COU', 'Au cours')], max_length=3, verbose_name='fréquence de la cotisation', default='ANN', blank=True)),
|
||||||
('association', models.ForeignKey(on_delete=models.deletion.PROTECT, related_name='clubs', to='gestion.Association', verbose_name='association')),
|
('association', models.ForeignKey(on_delete=models.deletion.PROTECT, related_name='clubs', to='gestion.Association', verbose_name='association')),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
|
@ -84,7 +84,13 @@ class Migration(migrations.Migration):
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='club',
|
model_name='club',
|
||||||
name='members',
|
name='members',
|
||||||
field=models.ManyToManyField(to=settings.AUTH_USER_MODEL, related_name='in_clubs', through='gestion.ClubUser', blank=True, verbose_name='membres'),
|
field=models.ManyToManyField(
|
||||||
|
to=settings.AUTH_USER_MODEL,
|
||||||
|
related_name='in_clubs',
|
||||||
|
through='gestion.ClubUser',
|
||||||
|
blank=True,
|
||||||
|
verbose_name='membres du club'
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Event',
|
name='Event',
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from django.contrib.auth.models import User, Group
|
from django.contrib.auth.models import Group, Permission, User
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.db.models.signals import post_delete, post_save
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from django.db.models.signals import post_save, post_delete
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
@ -105,6 +105,55 @@ class Association(models.Model):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
def setup_perms(self, buro_of_apps=[], perms=[]):
|
||||||
|
"""
|
||||||
|
Setup permissions of the staff and members groups.
|
||||||
|
|
||||||
|
Permission '<assoc_label>.member' is added to the 'members_group' of
|
||||||
|
the association.
|
||||||
|
|
||||||
|
Permission '<assoc_label>.buro' is added to the 'staff_group' of the
|
||||||
|
association. All permissions of applications from 'buro_of_apps' are
|
||||||
|
also added to this group.
|
||||||
|
|
||||||
|
Arguments
|
||||||
|
buro_of_apps (list of 'app_label', optional)
|
||||||
|
perms (list of permission codes, optional)
|
||||||
|
|
||||||
|
Should be used in receiver of 'post_migrate' signal, after permissions
|
||||||
|
creation.
|
||||||
|
|
||||||
|
"""
|
||||||
|
def try_add_perm(group, app_label, codename):
|
||||||
|
try:
|
||||||
|
perm = Permission.objects.get(
|
||||||
|
content_type__app_label=app_label,
|
||||||
|
codename=codename,
|
||||||
|
)
|
||||||
|
except Permission.DoesNotExist:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
group.permissions.add(perm)
|
||||||
|
|
||||||
|
assoc_app_label = self.name.lower()
|
||||||
|
|
||||||
|
# Buro group has perm '<assoc>.buro'.
|
||||||
|
try_add_perm(self.staff_group, assoc_app_label, 'buro')
|
||||||
|
|
||||||
|
# Add all permissions of applications given 'buro_of_apps'.
|
||||||
|
apps_perms = Permission.objects.filter(
|
||||||
|
content_type__app_label__in=buro_of_apps,
|
||||||
|
)
|
||||||
|
self.staff_group.permissions.add(*apps_perms)
|
||||||
|
|
||||||
|
# Add extra permissions from 'perms'
|
||||||
|
for perm in perms:
|
||||||
|
app_label, codename = perm.split('.', maxsplit=1)
|
||||||
|
try_add_perm(self.staff_group, app_label, codename)
|
||||||
|
|
||||||
|
# Members have perm '<assoc>.member'.
|
||||||
|
try_add_perm(self.members_group, assoc_app_label, 'member')
|
||||||
|
|
||||||
|
|
||||||
# ---
|
# ---
|
||||||
# Clubs
|
# Clubs
|
||||||
|
@ -151,6 +200,10 @@ class Club(models.Model):
|
||||||
blank=True
|
blank=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _("club")
|
||||||
|
verbose_name_plural = _("clubs")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
template = (
|
template = (
|
||||||
self.needs_cotiz and
|
self.needs_cotiz and
|
||||||
|
@ -176,6 +229,10 @@ class ClubUser(models.Model):
|
||||||
is_respo = models.BooleanField(_("est responsable du club"))
|
is_respo = models.BooleanField(_("est responsable du club"))
|
||||||
has_paid = models.BooleanField(_("a payé sa cotisation"))
|
has_paid = models.BooleanField(_("a payé sa cotisation"))
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _("inscription au club")
|
||||||
|
verbose_name_plural = _("inscriptions aux clubs")
|
||||||
|
|
||||||
|
|
||||||
# ---
|
# ---
|
||||||
# Events
|
# Events
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
|
||||||
This file demonstrates writing tests using the unittest module. These will pass
|
|
||||||
when you run "manage.py test".
|
|
||||||
|
|
||||||
Replace this with more appropriate tests for your application.
|
|
||||||
"""
|
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
|
from django.contrib.auth.models import Permission
|
||||||
from django.db.utils import IntegrityError
|
from django.db.utils import IntegrityError
|
||||||
from django.test import Client, TestCase
|
from django.test import Client, TestCase
|
||||||
|
|
||||||
from gestion.models import Profile, User
|
from bds.models import get_bds_assoc
|
||||||
|
from cof.models import get_cof_assoc
|
||||||
|
|
||||||
|
from .models import Profile
|
||||||
|
|
||||||
|
|
||||||
|
User = get_user_model()
|
||||||
|
|
||||||
|
|
||||||
def create_profile(username):
|
def create_profile(username):
|
||||||
|
@ -120,3 +122,70 @@ class AuthTest(TestCase):
|
||||||
resp.url.split('?')[0],
|
resp.url.split('?')[0],
|
||||||
"https://cas.eleves.ens.fr/login"
|
"https://cas.eleves.ens.fr/login"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AssociationTests(TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.custommail_p = Permission.objects.filter(
|
||||||
|
content_type__app_label="custommail",
|
||||||
|
codename__in=["add_custommail", "change_custommail"]
|
||||||
|
)
|
||||||
|
|
||||||
|
def assertAllAppPerms(self, group, app_label):
|
||||||
|
group_p = group.permissions.all()
|
||||||
|
app_p = Permission.objects.filter(
|
||||||
|
content_type__app_label=app_label,
|
||||||
|
)
|
||||||
|
for perm in app_p:
|
||||||
|
self.assertIn(perm, group_p)
|
||||||
|
|
||||||
|
def test_cof_assoc(self):
|
||||||
|
cof_assoc = get_cof_assoc()
|
||||||
|
|
||||||
|
# Check cof buro group has 'cof.buro' permission.
|
||||||
|
buro_perm = Permission.objects.get(
|
||||||
|
content_type__app_label='cof',
|
||||||
|
codename='buro',
|
||||||
|
)
|
||||||
|
self.assertIn(buro_perm, cof_assoc.staff_group.permissions.all())
|
||||||
|
|
||||||
|
# Check cof buro group has all permissions of 'gestion' and 'cof' apps.
|
||||||
|
self.assertAllAppPerms(cof_assoc.staff_group, 'cof')
|
||||||
|
self.assertAllAppPerms(cof_assoc.staff_group, 'gestion')
|
||||||
|
|
||||||
|
# + some permissions in custommail
|
||||||
|
for p in self.custommail_p:
|
||||||
|
self.assertIn(p, cof_assoc.staff_group.permissions.all())
|
||||||
|
|
||||||
|
# Check cof members group has 'cof.member' permission.
|
||||||
|
member_perm = Permission.objects.get(
|
||||||
|
content_type__app_label='cof',
|
||||||
|
codename='member',
|
||||||
|
)
|
||||||
|
self.assertIn(member_perm, cof_assoc.members_group.permissions.all())
|
||||||
|
|
||||||
|
def test_bds_assoc(self):
|
||||||
|
bds_assoc = get_bds_assoc()
|
||||||
|
|
||||||
|
# Check cof buro group has 'bds.buro' permission.
|
||||||
|
buro_perm = Permission.objects.get(
|
||||||
|
content_type__app_label='bds',
|
||||||
|
codename='buro',
|
||||||
|
)
|
||||||
|
self.assertIn(buro_perm, bds_assoc.staff_group.permissions.all())
|
||||||
|
|
||||||
|
# Check bds buro group has all permissions of 'gestion' and 'bds' apps.
|
||||||
|
self.assertAllAppPerms(bds_assoc.staff_group, 'bds')
|
||||||
|
self.assertAllAppPerms(bds_assoc.staff_group, 'gestion')
|
||||||
|
|
||||||
|
# + some permissions in custommail
|
||||||
|
for p in self.custommail_p:
|
||||||
|
self.assertIn(p, bds_assoc.staff_group.permissions.all())
|
||||||
|
|
||||||
|
# Check cof members group has 'bds.member' permission.
|
||||||
|
member_perm = Permission.objects.get(
|
||||||
|
content_type__app_label='bds',
|
||||||
|
codename='member',
|
||||||
|
)
|
||||||
|
self.assertIn(member_perm, bds_assoc.members_group.permissions.all())
|
||||||
|
|
Loading…
Reference in a new issue