t('[226853] upload.module hard-codes \'upload files\' permission check'),
'desc' => t('The short version: _upload_form() should be using a form #access property to set its requirement for upload files permission, and not hard-code it in the module logic. Because it does not do this, the only way to extend this form from a contributed module is to hack core.'),
'group' => t('Drupal 7 Tests'),
);
}
function testIssue() {
$this->drupalModuleEnable('upload');
// A module makes new own permission and implements hook_form_alter()
$module_name = $this->randomName();
$module_text = <<< EOF
t('Attach files to content to something {$module_name} related.'),
);
}
function {$module_name}_form_alter(&\$form, \$form_state, \$form_id) {
if (\$form_id == '{$module_name}_form') {
\$obj->files = array();
\$form['attachments'] = array(
'#type' => 'fieldset',
'#title' => t('File attachments'),
'#access' => user_access('upload files to {$module_name}') || user_access('upload files'),
'#collapsible' => TRUE,
'#collapsed' => empty(\$obj->files),
'#description' => t('Changes made to the attachments are not permanent until you save this post. The first "listed" file will be included in RSS feeds.'),
'#prefix' => '
',
'#suffix' => '
',
'#weight' => 10,
);
// Wrapper for fieldset contents (used by ahah.js).
\$form['attachments']['wrapper'] = array(
'#prefix' => '',
'#suffix' => '
',
);
\$form['attachments']['wrapper'] += _upload_form(\$obj);
if (isset(\$form['attachments']['wrapper']['#access'])) {
\$form['attachments']['wrapper']['#access'] |= user_access('upload files to {$module_name}');
}
\$form['#attributes']['enctype'] = 'multipart/form-data';
}
}
EOF;
$this->createModule($module_name, $module_text);
// check for a user has only 'upload files' permission
$this->checkPowerfulRole($module_name);
// check for a user has only module's permission
$this->checkModuleRole($module_name);
// check for a user has other permission
$this->checkRandomRole($module_name);
$this->deleteModule($module_name);
}
function createModule($module_name, $module_text, $module_core = '7.x') {
$module_dir = "sites/all/modules/$module_name";
$module_file = "$module_dir/$module_name.module";
$module_file_info = "$module_dir/$module_name.info";
if (file_check_directory($module_dir, FILE_CREATE_DIRECTORY)) {
$info = <<< EOF
name = "$module_name module"
description = "$module_name module for test. Delete it when you see it."
package = Temporary
core = $module_core
EOF;
if ($fp = @fopen($module_file_info, 'w')) {
fwrite($fp, $info);
fclose($fp);
}
if ($fp = @fopen($module_file, 'w')) {
fwrite($fp, $module_text);
fclose($fp);
}
$this->drupalModuleEnable($module_name);
}
}
function deleteModule($module_name) {
$module_dir = "sites/all/modules/$module_name";
$module_file = "$module_dir/$module_name.module";
$module_file_info = "$module_dir/$module_name.info";
@unlink($module_file);
@unlink($module_file_info);
@rmdir($module_dir);
}
// Check 'upload files' permission.
// Should pass so 'upload files' is very general
function checkPowerfulRole($module_name) {
// function _upload_form() uses a global $user
global $user;
$orig_user = $user;
$form = array();
// create a user for form's preparing
$user = $this->drupalCreateUserRolePerm(array("upload files"));
$this->drupalLoginUser($user);
// prepare the form (executing any hook_form_alter)
drupal_prepare_form("{$module_name}_form", $form, $form_state);
$this->assertTrue($this->checkAccess($form), "check generic 'upload files'");
$this->drupalGet('logout');
$user = $orig_user; // restore the original user
}
// Check permission for upload by module's permission.
// Should pass so module's permission checked in hook_form_alter()
// It checks the issue: the user don't have 'upload files' permission,
// but he have module's permission though.
function checkModuleRole($module_name) {
global $user;
$orig_user = $user;
$form = array();
$user = $this->drupalCreateUserRolePerm(array("upload files to {$module_name}"));
$this->drupalLoginUser($user);
drupal_prepare_form("{$module_name}_form", $form, $form_state);
$this->assertTrue($this->checkAccess($form), "check module's 'upload files to {$module_name}'");
$this->drupalGet('logout');
$user = $orig_user;
}
// Check random permission
// Should pass (assertFalse) so random permission does not allow file upload
function checkRandomRole($module_name) {
global $user;
$orig_user = $user;
$form = array();
$user = $this->drupalCreateUserRolePerm(array($this->randomName()));
$this->drupalLoginUser($user);
drupal_prepare_form("{$module_name}_form", $form, $form_state);
$this->assertFalse($this->checkAccess($form), "Check other roles");
$this->drupalGet('logout');
$user = $orig_user;
}
function checkAccess($form) {
return !empty($form['attachments']['#access']) && // access to attachments
isset($form['attachments']['wrapper']['new']); // is 'new' form exists?
!empty($form['attachments']['wrapper']['#access']); // access to wrapper
}
}