3 namespace Drupal\Tests\system\Functional\System;
5 use Drupal\Component\Render\FormattableMarkup;
6 use Drupal\Core\Site\Settings;
7 use Drupal\Core\StringTranslation\StringTranslationTrait;
8 use Drupal\Tests\BrowserTestBase;
11 * Tests Drupal permissions hardening of /sites subdirectories.
15 class SitesDirectoryHardeningTest extends BrowserTestBase {
16 use StringTranslationTrait;
19 * Tests the default behavior to restrict directory permissions is enforced.
21 * Checks both the the current sites directory and settings.php.
23 public function testSitesDirectoryHardening() {
24 $site_path = $this->kernel->getSitePath();
25 $settings_file = $this->settingsFile($site_path);
27 // First, we check based on what the initial install has set.
28 $this->assertTrue(drupal_verify_install_file($site_path, FILE_NOT_WRITABLE, 'dir'), new FormattableMarkup('Verified permissions for @file.', ['@file' => $site_path]));
30 // We intentionally don't check for settings.local.php as that file is
31 // not created by Drupal.
32 $this->assertTrue(drupal_verify_install_file($settings_file, FILE_EXIST | FILE_READABLE | FILE_NOT_WRITABLE), new FormattableMarkup('Verified permissions for @file.', ['@file' => $settings_file]));
34 $this->makeWritable($site_path);
35 $this->checkSystemRequirements();
37 $this->assertTrue(drupal_verify_install_file($site_path, FILE_NOT_WRITABLE, 'dir'), new FormattableMarkup('Verified permissions for @file after manual permissions change.', ['@file' => $site_path]));
38 $this->assertTrue(drupal_verify_install_file($settings_file, FILE_EXIST | FILE_READABLE | FILE_NOT_WRITABLE), new FormattableMarkup('Verified permissions for @file after manual permissions change.', ['@file' => $settings_file]));
42 * Tests writable files remain writable when directory hardening is disabled.
44 public function testSitesDirectoryHardeningConfig() {
45 $site_path = $this->kernel->getSitePath();
46 $settings_file = $this->settingsFile($site_path);
48 // Disable permissions enforcement.
49 $settings = Settings::getAll();
50 $settings['skip_permissions_hardening'] = TRUE;
51 new Settings($settings);
52 $this->assertTrue(Settings::get('skip_permissions_hardening'), 'Able to set hardening to true');
53 $this->makeWritable($site_path);
55 // Manually trigger the requirements check.
56 $requirements = $this->checkSystemRequirements();
57 $this->assertEqual(REQUIREMENT_WARNING, $requirements['configuration_files']['severity'], 'Warning severity is properly set.');
58 $this->assertEqual($this->t('Protection disabled'), (string) $requirements['configuration_files']['description']['#context']['configuration_error_list']['#items'][0], 'Description is properly set.');
60 $this->assertTrue(is_writable($site_path), 'Site directory remains writable when automatically fixing permissions is disabled.');
61 $this->assertTrue(is_writable($settings_file), 'settings.php remains writable when automatically fixing permissions is disabled.');
63 // Re-enable permissions enforcement.
64 $settings = Settings::getAll();
65 $settings['skip_permissions_hardening'] = FALSE;
66 new Settings($settings);
68 // Manually trigger the requirements check.
69 $this->checkSystemRequirements();
71 $this->assertFalse(is_writable($site_path), 'Site directory is protected when automatically fixing permissions is enabled.');
72 $this->assertFalse(is_writable($settings_file), 'settings.php is protected when automatically fixing permissions is enabled.');
76 * Checks system runtime requirements.
79 * An array of system requirements.
81 protected function checkSystemRequirements() {
82 module_load_install('system');
83 return system_requirements('runtime');
87 * Makes the given path and settings file writable.
89 * @param string $site_path
90 * The sites directory path, such as 'sites/default'.
92 protected function makeWritable($site_path) {
93 chmod($site_path, 0755);
94 chmod($this->settingsFile($site_path), 0644);
98 * Returns the path to settings.php
100 * @param string $site_path
101 * The sites subdirectory path.
104 * The path to settings.php.
106 protected function settingsFile($site_path) {
107 $settings_file = $site_path . '/settings.php';
108 return $settings_file;