如何调试权限?


36

如何在Drupal 7中调试权限?

我使用核心报告,错误日志,开发模块错误日志,回溯和节点访问权限块,但有时还不够。我还应该检查什么以找出为什么某些字段,视图或块未显示给用户?

我还发现有一个用于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

这可能是您问题的重要组成部分:您是否正在使用任何contrib或自定义节点访问模块,例如node_access
业余咖啡师,

自我注意:node_access在D7中不可用,仅在D6中可用。但是可能涉及其他权限模块。
业余咖啡师,

@amateurbarista是的,我使用的是PS2中提到的权限模块。
Refineo 2011年

filter_perms模块是Drupal-7的等同于上面提到的Permissions_report模块
Druvision 2014年

Answers:


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

依此类推,基本上是相同的概念,您可以对节点,表单,视图执行相同的操作。希望这可以帮助。


当访问参数yourmodule_get_page_access()毫无意义时,您可以查看一下$router_item['access_callback'],然后在相关模块中搜索具有该名称的函数,以查看其中发生的情况。好答案。
Wtower

7

编辑用户模块主文件;找到该user_access()函数,在return语句之前添加2行,并监视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]);

这实际上是相当不错的。调试字段权限如何?
Michal Przybylowicz 2014年

我在drush中看到了值,但drush不知道用户是谁。但是它没有出现在hook_menu中定义的页面上。不确定为什么不。
sam452

error_log不会输出到屏幕。对于我的安装,它已写入apache错误日志。 php.net/manual/en/function.error-log.php
Ryre

5

看来您已经拥有所有基于GUI的工具来对权限进行故障排除。我过去有效使用过的一种更高级(可能更困难)的技巧是:

  1. 使用要测试的字段,角色,节点类型等构造一个View。
  2. 在“视图”高级选项页面上启用“显示查询”。
  3. 执行“视图”并将SQL查询粘贴到基于GUI的SQL编辑器中,例如Navicat(商业)或MySQL Workbench(免费)。
  4. 查看哪些节点不显示。
  5. 根据您的需求调整查询。

在很多情况下,View吐出的查询非常复杂(充满连接的震动),而手动构造它们会花费更多时间(而且容易出错)。此外,这种方法还可以确保您正在根据用户所看到的内容进行测试。如果您启用了任何权限模块(利用了Drupal核心权限),则它们的表联接将显示在Views使用的查询中。一旦获得此查询,我将对其进行调整以显示例如角色x允许有多少个内容类型为x的节点。它与报告所能获得的一样准确和细粒度。这些是我的“高级”报告。


2

使用Drupal,我不得不使用调试器几次(使用NetBeans的xdebug)。间接调用了许多函数,仅通过读取代码,打印回溯记录或检查最终输出,几乎不可能跟随全局追加的内容。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.