You are here

administerusersbyrole.module in Administer Users by Role 7

Provides fine-grained permissions for creating, editing, and deleting users.

This module allows site builders to set up fine-grained permissions for allowing users to edit and cancel other users: more specific than Drupal Core's all-or-nothing 'administer users' permission. It also provides and enforces a 'create users' permission.

File

administerusersbyrole.module
View source
<?php

/**
 * @file
 * Provides fine-grained permissions for creating, editing, and deleting users.
 *
 * This module allows site builders to set up fine-grained permissions for
 * allowing users to edit and cancel other users:  more specific than
 * Drupal Core's all-or-nothing 'administer users' permission.  It also
 * provides and enforces a 'create users' permission.
 */

/**
 * Implements hook_permission().
 */
function administerusersbyrole_permission() {
  $roles = user_roles();
  $perms = array();
  $perms['create users'] = array(
    'title' => 'Create new users',
  );
  $perms['edit users with no custom roles'] = array(
    'title' => 'Edit users with no custom roles',
  );
  $perms['cancel users with no custom roles'] = array(
    'title' => 'Cancel users with no custom roles',
  );
  foreach ($roles as $rid => $role) {
    foreach (array(
      'edit',
      'cancel',
    ) as $op) {

      // edit/cancel x.
      $perm_string = _administerusersbyrole_build_perm_string($role, $op, FALSE);
      $perm_title = ucfirst($perm_string);
      $perms[$perm_string] = array(
        'title' => $perm_title,
      );

      // edit/cancel $op x and other.
      $perm_string = _administerusersbyrole_build_perm_string($role, $op, TRUE);
      $perm_title = ucfirst($perm_string);
      $perms[$perm_string] = array(
        'title' => $perm_title,
      );
    }
  }
  return $perms;
}

/**
 * Implements hook_menu_alter().
 */
function administerusersbyrole_menu_alter(&$items) {
  $items['user/%user/edit']['access callback'] = '_administerusersbyrole_can_edit_user';
  $items['user/%user/edit']['access arguments'] = array(
    1,
  );
  $items['user/%user/cancel']['access callback'] = '_administerusersbyrole_can_cancel_user';
  $items['user/%user/cancel']['access arguments'] = array(
    1,
  );
  $items['admin/people/create']['access arguments'] = array(
    'create users',
  );
}
function _administerusersbyrole_can_edit_user($account) {
  global $user;
  if ($account->uid == $user->uid) {
    return TRUE;
  }

  // allow only uid1 to edit uid1
  if ($account->uid == 1) {
    return FALSE;
  }

  // We mave been passed a mock account object. If so, load the user to ensure
  // that we have roles to check against.
  if (!isset($account->roles)) {
    $account = user_load($account->uid);
  }
  if ($account->roles === array(
    DRUPAL_AUTHENTICATED_RID => 'authenticated user',
  )) {
    if (!user_access('edit users with no custom roles')) {
      return FALSE;
    }
  }
  $allow = TRUE;
  foreach ($account->roles as $rid => $role) {
    if ($rid === DRUPAL_AUTHENTICATED_RID) {
      continue;
    }
    if (user_access(_administerusersbyrole_build_perm_string($role, 'edit', TRUE))) {
      return TRUE;
    }
    if (!user_access(_administerusersbyrole_build_perm_string($role, 'edit', FALSE))) {
      $allow = FALSE;
    }
  }
  return $allow;
}
function _administerusersbyrole_can_cancel_user($account) {
  if ($account->uid == 1) {
    return FALSE;
  }

  // We mave been passed a mock account object. If so, load the user to ensure
  // that we have roles to check against.
  if (!isset($account->roles)) {
    $account = user_load($account->uid);
  }
  if ($account->roles === array(
    DRUPAL_AUTHENTICATED_RID => 'authenticated user',
  )) {
    if (!user_access('cancel users with no custom roles')) {
      return FALSE;
    }
  }
  $allow = TRUE;
  foreach ($account->roles as $rid => $role) {
    if ($rid === DRUPAL_AUTHENTICATED_RID) {
      continue;
    }
    if (user_access(_administerusersbyrole_build_perm_string($role, 'cancel', TRUE))) {
      return TRUE;
    }
    if (!user_access(_administerusersbyrole_build_perm_string($role, 'cancel', FALSE))) {
      $allow = FALSE;
    }
  }
  return $allow;
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function administerusersbyrole_form_user_multiple_cancel_confirm_alter(&$form, &$form_state) {
  $anyallowed = FALSE;
  foreach (array_filter($form_state['post']['accounts']) as $uid => $value) {
    $account = user_load($uid);
    if (_administerusersbyrole_can_cancel_user($account)) {
      $anyallowed = TRUE;
    }
    else {
      drupal_set_message(t('You do not have permission to cancel %user.', array(
        '%user' => $account->name,
      )), 'error');
      unset($form_state['post']['accounts'][$uid]);
      unset($form['accounts'][$uid]);
    }
  }
  if (!$anyallowed) {
    drupal_goto(drupal_substr($form['#action'], 1));
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Make the user edit form consider our permissions when determining which
 * elements should be visible to administrators.
 */
function administerusersbyrole_form_user_profile_form_alter(&$form, &$form_state) {
  global $user;
  $account = $form['#user'];
  $register = $form['#user']->uid > 0 ? FALSE : TRUE;
  $admin = _administerusersbyrole_can_edit_user($account);
  $admin = !empty($admin) ? TRUE : user_access('administer users');
  $form['account']['name']['#access'] = $register || $user->uid == $account->uid && user_access('change own username') || $admin;
  $form['account']['status']['#access'] = $account->uid == $user->uid ? $form['account']['status']['#access'] : $admin;
}

/**
 * Generates a permission string for a given a role name.
 */
function _administerusersbyrole_build_perm_string($role_name, $op = 'edit', $other = FALSE) {
  $perm = "{$op} users with role ";
  $perm .= preg_replace('/[^a-zA-Z0-9]/', '', $role_name);
  if ($other) {
    $perm .= ' and other roles';
  }
  return $perm;
}

/**
 * Implements hook_views_api().
 */
function administerusersbyrole_views_api() {
  return array(
    'api' => 3,
    'path' => drupal_get_path('module', 'administerusersbyrole') . '/views',
  );
}