3 namespace Drupal\KernelTests\Core\File;
5 use Drupal\Component\Utility\SafeMarkup;
6 use Drupal\Core\Site\Settings;
7 use Drupal\KernelTests\KernelTestBase;
10 * Tests .htaccess file saving.
14 class HtaccessTest extends KernelTestBase {
17 * Tests file_save_htaccess().
19 public function testHtaccessSave() {
20 // Prepare test directories.
21 $public = Settings::get('file_public_path') . '/test/public';
22 $private = Settings::get('file_public_path') . '/test/private';
23 $stream = 'public://test/stream';
25 // Verify that file_save_htaccess() returns FALSE if .htaccess cannot be
27 // Note: We cannot test the condition of a directory lacking write
28 // permissions, since at least on Windows file_save_htaccess() succeeds
29 // even when changing directory permissions to 0000.
30 $this->assertFalse(file_save_htaccess($public, FALSE));
32 // Create public .htaccess file.
33 mkdir($public, 0777, TRUE);
34 $this->assertTrue(file_save_htaccess($public, FALSE));
35 $content = file_get_contents($public . '/.htaccess');
36 $this->assertTrue(strpos($content, "SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006") !== FALSE);
37 $this->assertFalse(strpos($content, "Require all denied") !== FALSE);
38 $this->assertFalse(strpos($content, "Deny from all") !== FALSE);
39 $this->assertTrue(strpos($content, "Options -Indexes -ExecCGI -Includes -MultiViews") !== FALSE);
40 $this->assertTrue(strpos($content, "SetHandler Drupal_Security_Do_Not_Remove_See_SA_2013_003") !== FALSE);
41 $this->assertFilePermissions($public . '/.htaccess', 0444);
43 $this->assertTrue(file_save_htaccess($public, FALSE));
45 // Create private .htaccess file.
46 mkdir($private, 0777, TRUE);
47 $this->assertTrue(file_save_htaccess($private));
48 $content = file_get_contents($private . '/.htaccess');
49 $this->assertTrue(strpos($content, "SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006") !== FALSE);
50 $this->assertTrue(strpos($content, "Require all denied") !== FALSE);
51 $this->assertTrue(strpos($content, "Deny from all") !== FALSE);
52 $this->assertTrue(strpos($content, "Options -Indexes -ExecCGI -Includes -MultiViews") !== FALSE);
53 $this->assertTrue(strpos($content, "SetHandler Drupal_Security_Do_Not_Remove_See_SA_2013_003") !== FALSE);
54 $this->assertFilePermissions($private . '/.htaccess', 0444);
56 $this->assertTrue(file_save_htaccess($private));
58 // Create an .htaccess file using a stream URI.
59 mkdir($stream, 0777, TRUE);
60 $this->assertTrue(file_save_htaccess($stream));
61 $content = file_get_contents($stream . '/.htaccess');
62 $this->assertTrue(strpos($content, "SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006") !== FALSE);
63 $this->assertTrue(strpos($content, "Require all denied") !== FALSE);
64 $this->assertTrue(strpos($content, "Deny from all") !== FALSE);
65 $this->assertTrue(strpos($content, "Options -Indexes -ExecCGI -Includes -MultiViews") !== FALSE);
66 $this->assertTrue(strpos($content, "SetHandler Drupal_Security_Do_Not_Remove_See_SA_2013_003") !== FALSE);
67 $this->assertFilePermissions($stream . '/.htaccess', 0444);
69 $this->assertTrue(file_save_htaccess($stream));
73 * Asserts expected file permissions for a given file.
76 * The URI of the file to check.
77 * @param int $expected
78 * The expected file permissions; e.g., 0444.
81 * Whether the actual file permissions match the expected.
83 protected function assertFilePermissions($uri, $expected) {
84 $actual = fileperms($uri) & 0777;
85 return $this->assertIdentical($actual, $expected, SafeMarkup::format('@uri file permissions @actual are identical to @expected.', [
87 '@actual' => 0 . decoct($actual),
88 '@expected' => 0 . decoct($expected),