'Node access across referenced nodes', 'description' => 'Tests that node access checks get applied to the node base table across referenced fields.', 'group' => 'Node', ); } public function setUp() { parent::setUp(); node_access_rebuild(); variable_set('node_access_test_private', TRUE); // Create some users. $this->admin_user = $this->drupalCreateUser(array('access content', 'bypass node access')); $this->user = $this->drupalCreateUser(array('access content')); // Add a custom field to the page content type. $this->field_name = drupal_strtolower($this->randomName() . '_field_name'); $this->field = field_create_field(array('field_name' => $this->field_name, 'type' => 'number_integer')); $instance = array( 'field_name' => $this->field_name, 'entity_type' => 'node', 'bundle' => 'page', ); $this->instance = field_create_instance($instance); } /** * Tests administering fields when node access is restricted. * * Create admin user that can skip node access checks. * Create regular user that cannot see nodes subject to access checks. * * Create private node 1 that only admin user can see. * Create public node 2 that both users can see, with integer field that * references the private node 1. * Create public node 3 with nothing in the integer reference field. * Create a select query that shows nodes and the title from nodes related * through the integer field, and tag for node_access. * * Test that admin user gets all 3 nodes returned in the query, and that the * joined node appears in that node's result row. * Test that regular user gets two results returned, and that the joined node * does not appear in the public node's result row. * * Add a second instance of the integer reference field on node 2 that refers * to node 3. * Test that admin user gets 4 rows returned from query, two containing node 2. * * Test that regular user gets 2 rows returned from query, with node 2 listing * only the reference to node 3. * */ function testNodeAccessSubquery() { // Create a page node. $langcode = LANGUAGE_NOT_SPECIFIED; $field_data = array(); $this->drupalLogin($this->admin_user); $node1 = $this->drupalCreateNode(array('title'=>'Private node 1','private'=>true, 'status'=>0)); $value = $field_data[$langcode][0]['value'] = $node1->nid; $node2 = $this->drupalCreateNode(array('title' => 'Public node 2', $this->field_name => $field_data, 'private' => false, 'status'=>1)); $node3 = $this->drupalCreateNode(array('title' => 'Public node 3', 'private' => false, 'status'=>1)); $join_table = _field_sql_storage_tablename($this->field); $join_column = $this->field_name . '_value'; // Test #1349080 // Get Query object for query. $query = db_select('node', 'n'); $query->addTag('node_access'); // Tag for node access. //$query->addTag('node_access'); // Join on $join_table $query->addJoin('LEFT OUTER', $join_table, 'jf', 'n.vid = jf.revision_id'); // Now add subquery join $query->addJoin('LEFT OUTER', 'node', 's', 'jf.' . $join_column .' = s.nid'); $query->fields('n', array('nid', 'title')) ->fields('s', array('nid', 'title')); // test as admin_user $result1 = $query->execute(); $untagged = array(); while ($record = $result1->fetchAssoc()) { $untagged[] = $record; } $this->assertEqual(count($untagged), 3, 'Admin user gets 3 rows returned after initial load.'); $this->verbose('Admin query result: '. theme('table',array('header'=>array('nid','title','subquery_nid','subquery title'), 'rows'=>$untagged))); $this->drupalLogin($this->user); $result2 = $query->execute(); $tagged = array(); while ($record = $result2->fetchAssoc()) { $tagged[] = $record; } $this->assertEqual(count($tagged), 2, 'Regular user gets 2 rows returned after initial load. '.count($tagged)); $this->verbose('Regular user query result: '. theme('table',array('header'=>array('nid','title','subquery_nid','subquery title'), 'rows'=>$tagged))); return; // Log in as the administrator and confirm that the field value is present. $this->drupalLogin($this->admin_user); $this->drupalGet("node/{$node->nid}"); $this->assertText($value, 'The saved field value is visible to an administrator.'); // Log in as the content admin and try to view the node. $this->drupalLogin($this->content_admin_user); $this->drupalGet("node/{$node->nid}"); $this->assertText('Access denied', 'Access is denied for the content admin.'); // Modify the field default as the content admin. $edit = array(); $default = 'Sometimes words have two meanings'; $edit["{$this->field_name}[$langcode][0][value]"] = $default; $this->drupalPost( "admin/structure/types/manage/page/fields/{$this->field_name}", $edit, t('Save settings') ); // Log in as the administrator. $this->drupalLogin($this->admin_user); // Confirm that the existing node still has the correct field value. $this->drupalGet("node/{$node->nid}"); $this->assertText($value, 'The original field value is visible to an administrator.'); // Confirm that the new default value appears when creating a new node. $this->drupalGet('node/add/page'); $this->assertRaw($default, 'The updated default value is displayed when creating a new node.'); } }