Como depurar permissões?

36

Como depurar permissões no Drupal 7?

Uso relatórios principais, logs de erros, logs de erros do módulo de desenvolvimento, backtrace e bloqueio de permissão de acesso ao nó, mas às vezes não é suficiente. O que mais devo verificar para descobrir por que certos campos, visualizações ou blocos não estão sendo exibidos para um usuário?

Também descobri que existe um módulo para o Drupal 6 para relatar permissões chamado, mas ele não está disponível para o Drupal 7.

Estou usando vários módulos de terceiros relacionados à permissão:

 - 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
fonte
Isso pode ser uma parte importante da sua pergunta: você está usando algum contrib ou módulo de acesso ao nó customizado, como node_access ?
amateur barista
Nota para self: node_access não está disponível no D7, apenas no D6. Mas pode haver outros módulos de permissão envolvidos.
amateur barista
@amateurbarista sim, estou usando módulos de permissão, como mencionei no PS2.
Refineo 13/12/11
O módulo filter_perms é um equivalente do Drupal-7 do módulo Permissions_report mencionado acima
Druvision

Respostas:

21

Uma maneira de fazer é criar um módulo personalizado, imprimir informações de acesso em todas as páginas, todos os nós, todos os blocos.

A função menu_get_item () retorna um item do roteador que possui a propriedade access_arguments para a página atual.

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

Em seguida, você pode hook_page_alter, para exibir as informações de acesso na 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;
}

Em seguida, você pode exibir as informações de permissão de bloqueio assim:

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

E assim por diante, basicamente o mesmo conceito, você pode fazer o mesmo para nó, formulário, visualizações. Espero que isto ajude.

Gilzero
fonte
Quando os argumentos de acesso yourmodule_get_page_access()não fazem sentido, você pode dar uma olhada $router_item['access_callback']e procurar a função com esse nome nos módulos relevantes para analisar o que está acontecendo lá. Ótima resposta.
Wtower 26/06
7

Edite o arquivo principal do módulo Usuário; encontre a user_access()função, adicione 2 linhas antes da returninstrução e monitore o log de erros do 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
fonte
Na verdade, isso é muito bom. Que tal depurar permissões de campo?
Michal Przybylowicz
Eu vejo os valores no drush, mas o drush não sabe quem é o usuário. Mas não está aparecendo na página definida no hook_menu. Incerto por que não.
sam452
error_lognão sai para a tela. Para minha instalação, ele escreveu no log de erros do apache. php.net/manual/en/function.error-log.php
Ryre
5

Parece que você já possui todas as ferramentas baseadas em GUI para solucionar problemas de permissões. Um truque mais avançado (e provavelmente mais difícil) que usei efetivamente no passado é:

  1. Construa uma visualização com os campos, funções, tipos de nós etc. que eu quero testar.
  2. Ative a "consulta de exibição" na página de opções avançadas do Views.
  3. Execute o View e cole a consulta SQL em um editor SQL baseado em GUI, como Navicat (comercial) ou MySQL Workbench (gratuito).
  4. Veja quais nós não aparecem.
  5. Ajuste a consulta de acordo com suas necessidades.

Em muitos casos, as consultas que o Views expõe são bastante complexas (choque cheio de junções) e construí-las manualmente levaria um pouco mais de tempo (além disso, seria um pouco mais propenso a erros). Além disso, essa abordagem garante que você esteja testando o que o usuário está vendo. Se você tiver algum módulo de permissão ativado (que faça uso das permissões principais do Drupal), suas junções de tabela aparecerão na consulta usada pelo Views. Depois de obter essa consulta, eu a ajusto para mostrar quantos nós do tipo de conteúdo x são permitidos para a função x, por exemplo. É o mais preciso e refinado possível nos relatórios. E esses são meus relatórios "avançados".

barista amador
fonte
2

Com o Drupal, tenho que usar um depurador algumas vezes (xdebug com netbeans). Muitas funções são chamadas indiretamente, tornando quase impossível seguir o que realmente se acrescenta globalmente apenas lendo o código, imprimindo um retorno ou verificando a saída final.

gagarine
fonte