--- role_delegation.module.orig 2010-12-09 13:25:31.000000000 -0500 +++ role_delegation.module.mod 2011-02-10 16:11:06.000000000 -0500 @@ -64,7 +64,7 @@ $roles = _role_delegation_roles(); $roles_preserve = array('authenticated user'); foreach ($roles as $rid => $role) { - if (!(user_access('assign all roles') || user_access(_role_delegation_make_perm($role)) || user_access('administer permissions'))) { + if (!(user_access('assign all roles') || user_access(_role_delegation_make_perm($role)))) { // Hide roles the user can't assign. $form['roles'][$rid] = array( '#type' => 'value', @@ -129,9 +129,6 @@ return FALSE; } // Check access to role assignment page. - if (user_access('administer permissions')) { - return TRUE; - } $perms = role_delegation_perm(); foreach ($perms as $perm) { if (user_access($perm)) { @@ -219,8 +216,6 @@ */ function role_delegation_user($op, &$edit, &$account, $category = NULL) { if ($op == 'register' || ($op == 'form' && $category == 'account')) { - // Only alter user form when user can't assign permissions without Role Delegation. - if (!user_access('administer permissions')) { // Split up roles based on whether they can be delegated or not. $current_roles = isset($account->roles) ? $account->roles : array(); $rids_default = array(); @@ -269,7 +264,6 @@ } return $form; } - } elseif (isset($edit['roles_assign']) && ($op == 'insert' || $op == 'submit')) { $edit['roles'] = $edit['roles_preserve'] + array_filter($edit['roles_assign']); } @@ -291,12 +285,6 @@ * Implementation of hook_user_operations(). */ function role_delegation_user_operations($form_state = array()) { - // Only provide role add/remove operations when user can't assign permissions - // without Role Delegation. - if (user_access('administer permissions')) { - return; - } - // Provide add/remove operations for delegated roles. $roles = _role_delegation_roles(); $add_roles = array(); @@ -343,3 +331,76 @@ return $operations; } + +/** + * Implementation of hook_form_alter(). + * Main method which will strip out all restricted roles and 'assign ROLE' permissions + */ +function role_delegation_form_alter(&$form, $form_state, $form_id){ + switch($form_id){ + case "user_profile_form": + if(!user_access('assign all roles') and user_access('administer permissions')) unset($form['account']['roles']); + break; + + case "user_admin_perm": + if(user_access('assign all roles')) break; + $form["#validate"][] = 'role_delegation_user_admin_perm_validate'; + $role_names = $form['role_names']; + foreach($role_names as $rid => $role){ + if($rid != DRUPAL_ANONYMOUS_RID && $rid != DRUPAL_AUTHENTICATED_RID && !user_access(_role_delegation_make_perm($role['#value']))){ + // Remove entire role + $removedRoles[] = $role['#value']; + unset($form['checkboxes'][$rid]); + unset($form['role_names'][$rid]); + } + } + // Okay, we can delegate the remaining roles, but we need to remove the 'assign ROLE' permissions for the ones we just removed + $form['hiddenPermissions'] = array('#type' => 'value', '#value' => array()); + foreach(_role_delegation_roles() as $perm){ + if(in_array($perm, $removedRoles)){ + $rolePerm = _role_delegation_make_perm($perm); + foreach($form['role_names'] as $rid => $role){ + if(in_array($rolePerm, $form['checkboxes'][$rid]['#default_value'])){ + $form['hiddenPermissions']['#value'][$rid][] = $rolePerm; + unset($form['checkboxes'][$rid]['#default_value'][$rolePerm]); + } + unset($form['checkboxes'][$rid]['#options'][$rolePerm]); + unset($form['permission'][$rolePerm]); + } + } + } + // Manualy remove 'assign all roles' permissions (because if we're here, the user dosne't have it) + foreach($form['role_names'] as $rid => $role){ + $permKey = array_search("assign all roles", $form['checkboxes'][$rid]['#default_value']); + if($permKey){ + $form['hiddenPermissions']['#value'][$rid]["assign all roles"] = (int)($permKey !== false); + unset($form['checkboxes'][$rid]['#default_value']["assign all roles"]); + } + unset($form['checkboxes'][$rid]['#options']["assign all roles"]); + unset($form['permission']["assign all roles"]); + } + break; + } +} + +/** + * Validation function to re-insert restricted permissions back into the permissions matrix before save. + * This will prevent permissions from being dropped from a subordinate user's submission (with missing permissions due to restrictions) + */ +function role_delegation_user_admin_perm_validate($form, &$form_state){ + if(array_key_exists('hiddenPermissions', $form_state['values'])) foreach($form_state['values']['hiddenPermissions'] as $rid => $permissions){ + foreach($permissions as $permission){ + $form_state['values'][$rid][$permission] = 1; + unset($form_state['values']['hiddenPermissions'][$rid][$permission]); + } + unset($form_state['values']['hiddenPermissions']); + } +} + +/** + * Implementation of hook_menu_alter(). + * Restrict access to the roles listing (backdoor into role permissions) + */ +function role_delegation_menu_alter(&$items){ + $items['admin/user/roles']['access arguments'] = array("assign all roles"); +}