¿Cómo depuro los permisos?

36

¿Cómo depuro permisos en Drupal 7?

Utilizo informes centrales, registros de errores, registros de errores del módulo de desarrollo, traza inversa y bloqueo de permisos de acceso a nodos, pero a veces no es suficiente. ¿Qué más debo verificar para averiguar por qué ciertos campos, vistas o bloques no se muestran a un usuario?

También descubrí que hay un módulo para Drupal 6 para informar sobre los permisos llamados, pero no está disponible para Drupal 7.

Estoy usando varios módulos de terceros relacionados con permisos:

 - devel node access 7.x-1.x-dev 
 - fast permissions administration 7.x-2.0
 - organic groups access control 7.x-1.x 
 - profile2 group access 7.x-1.x-dev 
 - ur-node access 7.x-1.x-dev
Refineo
fuente
Esta podría ser una parte importante de su pregunta: ¿Está utilizando algún módulo de acceso de nodo personalizado o contrib, como node_access ?
barista aficionado
Nota para uno mismo: node_access no está disponible en D7, solo D6. Pero podría haber otros módulos de permisos involucrados.
barista aficionado
@amateurbarista sí, estoy usando módulos de permisos como mencioné en PS2.
Refineo
El módulo filter_perms es un equivalente Drupal-7 del módulo permissions_report mencionado anteriormente
Druvision

Respuestas:

21

Una forma de hacerlo es crear un módulo personalizado, imprimir información de acceso en cada página, cada nodo, cada bloque.

La función menu_get_item () devuelve un elemento de enrutador que tiene la propiedad access_arguments para la página actual.

/**
 * Show access permission of current page.
 */
function yourmodule_get_page_access() {

  $router_item = menu_get_item();
  if ($router_item) {

    $access_arguments = unserialize($router_item['access_arguments']);

    $arguments = array();
    foreach ($access_arguments as $access_argument) {
      $arguments[] = $access_argument;
    }
    if ($arguments) {
      $output  = '<p>';
      $output .= t('This page needs user to have %p permission(s) to access', array(
        '%p' => implode(', ', $arguments),
      ));
      $output .= '</p>';
    }
    else {
      $output = '<p>' . t('This page needs no user permissions') . ' </p>';
    }
    return $output;
  }
}

Luego puede hook_page_alter, para mostrar la información de acceso en la parte superior de cada página.

/**
 * Implements hook_page_alter().
 *
 * Display access information on top of every page.
 */
function yourmodule_page_alter(&$page) {

  // Make a new area on top of the page for displaying access information.
  $page['content']['theverytop']['#markup'] = yourmodule_get_page_access();
  $page['content']['theverytop']['#weight'] = -10;
  $page['content']['#sorted'] = FALSE;
}

A continuación, puede mostrar la información de permiso de bloqueo de esta manera:

/**
 * Implement hook_block_alter
 *
 * To display block permission information to the block title.
 */

function yourmodule_block_view_alter(&$data, $block) {
  $delta = $block->delta;
  $output = '';

  $rid = db_query("SELECT rid FROM {block_role} WHERE delta = :delta", array(':delta' => $delta))->fetchCol();

  if (empty($rid)) {
      $output = ' This block does not have any role permission restriction.';
  } else {
      $output = ' This block is viewable for users have role(s): ';
      foreach ($rid as $role_id) {
          $rolename = db_query("SELECT name from {role} where rid = :rid", array(':rid' => $role_id))->fetchField();
          $output .= $rolename . ' ';
      }
  }

  // append the permission info to block title for every block
  $block->title .= $output;
}

Y así sucesivamente, básicamente el mismo concepto, puede hacer lo mismo para nodo, formulario, vistas. Espero que esto ayude.

gilzero
fuente
Cuando los argumentos de acceso yourmodule_get_page_access()no tienen sentido, puede echar un vistazo $router_item['access_callback']y luego buscar la función con ese nombre en los módulos relevantes para ver qué está pasando allí. Gran respuesta.
Wtower
7

Edite el archivo principal del módulo de usuario; encuentre la user_access()función, agregue 2 líneas antes de la returndeclaración y monitoree el registro de errores de PHP.

$granted = isset($perm[$account->uid][$string]);
error_log(sprintf('--- user_access: %s "%s" = %s', $account->name, $string, $granted ? 'yes' : 'no'));
return isset($perm[$account->uid][$string]);
temoto
fuente
De hecho, esto esta muy bien. ¿Qué hay de depurar permisos de campo?
Michal Przybylowicz
Veo los valores en drush, pero drush no sabe quién es el usuario. Pero no aparece en la página definida en hook_menu. No estoy seguro de por qué no.
sam452
error_logno sale a la pantalla. Para mi instalación, escribió en el registro de errores de apache. php.net/manual/en/function.error-log.php
Ryre
5

Parece que ya tiene todas las herramientas basadas en GUI para solucionar problemas de permisos. Un truco más avanzado (y probablemente más difícil) que he usado efectivamente en el pasado es:

  1. Construya una vista con los campos, roles, tipos de nodo, etc. que quiero probar.
  2. Habilite la "consulta de visualización" en la página de opciones avanzadas Vistas.
  3. Ejecute la Vista y pegue la consulta SQL en un editor SQL basado en GUI como Navicat (comercial) o MySQL Workbench (gratis).
  4. Vea qué nodos no aparecen.
  5. Ajusta la consulta a tus necesidades.

En muchos casos, las consultas que escupieron Vistas son bastante complejas (choque lleno de combinaciones) y construirlas manualmente tomaría un poco más de tiempo (además sería un poco más propenso a errores). Además, este enfoque garantiza que esté probando lo que el usuario está viendo. Si tiene habilitados los módulos de permisos (que utilizan los permisos principales de Drupal), sus uniones de tabla se mostrarán en la consulta utilizada por las Vistas. Una vez que recibí esta consulta, la modifico para mostrar cuántos nodos de tipo de contenido x están permitidos para el rol x, por ejemplo. Es tan preciso y preciso como los informes pueden ser. Y esos son mis informes "avanzados".

barista aficionado
fuente
2

Con Drupal tengo que usar un depurador algunas veces (xdebug con netbeans). Se llaman muchas funciones indirectamente, lo que hace casi imposible seguir lo que realmente se agrega globalmente solo leyendo el código, imprimiendo una traza inversa o verificando el resultado final.

gagarina
fuente