From 40093b2fa7dde4a5f3c6806aad91b9302c232903 Mon Sep 17 00:00:00 2001 From: webchick Date: Wed, 1 Feb 2012 13:29:51 -0800 Subject: SA-CORE-2012-001 --- modules/file/file.api.php | 12 ++++++------ modules/file/file.module | 25 ++++++++++++++----------- modules/file/tests/file.test | 15 ++++++++++++++- 3 files changed, 34 insertions(+), 18 deletions(-) (limited to 'modules/file') diff --git a/modules/file/file.api.php b/modules/file/file.api.php index 76fb98610..663682033 100644 --- a/modules/file/file.api.php +++ b/modules/file/file.api.php @@ -12,8 +12,8 @@ * file is referenced, e.g., only users with access to a node should be allowed * to download files attached to that node. * - * @param $field - * The field to which the file belongs. + * @param array $file_item + * The array of information about the file to check access for. * @param $entity_type * The type of $entity; for example, 'node' or 'user'. * @param $entity @@ -26,7 +26,7 @@ * * @see hook_field_access(). */ -function hook_file_download_access($field, $entity_type, $entity) { +function hook_file_download_access($file_item, $entity_type, $entity) { if ($entity_type == 'node') { return node_access('view', $entity); } @@ -45,8 +45,8 @@ function hook_file_download_access($field, $entity_type, $entity) { * An array of grants gathered by hook_file_download_access(). The array is * keyed by the module that defines the entity type's access control; the * values are Boolean grant responses for each module. - * @param $field - * The field to which the file belongs. + * @param array $file_item + * The array of information about the file to alter access for. * @param $entity_type * The type of $entity; for example, 'node' or 'user'. * @param $entity @@ -58,7 +58,7 @@ function hook_file_download_access($field, $entity_type, $entity) { * module's value in addition to other grants or to overwrite the values set by * other modules. */ -function hook_file_download_access_alter(&$grants, $field, $entity_type, $entity) { +function hook_file_download_access_alter(&$grants, $file_item, $entity_type, $entity) { // For our example module, we always enforce the rules set by node module. if (isset($grants['node'])) { $grants = array('node' => $grants['node']); diff --git a/modules/file/file.module b/modules/file/file.module index 5d7b17af5..83e960017 100644 --- a/modules/file/file.module +++ b/modules/file/file.module @@ -165,24 +165,27 @@ function file_file_download($uri, $field_type = 'file') { // Try to load $entity and $field. $entity = entity_load($entity_type, array($id)); $entity = reset($entity); - $field = NULL; + $field = field_info_field($field_name); + + // Load the field item that references the file. + $field_item = NULL; if ($entity) { - // Load all fields for that entity. + // Load all field items for that entity. $field_items = field_get_items($entity_type, $entity, $field_name); // Find the field item with the matching URI. - foreach ($field_items as $field_item) { - if ($field_item['uri'] == $uri) { - $field = $field_item; + foreach ($field_items as $item) { + if ($item['uri'] == $uri) { + $field_item = $item; break; } } } - // Check that $entity and $field were loaded successfully and check if - // access to that field is not disallowed. If any of these checks fail, - // stop checking access for this reference. - if (empty($entity) || empty($field) || !field_access('view', $field, $entity_type, $entity)) { + // Check that $entity, $field and $field_item were loaded successfully + // and check if access to that field is not disallowed. If any of these + // checks fail, stop checking access for this reference. + if (empty($entity) || empty($field) || empty($field_item) || !field_access('view', $field, $entity_type, $entity)) { $denied = TRUE; break; } @@ -191,10 +194,10 @@ function file_file_download($uri, $field_type = 'file') { // Default to FALSE and let entities overrule this ruling. $grants = array('system' => FALSE); foreach (module_implements('file_download_access') as $module) { - $grants = array_merge($grants, array($module => module_invoke($module, 'file_download_access', $field, $entity_type, $entity))); + $grants = array_merge($grants, array($module => module_invoke($module, 'file_download_access', $field_item, $entity_type, $entity))); } // Allow other modules to alter the returned grants/denies. - drupal_alter('file_download_access', $grants, $field, $entity_type, $entity); + drupal_alter('file_download_access', $grants, $field_item, $entity_type, $entity); if (in_array(TRUE, $grants)) { // If TRUE is returned, access is granted and no further checks are diff --git a/modules/file/tests/file.test b/modules/file/tests/file.test index 59f6e0cb0..324faffc4 100644 --- a/modules/file/tests/file.test +++ b/modules/file/tests/file.test @@ -1107,7 +1107,7 @@ class FilePrivateTestCase extends FileFieldTestCase { } function setUp() { - parent::setUp('node_access_test'); + parent::setUp(array('node_access_test', 'field_test')); node_access_rebuild(); variable_set('node_access_test_private', TRUE); } @@ -1124,6 +1124,10 @@ class FilePrivateTestCase extends FileFieldTestCase { $field_name = strtolower($this->randomName()); $this->createFileField($field_name, $type_name, array('uri_scheme' => 'private')); + // Create a field with no view access - see field_test_field_access(). + $no_access_field_name = 'field_no_view_access'; + $this->createFileField($no_access_field_name, $type_name, array('uri_scheme' => 'private')); + $test_file = $this->getTestFile('text'); $nid = $this->uploadNodeFile($test_file, $field_name, $type_name, TRUE, array('private' => TRUE)); $node = node_load($nid, NULL, TRUE); @@ -1134,5 +1138,14 @@ class FilePrivateTestCase extends FileFieldTestCase { $this->drupalLogOut(); $this->drupalGet(file_create_url($node_file->uri)); $this->assertResponse(403, t('Confirmed that access is denied for the file without the needed permission.')); + + // Test with the field that should deny access through field access. + $this->drupalLogin($this->admin_user); + $nid = $this->uploadNodeFile($test_file, $no_access_field_name, $type_name, TRUE, array('private' => TRUE)); + $node = node_load($nid, NULL, TRUE); + $node_file = (object) $node->{$no_access_field_name}[LANGUAGE_NONE][0]; + // Ensure the file cannot be downloaded. + $this->drupalGet(file_create_url($node_file->uri)); + $this->assertResponse(403, t('Confirmed that access is denied for the file without view field access permission.')); } } -- cgit v1.2.3