Overriding permissions selectively via settings.php/settings.local.php

by Cottser   Last Updated January 11, 2019 11:07 AM

The use case is a development module that you would only have installed on a local environment.

My thought was to use $config in settings.php to do this:

$config['user.role.anonymous']['permissions'][] = 'use browsersync';
$config['user.role.authenticated']['permissions'][] = 'use browsersync';

When doing this everything looks good in the permissions UI but in practice the permissions seem to be clobbered and permissions like 'access content' are no longer enabled for these users.



Answers 2


I'm not sure I completely understand your use case, but think https://www.drupal.org/project/secure_permissions will work for you. It doesn't manage permissions in the settings.php. Instead it allows you to export permission to a hook that can be implemented across several modules. We have a module called cu_debug_admin_bundle that enables devel, disables a few caching related modules. and sets a number of variables for local testing. The module also sets the permission so that devel output is visible to users with specific roles. Ideally that module isn't even deployed to production.

 /**
 * Define site permissions in code.
 *
 * Create a secure_permissions_data module directory and place this function
 * in secure_permissions_data.module.
 *
 * @param $role
 *   The role for which the permissions are being requested.
 *
 * @return
 *   An array defining all the permissions for the site.
 */

function cu_debug_admin_bundle_secure_permissions($role) {
  $permissions = array(
    'developer' => array(
      'access devel information',
      'access security review list',
      'run security checks',
    ),
  );
  if (isset($permissions[$role])) {
    return $permissions[$role];
  }
}
kreynen
kreynen
December 01, 2015 21:16 PM

Permissions are clobbered because Drupal uses NestedArray::mergeDeepArray() to merge overrides with existing config.

For example, if we have this permissions

$ drush cget user.role.anonymous permissions
'user.role.anonymous:permissions':
  - 'access content'
  - 'access comments'

and then add

$config['user.role.anonymous']['permissions'][] = 'use browsersync';

to settings.php, the result will be

$ drush cget user.role.anonymous permissions
'user.role.anonymous:permissions':
  - 'use browsersync'
  - 'access comments'

An easy way to workaround this would be

$config['user.role.anonymous']['permissions'][9999] = 'use browsersync';

which will result in

$ drush cget user.role.anonymous permissions
'user.role.anonymous:permissions':
  0:'access content'
  1:'access comments'
  9999: 'use browsersync'

But if you need to remove a permission via settings.php, then I honestly don't know how to do it, even with module config overrides system (which has an ability to load original config before providing the override). Maybe overriding the unwanted permission with NULL may work, but I haven't tried.

Leksat
Leksat
January 11, 2019 10:47 AM

Related Questions


Using Configuration API in drupal 8

Updated June 15, 2015 23:03 PM




Config folder in drupal8

Updated April 13, 2016 08:03 AM