Jak debugować uprawnienia?

36

Jak debugować uprawnienia w Drupal 7?

Korzystam z podstawowych raportów, dzienników błędów, dzienników błędów modułów programistycznych, blokowania uprawnień dostępu do śledzenia i węzłów, ale czasami to nie wystarczy. Co jeszcze powinienem sprawdzić, aby dowiedzieć się, dlaczego pewne pola, widoki lub bloki nie są wyświetlane użytkownikowi?

Odkryłem również, że istnieje moduł dla Drupala 6 do raportowania o wywołanych uprawnieniach, ale nie jest on dostępny dla Drupala 7.

Korzystam z różnych zewnętrznych modułów powiązanych z uprawnieniami:

 - 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
źródło
Może to być ważna część twojego pytania: Czy używasz modułów contrib lub niestandardowych węzłów dostępu, takich jak node_access ?
amator barista
Uwaga do siebie: węzeł_dostęp nie jest dostępny w D7, tylko D6. Ale mogą być zaangażowane inne moduły uprawnień.
amator barista
@amateurbarista tak, używam modułów uprawnień, jak wspomniałem w PS2.
Refineo,
Moduł filter_perms jest Drupal-7 odpowiednikiem wspomnianego wyżej modułu permissions_report
Druvision

Odpowiedzi:

21

Jednym ze sposobów jest utworzenie niestandardowego modułu, drukowanie informacji o dostępie na każdej stronie, w każdym węźle, w każdym bloku.

Funkcja menu_get_item () zwraca element routera, który ma właściwość access_arguments dla bieżącej strony.

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

Następnie możesz hook_page_alter, aby wyświetlić informacje o dostępie na górze każdej strony.

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

Następnie możesz wyświetlić informacje o uprawnieniach do bloków w następujący sposób:

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

I tak dalej, w zasadzie ta sama koncepcja, możesz zrobić to samo z węzłem, formą, widokami. Mam nadzieję że to pomoże.

gilzero
źródło
Gdy argumenty dostępu yourmodule_get_page_access()nie mają sensu, możesz rzucić okiem, $router_item['access_callback']a następnie wyszukać funkcję o tej nazwie w odpowiednich modułach, aby sprawdzić, co się tam dzieje. Świetna odpowiedź.
Wtower
7

Edytuj główny plik modułu użytkownika; znajdź user_access()funkcję, dodaj 2 wiersze przed returninstrukcją i monitoruj dziennik błędów 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
źródło
To jest całkiem niezłe. Co powiesz na uprawnienia do debugowania w polu?
Michał Przybylowicz,
Widzę wartości w drush, ale drush nie wie, kim jest użytkownik. Ale nie pojawia się na stronie zdefiniowanej w hook_menu. Nie jestem pewien, dlaczego nie.
sam452
error_lognie wyświetla się na ekranie. W przypadku mojej instalacji zapisano go w dzienniku błędów Apache. php.net/manual/en/function.error-log.php
Ryre
5

Wygląda na to, że masz już wszystkie narzędzia oparte na GUI do rozwiązywania problemów z uprawnieniami. Jedną bardziej zaawansowaną (i prawdopodobnie trudniejszą) sztuczką, którą skutecznie stosowałem w przeszłości, jest:

  1. Utwórz widok z polami, rolami, typami węzłów itp., Dla których chcę przetestować.
  2. Włącz „wyświetlanie zapytania” na stronie opcji zaawansowanych Widoki.
  3. Uruchom widok i wklej zapytanie SQL do edytora SQL opartego na GUI, takiego jak Navicat (komercyjny) lub MySQL Workbench (bezpłatny).
  4. Zobacz, które węzły się nie wyświetlają.
  5. Dostosuj zapytanie do swoich potrzeb.

W wielu przypadkach zapytania wyrzucane przez widoki są dość złożone (wstrząs pełen złączeń), a ich ręczne wykonanie zajęłoby trochę więcej czasu (a ponadto byłoby nieco bardziej podatne na błędy). Takie podejście zapewnia także testowanie pod kątem tego, co widzi użytkownik. Jeśli masz włączone moduły uprawnień (które korzystają z uprawnień podstawowych Drupal), ich sprzężenia w tabeli pojawią się w zapytaniu używanym przez Widoki. Po otrzymaniu tego zapytania poprawiam je, aby pokazać, na przykład, ile węzłów typu treści x jest dozwolonych dla roli x. Jest tak dokładny i precyzyjny, jak to tylko możliwe. A to są moje „zaawansowane” raporty.

amator barista
źródło
2

Z Drupalem muszę czasem używać debuggera (xdebug z netbeans). Wiele funkcji jest wywoływanych pośrednio, co sprawia, że ​​prawie niemożliwe jest śledzenie tego, co naprawdę dołącza się globalnie, tylko poprzez czytanie kodu, drukowanie śladu wstecznego lub sprawdzanie końcowego wyniku.

gagarine
źródło