38

How do I debug permissions in Drupal 7?

I use core reporting, error logs, devel module error logs, backtrace and node access permission block but sometimes it is not enough. What else should I check to find out why certain fields, views or blocks are not showing to a user?

I also found there is a module for Drupal 6 for reporting on permissions called but it is not available for Drupal 7.

I am using various permission related third-party modules:

 - 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
4
  • This might be an important part of your question: Are you using any contrib or custom node access modules, such as node_access? Dec 13, 2011 at 21:05
  • Note to self: node_access is not available in D7, just D6. But there could be other permission modules involved. Dec 13, 2011 at 21:10
  • @amateurbarista yes, I am using permission modules as I mentioned in PS2.
    – LLub
    Dec 13, 2011 at 21:19
  • The filter_perms module is a Drupal-7 equivalent of the permissions_report module mentioned above
    – Druvision
    Jan 29, 2014 at 17:15

4 Answers 4

21
+50

One way you can do is make a custom module, print access info on every page, every node, every block.

menu_get_item() function return a router item which has access_arguments property for current page.

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

Then you can hook_page_alter, to display the access info on top of every page.

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

Next you can display out the block permission info like this:

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

And so forth, basically the same concept, you can do the same to node, form, views. Hope this helps.

1
  • 1
    When the access arguments in yourmodule_get_page_access() make no sense, you can take a look at $router_item['access_callback'] and then search for the function with that name in the relevant modules in order to look into what's going on in there. Great answer.
    – Wtower
    Jun 26, 2014 at 8:40
7

Edit the User module main file; find the user_access() function, add 2 lines before the return statement, and monitor the PHP error log.

$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]);
3
  • This is actually pretty good. How about debug Field permissions ? Aug 6, 2014 at 16:16
  • I see the values in drush, but drush doesn't know who the user is. But it's not appearing on the page defined in hook_menu. Unsure why not.
    – sam452
    Apr 29, 2015 at 19:02
  • error_log doesn't output to the screen. For my installation, it wrote to the apache error log. php.net/manual/en/function.error-log.php
    – Ryre
    Jul 13, 2015 at 16:04
5

It looks like like you've got all the GUI-based tools already to troubleshoot permissions. One more advanced (and probably more difficult) trick I've used effectively in the past is:

  1. Construct a View with the fields, roles, node-types, etc. that I want to test for.
  2. Enable "display query" on the Views advanced options page.
  3. Execute the View and paste the SQL query into a GUI-based SQL editor such as Navicat (commercial) or MySQL Workbench (free).
  4. See what nodes don't show up.
  5. Tweak the query to your needs.

I many cases the queries that Views spit out are rather complex (shock full of joins) and to construct them manually would take a little bit more time (plus it would be a little bit more error-prone). Also this approach ensures that you are testing against what the user is seeing. If you have any permissions modules enabled (that make use of Drupal core permissions), their table joins will show up in the query used by Views. Once I got this query I tweak it to show how many nodes of content type x are allowed for role x, for example. It's as accurate and fine-grained as reporting can get. And those are my "advanced" reports.

2

With Drupal I have to use a debugger some times (xdebug with netbeans). Lot of functions are called indirectly making almost impossible to follow what really append globally by only reading the code, printing a backtrace or checking the final output.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.