models/program: link to editor groups
This commit is contained in:
parent
92f9a08856
commit
b0afa0fd86
25
aircox/migrations/0015_program_editors.py
Normal file
25
aircox/migrations/0015_program_editors.py
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
# Generated by Django 4.2.5 on 2023-10-18 13:50
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("auth", "0012_alter_user_first_name_max_length"),
|
||||||
|
("aircox", "0014_alter_schedule_timezone"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="program",
|
||||||
|
name="editors",
|
||||||
|
field=models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
to="auth.group",
|
||||||
|
verbose_name="editors",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
|
@ -3,6 +3,8 @@ import os
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
from django.conf import settings as conf
|
from django.conf import settings as conf
|
||||||
|
from django.contrib.auth.models import Group, Permission
|
||||||
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import F
|
from django.db.models import F
|
||||||
from django.db.models.functions import Concat, Substr
|
from django.db.models.functions import Concat, Substr
|
||||||
|
@ -58,6 +60,7 @@ class Program(Page):
|
||||||
default=True,
|
default=True,
|
||||||
help_text=_("update later diffusions according to schedule changes"),
|
help_text=_("update later diffusions according to schedule changes"),
|
||||||
)
|
)
|
||||||
|
editors = models.ForeignKey(Group, models.CASCADE, blank=True, null=True, verbose_name=_("editors"))
|
||||||
|
|
||||||
objects = ProgramQuerySet.as_manager()
|
objects = ProgramQuerySet.as_manager()
|
||||||
detail_url_name = "program-detail"
|
detail_url_name = "program-detail"
|
||||||
|
@ -80,6 +83,14 @@ class Program(Page):
|
||||||
def excerpts_path(self):
|
def excerpts_path(self):
|
||||||
return os.path.join(self.path, settings.SOUND_ARCHIVES_SUBDIR)
|
return os.path.join(self.path, settings.SOUND_ARCHIVES_SUBDIR)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def editors_group_name(self):
|
||||||
|
return f"{self.title} editors"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def change_permission_codename(self):
|
||||||
|
return f"change_program_{self.slug}"
|
||||||
|
|
||||||
def __init__(self, *kargs, **kwargs):
|
def __init__(self, *kargs, **kwargs):
|
||||||
super().__init__(*kargs, **kwargs)
|
super().__init__(*kargs, **kwargs)
|
||||||
if self.slug:
|
if self.slug:
|
||||||
|
@ -109,6 +120,18 @@ class Program(Page):
|
||||||
os.makedirs(path, exist_ok=True)
|
os.makedirs(path, exist_ok=True)
|
||||||
return os.path.exists(path)
|
return os.path.exists(path)
|
||||||
|
|
||||||
|
def set_group_ownership(self):
|
||||||
|
editors, created = Group.objects.get_or_create(name=self.editors_group_name)
|
||||||
|
if created:
|
||||||
|
self.editors = editors
|
||||||
|
permission, _ = Permission.objects.get_or_create(
|
||||||
|
name=f"change program {self.title}",
|
||||||
|
codename=self.change_permission_codename,
|
||||||
|
content_type=ContentType.objects.get_for_model(self),
|
||||||
|
)
|
||||||
|
if permission not in editors.permissions.all():
|
||||||
|
editors.permissions.add(permission)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("Program")
|
verbose_name = _("Program")
|
||||||
verbose_name_plural = _("Programs")
|
verbose_name_plural = _("Programs")
|
||||||
|
@ -134,6 +157,9 @@ class Program(Page):
|
||||||
shutil.move(abspath, self.abspath)
|
shutil.move(abspath, self.abspath)
|
||||||
Sound.objects.filter(path__startswith=path_).update(file=Concat("file", Substr(F("file"), len(path_))))
|
Sound.objects.filter(path__startswith=path_).update(file=Concat("file", Substr(F("file"), len(path_))))
|
||||||
|
|
||||||
|
self.set_group_ownership()
|
||||||
|
super().save(*kargs, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class ProgramChildQuerySet(PageQuerySet):
|
class ProgramChildQuerySet(PageQuerySet):
|
||||||
def station(self, station=None, id=None):
|
def station(self, station=None, id=None):
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import pytest
|
import pytest
|
||||||
|
from django.contrib.auth.models import User, Group
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db()
|
@pytest.mark.django_db()
|
||||||
|
@ -12,3 +13,13 @@ def test_no_admin(user, client):
|
||||||
def test_user_cannot_change_program_or_episode(user, client, program):
|
def test_user_cannot_change_program_or_episode(user, client, program):
|
||||||
assert not user.has_perm("aircox.change_program")
|
assert not user.has_perm("aircox.change_program")
|
||||||
assert not user.has_perm("aircox.change_episode")
|
assert not user.has_perm("aircox.change_episode")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db()
|
||||||
|
def test_group_can_change_program(user, client, program):
|
||||||
|
assert program.editors in Group.objects.all()
|
||||||
|
assert not user.has_perm("aircox.%s" % program.change_permission_codename)
|
||||||
|
user.groups.add(program.editors)
|
||||||
|
user = User.objects.get(pk=user.pk) # reload user in order to have permissions set
|
||||||
|
assert program.editors in user.groups.all()
|
||||||
|
assert user.has_perm("aircox.%s" % program.change_permission_codename)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user