* @copyright Nicholas Vahalik 2013 * @package permission_report **/ /** * Implements hook_menu(). */ function permission_report_menu() { $items = array(); $items['admin/reports/permissions'] = array( 'title' => 'Permissions (role report)', 'page callback' => 'permission_report_role_list', 'access arguments' => array('view permission report'), 'description' => 'View roles and the users in them.', ); $items['admin/reports/permissions/roles'] = array( 'title' => 'Roles', 'page callback' => 'permission_report_role_list', 'type' => MENU_DEFAULT_LOCAL_TASK, 'access arguments' => array('view permission report'), 'weight' => -5, ); $items['admin/reports/permissions/perms'] = array( 'title' => 'Permissions', 'page callback' => 'permission_report_permission_list', 'type' => MENU_LOCAL_TASK, 'access arguments' => array('view permission report'), ); $items['admin/reports/permissions/perms/%'] = array( 'title' => 'Permissions', 'type' => MENU_CALLBACK, 'page arguments' => array(4), 'page callback' => 'permission_report_user_having_perm', 'access arguments' => array('view permission report'), ); $items['admin/reports/permissions/roles/%'] = array( 'title' => 'Roles', 'type' => MENU_CALLBACK, 'page callback' => 'permission_report_users_having_role', 'page arguments' => array(4), 'access arguments' => array('view permission report'), ); $items['user/%user/permission_report'] = array( 'title' => 'Permission Report', 'page callback' => 'permission_report_user_report', 'page arguments' => array(1), 'type' => MENU_LOCAL_TASK, 'access arguments' => array('view permission report'), 'weight' => 2, ); return $items; } /** * Implements hook_admin_paths(). */ function permission_report_admin_paths() { $paths = array( 'user/*/permission_report' => TRUE, ); return $paths; } /** * Implements hook_user_view(). */ function permission_report_user_view($account, $view_mode, $langcode) { if (user_access('view permission report', $account)) { $account->content['summary']['rsop'] = array( '#type' => 'user_profile_item', '#title' => t('Resultant Set of Permissions'), '#markup' => l(t('View permission report report for !s', array('!s' => $account->name)), "user/$account->uid/permission_report"), '#attributes' => array('class' => 'permission_report'), ); } } /** * Displays a permission report for a given user. * * @param $user User object. * * @return string */ function permission_report_user_report($user) { // Render role/permission overview: $options = array(); $row = array(); $can_admin_access = user_access('administer access control'); foreach (module_implements('permission') as $module) { if ($permissions = module_invoke($module, 'permission')) { $rows[] = array(array( 'data' => t('@module module', array('@module' => $module)), 'class' => 'module', 'id' => 'module-' . $module, 'colspan' => 3, )); asort($permissions); foreach ($permissions as $perm => $meta) { $options = array(); $display_roles = array(); $roles = _permission_report_roles_having_perm($perm, $user); if (array_key_exists('description', $meta)) { $options = array('attributes' => array('alt' => $meta['description'])); } foreach ($roles as $rid => $name) { $display_roles[] = $can_admin_access ? l($name, "admin/reports/permissions/roles/$rid") : t($name); } $rows[] = array( array('data' => l(strip_tags($meta['title']), "admin/reports/permissions/perms/$perm", $options)), array('data' => user_access($perm, $user) ? 'Yes' : 'No'), array('data' => implode(', ', $display_roles)), ); } } } return theme('table', array('header' => array('Permission', 'Access', 'Roles'), 'rows' => $rows, 'attributes' => array('id' => 'permissions'))); } /** * Return an array of users keyed by IDs that have access to a specific permission. * * @param $permission Permission string. * * @return array **/ function _permission_report_users_having_perm($permission) { $roles = _permission_report_roles_having_perm($permission); if (count($roles) > 0) { $query = db_select('users', 'u'); $query->innerJoin('users_roles', 'ur', 'ur.uid = u.uid'); $query->addField('u', 'uid'); $query->addField('u', 'name'); $query->condition('ur.rid', array_keys($roles), 'IN'); $users = $query->execute()->fetchAllKeyed(); return $users; } return array(); } /** * Gets a list of roles that have a permission, optionally limited * to a specific role. */ function _permission_report_roles_having_perm($permission, $user = NULL) { $query = db_select('role', 'r'); $query->addField('r', 'rid'); $query->addField('r', 'name'); $query->innerJoin('role_permission', 'p', 'r.rid = p.rid'); $query->condition('p.permission', $permission); if ($user) { $query->innerJoin('users_roles', 'ur', 'r.rid = ur.rid'); $query->condition('ur.uid', $user->uid); } return $query->execute()->fetchAllKeyed(); } /** * Generates a report of users having a particular role. **/ function permission_report_users_having_role($rid) { $users_having_roles = $rows = array(); $query = db_select('users', 'u'); $query->addField('u', 'uid'); $query->addField('u', 'name'); $query->innerJoin('users_roles', 'ur', 'ur.uid = u.uid'); $query->condition('ur.rid', $rid); $query->condition('u.status', 1); $users_having_role = $query->execute()->fetchAll(); $query = db_select('role', 'r'); $query->addField('r', 'name'); $query->condition('rid', $rid); $role_name = $query->execute()->fetchField(); $view_users = user_access('access user profiles'); drupal_set_title(t('Users in "!name" role', array('!name' => $role_name))); $users_header = array(array( 'data' => 'User', 'colspan' => 2, )); foreach ($users_having_role as $user) { $rows[] = array( array('data' => ($user->uid !== 0) ? ($view_users ? l($user->name, "user/$user->uid") : $user->name) : variable_get('anonymous', t('Anonymous'))) , array('data' => l('Permission report', "user/$user->uid/permission_report")), ); } return theme('table', array('header' => $users_header, 'rows' => $rows)); } /** * List of roles with the number of users in each role. */ function permission_report_role_list() { $user_in_roles = db_query('SELECT r.rid rid, r.name name, COUNT(ur.uid) as user_count FROM {role} r INNER JOIN {users_roles} ur USING (rid) INNER JOIN {users} u USING(uid) WHERE u.status = :u_status GROUP BY r.rid ORDER BY r.name', array(':u_status' => 1))->fetchAllAssoc('rid'); $can_admin_access = user_access('administer access control'); $all_users = user_roles(); // Remove 'authenticated user' and 'anonymous user'. unset($all_users[1], $all_users[2]); $rows = array(); foreach ($all_users as $rid => $name) { $count = (isset($user_in_roles[$rid])) ? $user_in_roles[$rid]->user_count : 0; $rows[] = array( $can_admin_access ? l($name, "admin/people/permissions/$rid") : t($name), l(format_plural($count, '1 user', '@count users'), "admin/reports/permissions/roles/$rid"), ); } $roles_header = array( array( 'data' => 'Role', 'colspan' => 2, ), ); return theme('table', array('header' => $roles_header, 'rows' => $rows)); } /** * Creates a report showing which users have a specific permission. */ function permission_report_user_having_perm($permission) { $view_users = user_access('access user profiles'); $can_admin_access = user_access('administer access control'); $output = ''; drupal_set_title(t('Permissions report for "!permission"', array('!permission' => $permission))); foreach (_permission_report_users_having_perm($permission) as $uid => $name) { $users_rows[] = array( array('data' => ($uid !== 0) ? ($view_users ? l($name, "user/$uid") : $name) : variable_get('anonymous', t('Anonymous'))), array('data' => l('Permission report', 'user/' . $uid . '/permission_report')), ); } $users_header = array( array( 'data' => 'User', 'colspan' => 2, ), ); foreach (_permission_report_roles_having_perm($permission) as $rid => $name) { $roles_rows[] = array( array('data' => $can_admin_access ? l($name, "admin/reports/permissions/roles/$rid") : t($name)), array('data' => l('Permission report', "admin/reports/permissions/roles/$rid")), ); } $roles_header = array( array( 'data' => 'Role', 'colspan' => 2, ), ); $output .= '

Users

'; $output .= theme('table', array('header' => $users_header, 'rows' => $users_rows)); $output .= '

Roles

'; $output .= theme('table', array('header' => $roles_header, 'rows' => $roles_rows)); return $output; } /** * Creates a report which lists all permissions and the number of users which * have those permissions. */ function permission_report_permission_list() { $can_admin_access = user_access('administer access control'); foreach (module_implements('permission') as $module) { if ($permissions = module_invoke($module, 'permission')) { $rows[] = array(array( 'data' => t('@module module', array('@module' => $module)), 'class' => 'module', 'id' => 'module-' . $module, 'colspan' => 3, )); asort($permissions); foreach ($permissions as $perm => $meta) { $display_roles = array(); $roles = _permission_report_roles_having_perm($perm); foreach ($roles as $rid => $name) { $display_roles[] = $can_admin_access ? l($name, "admin/reports/permissions/roles/$rid") : t($name); } $rows[] = array( array('data' => $meta['title']), array('data' => l(format_plural(count(_permission_report_users_having_perm($perm)), '1 user', '@count users'), "admin/reports/permissions/perms/$perm")), ); } } } return theme('table', array('header' => array('Permission', 'Users'), 'rows' => $rows, 'attributes' => array('id' => 'permissions', 'sticky' => TRUE))); } /** * Implements hook_permission(). */ function permission_report_permission() { return array( 'view permission report' => array( 'title' => t('View permission report'), 'description' => t('Allows a user to view permission reports.'), ), ); }