diff --git a/docs/permissions-and-groups/groups/home-editors.md b/docs/permissions-and-groups/groups/home-editors.md new file mode 100644 index 000000000..55c3d737f --- /dev/null +++ b/docs/permissions-and-groups/groups/home-editors.md @@ -0,0 +1,28 @@ +# Home page editors + +Users in this group get the following permissions: + +## Global permissions + +- Can access Wagtail admin + +## User permissions + +- Can change home page content + +## Image permissions + +- Can add/edit/choose images belonging to the following collections: + - **Root** + +## Media permissions + +- Can add/edit images belonging to the following collections: + - **Root** + +## Collection management permissions + +!!! note + I think this permission makes the document/image/media permissions redundant. + +- Can add to the following collection **Root** diff --git a/src/content/management/commands/create_groups.py b/src/content/management/commands/create_groups.py index 9084c8afc..139c6be01 100644 --- a/src/content/management/commands/create_groups.py +++ b/src/content/management/commands/create_groups.py @@ -143,6 +143,18 @@ "unlock_page", ] +HOME_EDITORS_GROUP_NAME = "Home page editors" +HOME_EDITORS_ROOT_COLLECTION_PERMISSIONS = [ + "add_media", + "change_media", + "add_image", + "change_image", + "choose_image", +] +HOME_EDITORS_USER_PERMISSIONS = [ + "can_change_home_page_content", +] + class Command(BaseCommand): help = "Create page permissions" @@ -174,6 +186,26 @@ def grant_page_perms(self, group, page_type, permissions): ), ) + def home_page_permissions(self): + home_editors_group, _ = Group.objects.get_or_create( + name=HOME_EDITORS_GROUP_NAME + ) + self.grant_wagtail_admin_perm(home_editors_group) + + # Home page editors permissions + self.grant_group_collection_perms( + home_editors_group, + HOME_EDITORS_ROOT_COLLECTION_PERMISSIONS, + ) + + # Home page editors get the user permission to change the homepage content + home_editors_group.permissions.add( + Permission.objects.get( + codename="can_change_home_page_content", + content_type__app_label="home", + ) + ) + def event_permissions(self): event_creators_group, _ = Group.objects.get_or_create( name=EVENT_CREATORS_GROUP_NAME @@ -316,4 +348,5 @@ def handle(self, *args, **options): ) ) + self.home_page_permissions() self.event_permissions() diff --git a/src/home/migrations/0011_alter_homepage_options.py b/src/home/migrations/0011_alter_homepage_options.py new file mode 100644 index 000000000..b3f20a6a1 --- /dev/null +++ b/src/home/migrations/0011_alter_homepage_options.py @@ -0,0 +1,22 @@ +# Generated by Django 4.2.15 on 2024-09-12 14:38 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("home", "0010_homepage_priority_pages_layout"), + ] + + operations = [ + migrations.AlterModelOptions( + name="homepage", + options={ + "permissions": [ + ("can_change_home_page_content", "Can change home page content") + ], + "verbose_name": "Home page", + }, + ), + ] diff --git a/src/home/models.py b/src/home/models.py index c3f245707..6a4bb317d 100644 --- a/src/home/models.py +++ b/src/home/models.py @@ -12,6 +12,7 @@ from modelcluster.models import ClusterableModel from waffle import flag_is_active from wagtail.admin.panels import FieldPanel, InlinePanel, PageChooserPanel +from wagtail.models import PagePermissionTester from wagtail.snippets.models import register_snippet from wagtail_adminsortable.models import AdminSortable from wagtailorderable.models import Orderable @@ -379,3 +380,21 @@ def pages_by_news_layout(self, pages) -> Iterator[list[int]]: for n in self.PriorityPagesLayout(self.priority_pages_layout).to_page_counts(): yield [next(pages) for _ in range(n)] + + # Wagtail overrides + + def permissions_for_user(self, user): + return HomePagePermissionTester(user, self) + + class Meta: + verbose_name = "Home page" + permissions = [ + ("can_change_home_page_content", "Can change home page content"), + ] + + +class HomePagePermissionTester(PagePermissionTester): + def can_edit(self): + if self.user.has_perm("can_change_home_page_content"): + return True + return super().can_edit()