I had an issue where I added a paragraphs field to the quiz_directions content type and populated a quiz_directions node. After doing so any users without the "bypass node access" permission would not have the paragraph items rendered.

It turns out that when the paragraphs module is about to render a paragraph item it checks the current user has access to view the parent entity using node_access(). Quiz however appears to use the node grants system to make any quiz question only accessible via the quiz take pages and not on their own node view pages. Therefore when Paragraphs checks for access to that node it does so in the context of a standard node view.

If it helps other people with the same issue, a workaround is to implement hook_node_grants_alter() in a custom module.

/**
 * Implements hook_node_grants_alter().
 */
function MY_MODULE_node_grants_alter(&$grants, $account, $op) {
  if ($op == 'view') {
    // Check we are on a course take page, so we aren't granting access to the
    // node view page of quiz questions.
    if (arg(0) == 'node' && is_numeric(arg(1)) && arg(2) == 'take') {
      $node = node_load(arg(1));
      if ($node->type == 'quiz') {
        // Confirm we're not granting access to just about anybody.
        if (user_access('access logged in content')) {
          $grants['quiz_question'][] = 1;
        }
      }
    }
  }
}

note. replace "MY_MODULE" with your module name.

This does however seem to be a bit of a blunt tool and could have access bypass security implications.

I don't know if any other modules are affected by the same issue, I haven't tried it with entity reference, field collection etc.

Is it worth considering that maybe using the grants system to restrict access to the node view page isn't the only/best solution. Possibly we could use the menu access system to do the same thing without the unpredictable effects on other modules.

Comments

PQ created an issue. See original summary.

djdevin’s picture

Do you know why paragraphs module is using node access? It's a field so I'm wondering why it's checking that instead of something like field access. I haven't seen any other field module use a node access check.

PQ’s picture

Not sure, could be just a belt and braces approach to access hardening. I've raised an issue on the paragraphs queue asking exactly that:

#2768257: Consider using field_access instead of entity_access for 'view' op in paragraphs_paragraphs_item_access()

PQ’s picture

Issue summary: View changes

Just edited the code workaround as it previously used menu_get_item() to check if the current path was a quiz take path but in some circumstances that was causing an infinite loop since menu_get_item() can ultimately call node_access().

neubreed’s picture

Oh boy! Thanks so much I spent an entire day wondering what the issue was. Cheers for the workaround!