I host multi-sites. I would like to keep the super admin (uid=1) to myself, and create some regular admins for each site. Regular admin would have pretty much all the rights with a few exceptions (php filter, module control etc). One important permission is the "administer permissions". If I grant regular admin "administer permissions", then he/she can grant everything to him/her self. This is what I consider an all-or-nothing permission.

I believe a simple scheme that can fundamentally improve the permission control: the system can implement a simple rule such that a user (regular admin) can change (grant or remove) a permission (e.g. “administer filters”) only if he/she has that permission (“administer filters”) in the first place.

Coupled with this patch http://drupal.org/node/39636 (hide uid=1 from other users), this rule effectively creates a permission "chain" or hierarchy that allows "administer permissions" to be granted to regular admin without worrying about the all-or-nothing effect.

I believe some minor changes in user.admin.inc that can make it work. However, the changes disabled all the check boxes. Can some expert take a look, and tell me what I am missing here? I'd also like to here if my idea is in the right direction.

Thanks in advance!

function user_admin_perm($form_state, $rid = NULL) {
...
        foreach ($role_names as $rid => $name) {
          // Builds arrays for checked boxes for each role
          if (strpos($role_permissions[$rid], $perm .',') !== FALSE) {
            $status[$rid][] = $perm;
          }
          // a user can only change this permission if he has this permission in the first place
          if (user_access($perm)) {
             $disabled[$rid][] = FALSE;
          }
          else {
             $disabled[$rid][] = TRUE;           
          }          
        }
      }
    }
  }

  // Have to build checkboxes here after checkbox arrays are built
  foreach ($role_names as $rid => $name) {
    //disable the checkbox if current user doesn't have this permission
    $form['checkboxes'][$rid] = array('#disabled'=>$disabled[$rid], '#type' => 'checkboxes', '#options' => $options, '#default_value' => isset($status[$rid]) ? $status[$rid] : array());
    $form['role_names'][$rid] = array('#value' => $name, '#tree' => TRUE);
  }
  $form['submit'] = array('#type' => 'submit', '#value' => t('Save permissions'));

This is only for presenting the form, on the form submit, similar checks can put in place to enforce the rule.

Comments

newbuntu’s picture

Title: Improve "administer permissions" control mechanism » Enhance "administer permissions" control mechanism
Category: support » feature

I found my problem. The actual solution is quite simple. It's in theme_user_admin_perm()

function theme_user_admin_perm($form) {
...
        foreach (element_children($form['checkboxes']) as $rid) {
          if (is_array($form['checkboxes'][$rid])) {
            if (!user_access($key)) { // a user can only grant permission if he has the permission!
              $form['checkboxes'][$rid][$key]['#attributes']['disabled'] = 'disabled'; 
            }
            $row[] = array('data' => drupal_render($form['checkboxes'][$rid][$key]), 'class' => 'checkbox', 'title' => $roles[$rid] .' : '. t($key));
          }
        }
...

I believe this is a simple change with fundamental impact on drupal permission control.

I know there can be more elaborate improvement with this idea. For example, this scheme does allow a user to shoot himself on his foot, because he can remove a permission from himself. Then he won't be able to get it back for himself.

I would like to recommend this as core feature change.

gaele’s picture

Version: 6.x-dev » 7.x-dev

Hi newbuntu,

Features like this either should go into a contributed module, or into the development version of Drupal. If you want other people to take a look at your code please supply a patch for Drupal 7.

sun.core’s picture

Version: 7.x-dev » 8.x-dev
jhedstrom’s picture

Version: 8.0.x-dev » 8.1.x-dev
Status: Active » Postponed (maintainer needs more info)

Feature -> 8.1.

There are a variety of ways to do this in contrib, marking postponed for now.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.0-beta1 was released on March 2, 2016, which means new developments and disruptive changes should now be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

dpi’s picture

Status: Postponed (maintainer needs more info) » Closed (won't fix)
Issue tags: +role delegation

I believe a simple scheme that can fundamentally improve the permission control: the system can implement a simple rule such that a user (regular admin) can change (grant or remove) a permission (e.g. “administer filters”) only if he/she has that permission (“administer filters”) in the first place.

This sounds nightmarish

Issue summary has not considered how to determine what roles you are allowed to modify.

This kind of complexity belongs in contrib.