Как мне отладить разрешения?

36

Как мне отладить разрешения в Drupal 7?

Я использую основные отчеты, журналы ошибок, журналы ошибок модуля devel, backtrace и блок доступа к узлам, но иногда этого недостаточно. Что еще я должен проверить, чтобы выяснить, почему определенные поля, представления или блоки не отображаются для пользователя?

Я также обнаружил, что есть модуль для Drupal 6 для создания отчетов о вызываемых разрешениях, но он не доступен для Drupal 7.

Я использую различные разрешения сторонних модулей:

 - 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
источник
Это может быть важной частью вашего вопроса: используете ли вы какие-либо модули contrib или пользовательского доступа к узлам , например, node_access ?
бариста-любитель
Примечание для себя: node_access недоступен в D7, просто D6. Но могут быть и другие модули разрешения.
бариста-любитель
@amateurbarista да, я использую модули разрешений, как я упоминал в PS2.
Refineo
Модуль filter_perms является эквивалентом Drupal-7 вышеупомянутого модуля permissions_report
Druvision

Ответы:

21

Один из способов сделать это - создать собственный модуль, распечатать информацию о доступе на каждой странице, каждом узле, каждом блоке.

Функция menu_get_item () возвращает элемент маршрутизатора, который имеет свойство access_arguments для текущей страницы.

/**
 * 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;
  }
}

Затем вы можете hook_page_alter, чтобы отобразить информацию о доступе в верхней части каждой страницы.

/**
 * 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;
}

Далее вы можете отобразить информацию о разрешениях блока следующим образом:

/**
 * 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;
}

И так далее, в основном та же концепция, вы можете сделать то же самое для узла, формы, представления. Надеюсь это поможет.

gilzero
источник
Когда аргументы доступа yourmodule_get_page_access()не имеют смысла, вы можете посмотреть $router_item['access_callback']и затем найти функцию с таким именем в соответствующих модулях, чтобы посмотреть, что там происходит. Отличный ответ.
Wtower
7

Отредактируйте основной файл модуля User; найдите user_access()функцию, добавьте 2 строки перед returnоператором и следите за журналом ошибок 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
источник
Это на самом деле очень хорошо. Как насчет отладки Полевых разрешений?
Михал Przybylowicz
Я вижу значения в drush, но drush не знает, кто пользователь. Но он не появляется на странице, определенной в hook_menu. Не уверен, почему нет.
sam452
error_logне выводится на экран. Для моей установки он записал в журнал ошибок apache. php.net/manual/en/function.error-log.php
Ryre
5

Похоже, что у вас уже есть все инструменты на основе графического интерфейса для устранения проблем с разрешениями. Еще один продвинутый (и, вероятно, более сложный) трюк, который я эффективно использовал в прошлом:

  1. Создайте представление с полями, ролями, типами узлов и т. Д., Которые я хочу проверить.
  2. Включите «показывать запрос» на странице расширенных настроек Views.
  3. Выполните представление и вставьте запрос SQL в редактор SQL на основе графического интерфейса, например Navicat (коммерческий) или MySQL Workbench (бесплатный).
  4. Посмотрите, какие узлы не отображаются.
  5. Настройте запрос в соответствии с вашими потребностями.

Во многих случаях запросы, которые выплевывает Views, довольно сложны (шок полон объединений), и для их создания вручную потребовалось бы немного больше времени (плюс это было бы немного более подверженным ошибкам). Также этот подход гарантирует, что вы тестируете против того, что видит пользователь. Если у вас включены какие-либо модули разрешений (которые используют разрешения ядра Drupal), их объединения таблиц будут отображаться в запросе, используемом Views. Получив этот запрос, я настраиваю его, чтобы показать, например, сколько узлов типа контента x разрешено для роли x. Это настолько точно и детально, насколько это возможно. И это мои "продвинутые" отчеты.

любитель бариста
источник
2

С Drupal я должен использовать отладчик несколько раз (xdebug с netbeans). Многие функции вызываются косвенно, делая практически невозможным отслеживание того, что действительно добавляется глобально, только читая код, печатая обратную трассировку или проверяя окончательный результат.

gagarine
источник