diff options
-rw-r--r-- | modules/node/node.module | 28 | ||||
-rw-r--r-- | modules/node/node.test | 95 | ||||
-rw-r--r-- | modules/system/system.install | 17 |
3 files changed, 118 insertions, 22 deletions
diff --git a/modules/node/node.module b/modules/node/node.module index fff04872a..4c3141b25 100644 --- a/modules/node/node.module +++ b/modules/node/node.module @@ -1294,6 +1294,10 @@ function node_permission() { 'title' => t('Delete revisions'), 'description' => t('Delete content revisions.'), ), + 'view own unpublished content' => array( + 'title' => t('View own unpublished content'), + 'description' => t('View unpublished content created by the user'), + ), ); foreach (node_type_get_types() as $type) { @@ -2271,17 +2275,22 @@ function node_access($op, $node, $account = NULL) { return $access; } + // Check if authors can view their own unpublished nodes. + if ($op == 'view' && !$node->status && user_access('view own unpublished content', $account) && $account->uid == $node->uid && $account->uid != 0) { + return TRUE; + } + // If the module did not override the access rights, use those set in the // node_access table. - if ($op != 'create' && $node->nid && $node->status) { + if ($op != 'create' && $node->nid) { $query = db_select('node_access'); $query->addExpression('COUNT(*)'); - $query - ->condition(db_or() - ->condition('nid', 0) - ->condition('nid', $node->nid) - ) - ->condition('grant_' . $op, 1, '>='); + $query->condition('grant_' . $op, 1, '>='); + $nids = db_or()->condition('nid', $node->nid); + if ($node->status) { + $nids->condition('nid', 0); + } + $query->condition($nids); $grants = db_or(); foreach (node_access_grants($op, $account) as $realm => $gids) { @@ -2300,11 +2309,6 @@ function node_access($op, $node, $account = NULL) { ->fetchField(); } - // Let authors view their own nodes. - if ($op == 'view' && $account->uid == $node->uid && $account->uid != 0) { - return TRUE; - } - return FALSE; } diff --git a/modules/node/node.test b/modules/node/node.test index 1d2abd69e..be6152171 100644 --- a/modules/node/node.test +++ b/modules/node/node.test @@ -392,7 +392,7 @@ class SummaryLengthTestCase extends DrupalWebTestCase { // The node teaser when it has 600 characters in length $expected = 'What is a Drupalism?'; $this->assertRaw($expected, t('Check that the summary is 600 characters in length'), 'Node'); - + // Edit the teaser lenght for 'page' content type $edit = array ( 'teaser_length' => 200, @@ -587,13 +587,80 @@ class NodeRSSContentTestCase extends DrupalWebTestCase { } /** - * Test case to verify hook_node_access_records_alter functionality. + * Test case to verify basic node_access functionality. + * @todo Cover hook_access in a separate test class. + * hook_node_access_records is covered in another test class. */ -class NodeAccessRecordsAlterUnitTest extends DrupalWebTestCase { +class NodeAccessUnitTest extends DrupalWebTestCase { public static function getInfo() { return array( - 'name' => t('Node access records alter'), - 'description' => t('Test hook_node_access_records_alter when acquiring grants.'), + 'name' => t('Node access'), + 'description' => t('Test node_access function'), + 'group' => t('Node'), + ); + } + + /** + * Asserts node_access correctly grants or denies access. + */ + function assertNodeAccess($ops, $node, $account) { + foreach ($ops as $op => $result) { + $msg = t("node_access returns @result with operation '@op'.", array('@result' => $result ? 'true' : 'false', '@op' => $op)); + $this->assertEqual($result, node_access($op, $node, $account), $msg); + } + } + + function setUp() { + parent::setUp(); + // Clear permissions for authenticated users. + db_delete('role_permission') + ->condition('rid', DRUPAL_AUTHENTICATED_RID) + ->execute(); + } + + /** + * Runs basic tests for node_access function. + */ + function testNodeAccess() { + // Ensures user without 'access content' permission can do nothing. + $web_user1 = $this->drupalCreateUser(array('create page content', 'edit any page content', 'delete any page content')); + $node1 = $this->drupalCreateNode(array('type' => 'page')); + $this->assertNodeAccess(array('create' => FALSE), 'page', $web_user1); + $this->assertNodeAccess(array('view' => FALSE, 'update' => FALSE, 'delete' => FALSE), $node1, $web_user1); + + // Ensures user with 'bypass node access' permission can do everything. + $web_user2 = $this->drupalCreateUser(array('bypass node access')); + $node2 = $this->drupalCreateNode(array('type' => 'page')); + $this->assertNodeAccess(array('create' => TRUE), 'page', $web_user2); + $this->assertNodeAccess(array('view' => TRUE, 'update' => TRUE, 'delete' => TRUE), $node2, $web_user2); + + // User cannot 'view own unpublished content'. + $web_user3 = $this->drupalCreateUser(array('access content')); + $node3 = $this->drupalCreateNode(array('status' => 0, 'uid' => $web_user3->uid)); + $this->assertNodeAccess(array('view' => FALSE), $node3, $web_user3); + + // User can 'view own unpublished content', but another user cannot. + $web_user4 = $this->drupalCreateUser(array('access content', 'view own unpublished content')); + $web_user5 = $this->drupalCreateUser(array('access content', 'view own unpublished content')); + $node4 = $this->drupalCreateNode(array('status' => 0, 'uid' => $web_user4->uid)); + $this->assertNodeAccess(array('view' => TRUE, 'update' => FALSE), $node4, $web_user4); + $this->assertNodeAccess(array('view' => FALSE), $node4, $web_user5); + + // Tests the default access provided for a published node. + $node5 = $this->drupalCreateNode(); + $this->assertNodeAccess(array('create' => FALSE), 'page', $web_user3); + $this->assertNodeAccess(array('view' => TRUE, 'update' => FALSE, 'delete' => FALSE), $node5, $web_user3); + } +} + +/** + * Test case to verify hook_node_access_records functionality. + */ +class NodeAccessRecordsUnitTest extends DrupalWebTestCase { + public static function getInfo() { + return array( + 'name' => t('Node access records'), + 'description' => t('Test hook_node_access_records when acquiring grants.'), 'group' => t('Node'), ); } @@ -608,7 +675,7 @@ class NodeAccessRecordsAlterUnitTest extends DrupalWebTestCase { /** * Create a node and test the creation of node access rules. */ - function testGrantAlter() { + function testNodeAccessRecords() { // Create an article node. $node1 = $this->drupalCreateNode(array('type' => 'article')); $this->assertTrue(node_load($node1->nid), t('Article node created.')); @@ -629,13 +696,23 @@ class NodeAccessRecordsAlterUnitTest extends DrupalWebTestCase { $this->assertEqual($records[0]->realm, 'test_page_realm', t('Grant with page_realm acquired for node without alteration.')); $this->assertEqual($records[0]->gid, 1, t('Grant with gid = 1 acquired for node without alteration.')); + // Create an unpromoted, unpublished page node. + $node3 = $this->drupalCreateNode(array('type' => 'page', 'promote' => 0, 'status' => 0)); + $this->assertTrue(node_load($node3->nid), t('Unpromoted, unpublished page node created.')); + + // Check to see if grants added by node_test_node_access_records made it in. + $records = db_query('SELECT realm, gid FROM {node_access} WHERE nid = %d', $node3->nid)->fetchAll(); + $this->assertEqual(count($records), 1, t('Returned the correct number of rows.')); + $this->assertEqual($records[0]->realm, 'test_page_realm', t('Grant with page_realm acquired for node without alteration.')); + $this->assertEqual($records[0]->gid, 1, t('Grant with gid = 1 acquired for node without alteration.')); + // Create a promoted page node. - $node3 = $this->drupalCreateNode(array('type' => 'page', 'promote' => 1)); - $this->assertTrue(node_load($node3->nid), t('Promoted page node created.')); + $node4 = $this->drupalCreateNode(array('type' => 'page', 'promote' => 1)); + $this->assertTrue(node_load($node4->nid), t('Promoted page node created.')); // Check to see if grant added by node_test_node_access_records was altered // by node_test_node_access_records_alter. - $records = db_query('SELECT realm, gid FROM {node_access} WHERE nid = %d', $node3->nid)->fetchAll(); + $records = db_query('SELECT realm, gid FROM {node_access} WHERE nid = %d', $node4->nid)->fetchAll(); $this->assertEqual(count($records), 1, t('Returned the correct number of rows.')); $this->assertEqual($records[0]->realm, 'test_alter_realm', t('Altered grant with alter_realm acquired for node.')); $this->assertEqual($records[0]->gid, 2, t('Altered grant with gid = 2 acquired for node.')); diff --git a/modules/system/system.install b/modules/system/system.install index 3062a58fd..c1ab41c16 100644 --- a/modules/system/system.install +++ b/modules/system/system.install @@ -407,7 +407,7 @@ function system_install() { )); // Authenticated role permissions. - foreach (array('access comments', 'access content', 'post comments', 'post comments without approval') as $permission) { + foreach (array('access comments', 'access content', 'post comments', 'post comments without approval', 'view own unpublished content') as $permission) { $query->values(array( 'rid' => DRUPAL_AUTHENTICATED_RID, 'permission' => $permission, @@ -2226,6 +2226,21 @@ function system_update_7028() { } /** + * Add new 'view own unpublished content' permission for authenticated users. + * Preserves legacy behavior from Drupal 6.x. + */ +function system_update_7029() { + $ret = array(); + db_insert('role_permission') + ->fields(array( + 'rid' => DRUPAL_AUTHENTICATED_RID, + 'permission' => 'view own unpublished content', + )) + ->execute(); + return $ret; +} + +/** * @} End of "defgroup updates-6.x-to-7.x" * The next series of updates should start at 8000. */ |