View source
<?php
if (!function_exists('array_intersect_key')) {
function array_intersect_key() {
$arrs = func_get_args();
$result = array_shift($arrs);
foreach ($arrs as $array) {
foreach ($result as $key => $v) {
if (!array_key_exists($key, $array)) {
unset($result[$key]);
}
}
}
return $result;
}
}
function roleassign_help($section = "admin/help#roleassign") {
switch ($section) {
case 'admin/user/roleassign':
return _roleassign_settings_help();
case 'admin/help#roleassign':
return _roleassign_help_help();
}
}
function roleassign_perm() {
return array(
'assign roles',
);
}
function roleassign_menu($may_cache) {
$items = array();
if ($may_cache) {
$items[] = array(
'path' => 'admin/user/roleassign',
'title' => t('Role assign'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'roleassign_admin',
),
'description' => t('Allows site administrators to further delegate the task of managing user\'s roles.'),
'access' => user_access('administer access control'),
);
}
return $items;
}
function roleassign_admin() {
if (!user_access('administer access control')) {
return;
}
$roles = user_roles(true);
unset($roles[DRUPAL_AUTHENTICATED_RID]);
if ($roles) {
$form['roleassign_roles'] = array(
'#type' => 'checkboxes',
'#title' => t('Roles'),
'#options' => $roles,
'#default_value' => variable_get('roleassign_roles', array()),
'#description' => t('Select roles that should be available for assignment.'),
);
}
else {
$form['roleassign_roles'] = array(
'#type' => 'markup',
'#value' => '<p>No assignable roles avaiable. You have to ' . l(t('create roles'), 'admin/user/roles') . ' that can be assigned.</p>',
);
}
return system_settings_form($form);
}
function roleassign_form_alter($form_id, &$form) {
if (user_access('administer access control')) {
return;
}
if (!user_access('administer users') || !user_access('assign roles')) {
return;
}
if ($form_id != 'user_register' && ($form_id != 'user_edit' || !isset($form['account']))) {
return;
}
$roles = user_roles(true);
$assignable_roles = _roleassign_assignable_roles($roles);
$user = user_load(array(
'uid' => arg(1),
));
$assigned_roles = $user->roles;
$sticky_roles = array_diff($assigned_roles, $assignable_roles);
$sticky_roles = array_intersect_key($roles, $sticky_roles);
_roleassign_sticky_roles($sticky_roles);
$sticky_roles[DRUPAL_AUTHENTICATED_RID] = $roles[DRUPAL_AUTHENTICATED_RID];
foreach ($sticky_roles as $role) {
$sticky_roles_str .= $role . ', ';
}
$sticky_roles_str = substr($sticky_roles_str, 0, strlen($sticky_roles_str) - 2);
$roles_field = array(
'#type' => 'checkboxes',
'#title' => t('Assignable roles'),
'#options' => $assignable_roles,
'#default_value' => array_keys($assigned_roles),
'#description' => t('The user receives the combined permissions of all roles selected here and following roles: %roles.', array(
'%roles' => $sticky_roles_str,
)),
);
if (isset($form['account'])) {
$user_form =& $form['account'];
}
else {
$user_form =& $form;
}
$notify_field = $user_form['notify'];
unset($user_form['notify']);
$user_form['roleassign_roles'] = $roles_field;
$user_form['notify'] = $notify_field;
}
function roleassign_user($type, &$edit, &$user, $category = NULL) {
if ($category != 'account' || !isset($edit['roleassign_roles'])) {
return;
}
if ($type == 'validate' && !user_access('assign roles')) {
$message = t('Detected malicious attempt to alter user\'s roles.');
watchdog('security', $message, WATCHDOG_WARNING);
form_set_error('category', $message);
}
if ($type == 'insert' || $type == 'submit') {
$edit['roles'] = array_filter(_roleassign_sticky_roles() + $edit['roleassign_roles']);
unset($edit['roleassign_roles']);
}
}
function roleassign_user_operations() {
global $form_values;
if (user_access('administer access control') || !user_access('assign roles')) {
return;
}
$assignable_roles = _roleassign_assignable_roles(user_roles(true));
if (count($assignable_roles)) {
foreach ($assignable_roles as $key => $value) {
$add_roles['roleassign_add_role-' . $key] = $value;
$remove_roles['roleassign_remove_role-' . $key] = $value;
}
$operations = array(
t('Add a role to the selected users') => array(
'label' => $add_roles,
),
t('Remove a role from the selected users') => array(
'label' => $remove_roles,
),
);
}
else {
$operations = array();
}
if ($form_values) {
$op = explode('-', $form_values['operation']);
$rid = $op[1];
$op = $op[0];
if ($op != 'roleassign_add_role' && $op != 'roleassign_remove_role') {
return;
}
if (!user_access('assign roles')) {
$message = t('Detected malicious attempt to alter user\'s roles.');
watchdog('security', $message, WATCHDOG_WARNING);
form_set_error('category', $message);
}
$operations[$form_values['operation']] = array(
'callback' => 'user_multiple_role_edit',
'callback arguments' => array(
substr($op, 11),
$rid,
),
);
}
return $operations;
}
function _roleassign_assignable_roles($roles) {
return array_intersect_key($roles, array_filter(variable_get('roleassign_roles', array())));
}
function _roleassign_sticky_roles($new_sticky_roles = null) {
static $sticky_roles;
if (isset($new_sticky_roles)) {
$sticky_roles = $new_sticky_roles;
}
return $sticky_roles;
}
function _roleassign_settings_help() {
return t('<p>Users with both <code>administer users</code> and <code>assign roles</code> permissions are allowed to assign the roles selected below. For more information, see the !help.</p>', array(
'!help' => l(t('help page'), 'admin/help/roleassign'),
));
}
function _roleassign_help_help() {
$help = <<<EOT
<!-- Copyright (C) !year Thomas Barregren <mailto:thomas@webbredaktoren.se> -->
<style type="text/css" media="all">
/*<![CDATA[*/
code, kbd, pre { padding: 1px; font-family: "Bitstream Vera Sans Mono", Monaco, "Lucida Console", monospace; background-color: #EDF1F3; }
/*]]>*/
</style>
<p>
RoleAssign specifically allows site administrators to further delegate the task of managing user's roles.
</p>
<p>
RoleAssign introduces a new permission called <code>assign roles</code>. Users with this permission are able to assign selected roles to still other users. Only users with the <code>administer access control</code> permission may select which roles are available for assignment through this module.
</p>
<p>
This module is sponsored by <a href="http://www.webbredaktoren.se/">Webbredaktören</a>.
</p>
\t\t<!--break-->
<h2>
Background
</h2>
<p>
It is possible for site administrators to delegate the user administration through the <code>administer users</code> permission. But that doesn't include the right to assign roles to users. That is necessary if the delegatee should be able to administrate user accounts without intervention from a site administrator.
</p>
<p>
To delegate the assignment of roles, site administrators have had until now no other choice than also grant the <code>administer access control</code> permission. But that is not advisable, since it gives right to access all roles, and worse, to grant any rights to any role. That can be abused by the delegatee, who can assign himself all rights and thereby take control over the site.
</p>
<p>
This module solves this dilemma by introducing the <code>assign roles</code> permission. While editing a user's account information, a user with this permission will be able to select roles for the user from a set of available roles. Roles available are configured by users with the <code>administer access control</code> permission.
</p>
<h2>
Install
</h2>
<ol>
<li>Copy the entire <kbd>roleassign</kbd> directory, containing the <kbd>roleassign.module</kbd> and other files, to your Drupal modules directory.
</li>
<li>Log in as site administrator.
</li>
<li>Go to the administration page for modules and enable the module.
</li>
</ol>
<h2>
Configuration
</h2>
<ol>
<li>Log in as site administrator.
</li>
<li>Go to the administration page for access control and grant <code>assign roles</code> permission to those roles that should be able to assign roles to other users. Notice that besides the <code>assign roles</code> permission, these roles also must have the <code>administer users</code> permission.
</li>
<li>Go to the administration page for role assign and select those roles that should be available for assignment by users with <code>assign roles</code> permission.
</li>
<li>For each user that should be able to assign roles, go to the user's account and select a role with both the <code>assign roles</code> and the <code>administer users</code> permissions.
</li>
</ol>
<h2>
Usage
</h2>
<ol>
<li>Log in as a user with both the <code>assign roles</code> and the <code>administer users</code> permissions.
</li>
<li>To change the roles of a user, go to the user's account and review the assignable roles and change them as necessary.
</li>
</ol>
<h2>
License
</h2>
<p>
RoleAssign !version. Copyright © !year <a href="mailto:thomas@webbredaktoren.se">Thomas Barregren</a>.
</p>
<p>
RoleAssign is free software; you can redistribute it and/or modify it under the terms of the <a href="http://www.gnu.org/licenses/gpl.html#SEC1">GNU General Public License</a> as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
</p>
<p>
RoleAssign is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the <a href="http://www.gnu.org/licenses/gpl.html#SEC1">GNU General Public License</a> for more details.
</p>
<p>
You should have received a copy of the <a href="http://www.gnu.org/licenses/gpl.html#SEC1">GNU General Public License</a> along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
</p>
EOT;
$version = str_replace(array(
'$Re' . 'vision:',
' $',
), array(
'',
'',
), '$Revision$');
$year = substr('$Date$', 7, 4);
return t($help, array(
'!version' => $version,
'!year' => $year,
));
}