1

I'm using the Domain Access module to restrict content to specific domains. It uses the node_access table to do this.

I also want to make a single node hidden behind a login area. The problem is that when I add my node access rules to do this it overwrites all the Domain Access rules which mean that all the nodes appear on the same domain.

Is there a way to allow more than one module to use node access rules?

My node access code looks like this:

define('MYSITE_REALM', 'press');
define('MYSITE_GRANT_ID_PUBLIC', 0);
define('MYSITE_GRANT_ID_PRESS', 1);
define('MYSITE_PRESS_SECTION_NID', 554);
define('MYSITE_PRESS_USER', 'press');

/**
 * Implements hook_node_grants().
 */
function mysite_node_grants($account, $op) {
  if ($op == 'view') {
    $grants = array();

    if ($account->name == MYSITE_PRESS_USER) {
      $grants[MYSITE_REALM] = array(
        MYSITE_GRANT_ID_PUBLIC,
        MYSITE_GRANT_ID_PRESS,
      );
    }
        else {

      // everyone else
      $grants[MYSITE_REALM] = array(
        MYSITE_GRANT_ID_PUBLIC,
      );
    }

    return $grants;
  }
}


/**
 * Implements hook_access_records().
 */
function mysite_node_access_records($node) {
  $grants[] = array();

  if ($node->nid == MYSITE_PRESS_SECTION_NID) {
    $grants[] = array(
      'realm' => MYSITE_REALM,
      'gid' => MYSITE_GRANT_ID_PRESS,
      'grant_view' => 1,
      'grant_update' => 0,
      'grant_delete' => 0,
      'priority' => 0,
    );  
  }
    else {
    // everything else is public
    $grants[] = array(
        'realm' => MYSITE_REALM,
      'gid' => MYSITE_GRANT_ID_PUBLIC,
        'grant_view' => 1,
        'grant_update' => 0,
        'grant_delete' => 0,
        'priority' => 1,
    );
  }

  return $grants;
}

function mysite_user_login(&$edit, $account) {
  if ($account->name == MYSITE_PRESS_USER) {
    drupal_goto('node/' . MYSITE_PRESS_SECTION_NID);
  }
    else {
    drupal_goto('');
  }
}

1 Answer 1

3

Is there a way to allow more than one module to use node access rules?

The problem with hook_node_access_records() and hook_node_grants() is that, independently from the weight of the modules, once a module returns 1 for "grant_view," "grant_update," or "grant_delete" that permission is allowed to the user. If a module returns 1 for one of those operations, and another module returns 0, the access is allowed, independently from the priority given to the records returned from the modules for those records.

In Drupal 7 it is also possible to use hook_node_access(), which is able to report if the user has access or not to the node, or if the hook implementation let other implementations decide if the user has access to the node (using the value NODE_ACCESS_IGNORE).

In Node access rights it is explained how the node access is checked.

In determining access rights for a node, node_access() first checks whether the user has the "bypass node access" permission. Such users have unrestricted access to all nodes. User 1 will always pass this check.

Next, all implementations of hook_node_access() will be called. Each implementation may explicitly allow, explicitly deny, or ignore the access request. If at least one module says to deny the request, it will be rejected. If no modules deny the request and at least one says to allow it, the request will be permitted.

If all modules ignore the access request, then the node_access table is used to determine access. All node access modules are queried using hook_node_grants() to assemble a list of "grant IDs" for the user. This list is compared against the table. If any row contains the node ID in question (or 0, which stands for "all nodes"), one of the grant IDs returned, and a value of TRUE for the operation in question, then access is granted. Note that this table is a list of grants; any matching row is sufficient to grant access to the node.

1
  • Fantastic exactly what I was looking for.
    – Camsoft
    Commented Jul 28, 2011 at 10:56

Your Answer

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

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