Permissions in GridField

Silverstripe Version: 4.2

Do GridFields respect permissions?

I’ve been creating Permissions for a couple of DataObjects I’m using. The objects are part of a 1 to many relationship, which are editable via a GridField. I’ve tried this when the GridField is added to a Page & when managed via ModelAdmin.

It appears to me that although the objects themselves are respecting permissions (e.g. if I have View permissions, but no edit, I can’t edit the Object when I’m looking at it via the edit screen), the GridField’s actions are not respecting them.

I end up getting the edit & unlink actions being made available to each row in the GridField.

My Permissions look similar to this:

public function providePermissions()
    {
        return [
            'VIEW_CAROUSEL_ITEM' => [
                'name' => 'View a Carousel Item',
                'category' => 'Carousel'
            ],
            'EDIT_CAROUSEL_ITEM' => [
                'name' => 'Edit a Carousel Item',
                'category' => 'Carousel'
            ],
            'DELETE_CAROUSEL_ITEM' => [
                'name' => 'Delete a Carousel Item',
                'category' => 'Carousel'
            ],
            'CREATE_CAROUSEL_ITEM' => [
                'name' => 'Create a Carousel Item',
                'category' => 'Carousel'
            ],
            'PUBLISH_CAROUSEL_ITEM' => [
                'name' => 'Publish a Carousel Item',
                'category' => 'Carousel'
            ],
            'UNPUBLISH_CAROUSEL_ITEM' => [
                'name' => 'Unpublish a Carousel Item',
                'category' => 'Carousel'
            ],
            'ARCHIVE_CAROUSEL_ITEM' => [
                'name' => 'Archive a Carousel Item',
                'category' => 'Carousel'
            ],
        ];
    }

    public function canView($member = null)
    {
        return $this->can('view', $member);
    }
    ...

I then have to manually modify the GridField config like so:

if (!Permission::check('DELETE_CAROUSEL_ITEM')) {
    $config
        ->removeComponentsByType(GridFieldDeleteAction::class);
}

Is there something I’m missing here? Is there an option like private static $versioned_gridfield_extensions = true; that has to be added to the DataObject?

On further inspection, it appears that if the delete action is set to not remove the relation (i.e. delete & not simply unlink), then delete is applied.

It simply means the delete action of the grid config needs to be updated to respect that.

I can see use cases where an admin user should have edit permissions, but not “unlink” permissions. Would having an “unlink” permission as a global concept be a helpful thing? Ideally I don’t want to have to rewrite the GridFieldDeleteAction just to control the Unlink permission.