models/program: link to editor groups

This commit is contained in:
Chris Tactic 2023-10-18 15:44:47 +02:00
parent 92f9a08856
commit 0580ad2117
3 changed files with 62 additions and 0 deletions

View 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",
),
),
]

View File

@ -3,6 +3,8 @@ import os
import shutil
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.models import F
from django.db.models.functions import Concat, Substr
@ -58,6 +60,7 @@ class Program(Page):
default=True,
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()
detail_url_name = "program-detail"
@ -80,6 +83,14 @@ class Program(Page):
def excerpts_path(self):
return os.path.join(self.path, settings.SOUND_ARCHIVES_SUBDIR)
@property
def editors_group_name(self):
return "{self.title} editors"
@property
def change_permission_codename(self):
return f"change_program_{self.slug}"
def __init__(self, *kargs, **kwargs):
super().__init__(*kargs, **kwargs)
if self.slug:
@ -109,6 +120,18 @@ class Program(Page):
os.makedirs(path, exist_ok=True)
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:
verbose_name = _("Program")
verbose_name_plural = _("Programs")
@ -134,6 +157,9 @@ class Program(Page):
shutil.move(abspath, self.abspath)
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):
def station(self, station=None, id=None):

View File

@ -1,4 +1,5 @@
import pytest
from django.contrib.auth.models import User, Group
@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):
assert not user.has_perm("aircox.change_program")
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)