configurationyamlgrav

How do I add a custom permission for a custom configuration area to the Grav admin plugin so the menu point is shown in backend?


I have a custom config tab in a Grav CMS installation:

user/blueprints/config/content.yaml

title: 'My Title'
form:
  validation: loose
  fields:
    images:
      type: section
      title: 'Images'
      underline: true

      fields:
      # Content fields 

It does what it is supposed to do. Now I would like to restrict access to this tab to users with a specific permission (admin.configuration.content: true). Since the admin plugin does not seem to show custom configuration areas in the permission tree, I went to the user.yaml file and entered it there:

access:
  site:
    login: true
  admin:
    login: true
    cache: true
    configuration:
      content: true # this line and the one before added manually

This does not show the configuration in the menu on the left. It does show, once I additionally add one of the standard configuration tabs, e.g. site: true or info: true.

access:
  site:
    login: true
  admin:
    login: true
    cache: true
    configuration:
      site: true # now I see both configuration tabs, site and content
      content: true

Am I missing something? I discussed with a GPT that claimed it was possible to get custom user permissions or should work, but the generated examples went nowhere. Same for the documentation. It seems outdated: https://learn.getgrav.org/17/admin-panel/faq#managing-acl

I also tried to use the permission definition syntax from flex-objects just to see if it does anything, but to no avail:

title: 'My Title'

config:
  admin:
    permissions:
      admin.content:
        type: crudpl
        label: 'Content'

form:
  validation: loose
  fields:
    images:
      type: section
      title: 'Images'
      underline: true

      fields:
      # Content fields 

Is there a place I need to add the custom permission, so the system recognises it and it becomes usable? Worst case I will allow info and content, but I would prefer a cleaner solution.

Edit: Updated title to better describe the problem.


Solution

  • Understanding the problem

    The configuration area of a Grav CMS backend is generated by the admin plugin. The menu items are hard coded and do not support custom permissions as of yet. This leads to not seeing the tab, even though the permission is set correctly (and the user can access the configuration if he has the link).

    Grav CMS Configuration Menu entry

    Bad Solution

    In order to add a custom permission that allows us to show a custom tab in the configuration section, it is possible to change the admin plugin as follows (possible, but a bad idea, gets overwritten on every update). Looking at these files first helps to understand the mechanisms.

    user/plugins/admin/permissions.yaml

    # shortened example
    actions:
      
      admin:
        actions:
          configuration:
            actions:
              content: # Add your custom permission here, don't remove anything from the file
                label: 'Manage Content Configuration'
    

    user/plugins/admin/admin.php

    public function onAdminMenu()
        {
            /** @var Twig $twig */
            $twig = $this->grav['twig'];
    
            // shortened
    
            // Configuration
            $twig->plugins_hooked_nav['PLUGIN_ADMIN.CONFIGURATION'] = [
                'route' => 'config',
                'icon' => 'fa-wrench',
                'authorize' => [
                    'admin.configuration.system',
                    'admin.configuration.site',
                    'admin.configuration.media',
                    'admin.configuration.security',
                    'admin.configuration.info',
                    'admin.configuration.content', #add your menu item here
                    'admin.super'],
                'priority' => 9
            ];
    

    Better Solution

    1. Create a custom plugin.
    2. Copy the user/plugins/admin/permissions.yaml into your custom plugin and shorten it to the custom permission you need:
       actions:
         admin:
           actions:
             configuration:
               actions:
                 content:
                   label: 'Manage Content Configuration'
    
    1. Use the PermissionRegisterEvent from the Grav core to register the event and add it to the menu:
       // use the PermissionRegisterEvent
       public static function getSubscribedEvents(): array {
           return [
               'onPluginsInitialized' => [
                   ['onPluginsInitialized', 0]
               ],
               PermissionsRegisterEvent::class => ['onRegisterPermissions', 1000],
           ];
       }
    
       // enable the onAdminMenu-hook
       public function onPluginsInitialized(): void
       {
           // Enable the main events we are interested in
           $this->enable([
               'onAdminMenu'               => ['onAdminMenu', 1000]
           ]);
       }
    
       // extend (left join) the permissions from the admin plugin with your own
       public function onRegisterPermissions(PermissionsRegisterEvent $event): void {
           $actionsAdmin   = PermissionsReader::fromYaml("plugin://admin/permissions.yaml");
           $actionsCustom  = PermissionsReader::fromYaml("plugin://{$this->name}/permissions.yaml");
           $actions        = $actionsAdmin + $actionsCustom;
    
           $permissions = $event->permissions;
           $permissions->addActions($actions);
       }
    
       // extend the admin menu with your custom permission
       public function onAdminMenu() {
           /** @var Twig $twig */
           $twig = $this->grav['twig'];
    
           // Configuration
           $twig->plugins_hooked_nav['PLUGIN_ADMIN.CONFIGURATION']['authorize'][] = 'admin.configuration.content';
       }