Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace Drupal\system\Tests\System;
|
Chris@0
|
4
|
Chris@0
|
5 use Drupal\simpletest\WebTestBase;
|
Chris@0
|
6
|
Chris@0
|
7 /**
|
Chris@0
|
8 * Tests .htaccess is working correctly.
|
Chris@0
|
9 *
|
Chris@0
|
10 * @group system
|
Chris@0
|
11 */
|
Chris@0
|
12 class HtaccessTest extends WebTestBase {
|
Chris@0
|
13
|
Chris@0
|
14 /**
|
Chris@0
|
15 * Modules to enable.
|
Chris@0
|
16 *
|
Chris@0
|
17 * @var array
|
Chris@0
|
18 */
|
Chris@0
|
19 public static $modules = ['node', 'path'];
|
Chris@0
|
20
|
Chris@0
|
21 /**
|
Chris@0
|
22 * Get an array of file paths for access testing.
|
Chris@0
|
23 *
|
Chris@0
|
24 * @return int[]
|
Chris@0
|
25 * An array keyed by file paths. Each value is the expected response code,
|
Chris@0
|
26 * for example, 200 or 403.
|
Chris@0
|
27 */
|
Chris@0
|
28 protected function getProtectedFiles() {
|
Chris@0
|
29 $path = drupal_get_path('module', 'system') . '/tests/fixtures/HtaccessTest';
|
Chris@0
|
30
|
Chris@0
|
31 // Tests the FilesMatch directive which denies access to certain file
|
Chris@0
|
32 // extensions.
|
Chris@0
|
33 $file_exts_to_deny = [
|
Chris@0
|
34 'engine',
|
Chris@0
|
35 'inc',
|
Chris@0
|
36 'install',
|
Chris@0
|
37 'make',
|
Chris@0
|
38 'module',
|
Chris@0
|
39 'module~',
|
Chris@0
|
40 'module.bak',
|
Chris@0
|
41 'module.orig',
|
Chris@0
|
42 'module.save',
|
Chris@0
|
43 'module.swo',
|
Chris@0
|
44 'module.swp',
|
Chris@0
|
45 'php~',
|
Chris@0
|
46 'php.bak',
|
Chris@0
|
47 'php.orig',
|
Chris@0
|
48 'php.save',
|
Chris@0
|
49 'php.swo',
|
Chris@0
|
50 'php.swp',
|
Chris@0
|
51 'profile',
|
Chris@0
|
52 'po',
|
Chris@0
|
53 'sh',
|
Chris@0
|
54 'sql',
|
Chris@0
|
55 'theme',
|
Chris@0
|
56 'twig',
|
Chris@0
|
57 'tpl.php',
|
Chris@0
|
58 'xtmpl',
|
Chris@0
|
59 'yml',
|
Chris@0
|
60 ];
|
Chris@0
|
61
|
Chris@0
|
62 foreach ($file_exts_to_deny as $file_ext) {
|
Chris@0
|
63 $file_paths["$path/access_test.$file_ext"] = 403;
|
Chris@0
|
64 }
|
Chris@0
|
65
|
Chris@0
|
66 // Tests the .htaccess file in vendor and created by a Composer script.
|
Chris@0
|
67 // Try and access a non PHP file in the vendor directory.
|
Chris@0
|
68 // @see Drupal\\Core\\Composer\\Composer::ensureHtaccess
|
Chris@0
|
69 $file_paths['vendor/composer/installed.json'] = 403;
|
Chris@0
|
70
|
Chris@0
|
71 // Tests the rewrite conditions and rule that denies access to php files.
|
Chris@0
|
72 $file_paths['core/lib/Drupal.php'] = 403;
|
Chris@0
|
73 $file_paths['vendor/autoload.php'] = 403;
|
Chris@0
|
74 $file_paths['autoload.php'] = 403;
|
Chris@0
|
75
|
Chris@0
|
76 // Test extensions that should be permitted.
|
Chris@0
|
77 $file_exts_to_allow = [
|
Chris@0
|
78 'php-info.txt'
|
Chris@0
|
79 ];
|
Chris@0
|
80
|
Chris@0
|
81 foreach ($file_exts_to_allow as $file_ext) {
|
Chris@0
|
82 $file_paths["$path/access_test.$file_ext"] = 200;
|
Chris@0
|
83 }
|
Chris@0
|
84
|
Chris@0
|
85 // Ensure composer.json and composer.lock cannot be accessed.
|
Chris@0
|
86 $file_paths["$path/composer.json"] = 403;
|
Chris@0
|
87 $file_paths["$path/composer.lock"] = 403;
|
Chris@0
|
88
|
Chris@0
|
89 return $file_paths;
|
Chris@0
|
90 }
|
Chris@0
|
91
|
Chris@0
|
92 /**
|
Chris@0
|
93 * Iterates over protected files and calls assertNoFileAccess().
|
Chris@0
|
94 */
|
Chris@0
|
95 public function testFileAccess() {
|
Chris@0
|
96 foreach ($this->getProtectedFiles() as $file => $response_code) {
|
Chris@0
|
97 $this->assertFileAccess($file, $response_code);
|
Chris@0
|
98 }
|
Chris@0
|
99
|
Chris@0
|
100 // Test that adding "/1" to a .php URL does not make it accessible.
|
Chris@0
|
101 $this->drupalGet('core/lib/Drupal.php/1');
|
Chris@0
|
102 $this->assertResponse(403, "Access to core/lib/Drupal.php/1 is denied.");
|
Chris@0
|
103
|
Chris@0
|
104 // Test that it is possible to have path aliases containing .php.
|
Chris@0
|
105 $type = $this->drupalCreateContentType();
|
Chris@0
|
106
|
Chris@0
|
107 // Create an node aliased to test.php.
|
Chris@0
|
108 $node = $this->drupalCreateNode([
|
Chris@0
|
109 'title' => 'This is a node',
|
Chris@0
|
110 'type' => $type->id(),
|
Chris@0
|
111 'path' => '/test.php'
|
Chris@0
|
112 ]);
|
Chris@0
|
113 $node->save();
|
Chris@0
|
114 $this->drupalGet('test.php');
|
Chris@0
|
115 $this->assertResponse(200);
|
Chris@0
|
116 $this->assertText('This is a node');
|
Chris@0
|
117
|
Chris@0
|
118 // Update node's alias to test.php/test.
|
Chris@0
|
119 $node->path = '/test.php/test';
|
Chris@0
|
120 $node->save();
|
Chris@0
|
121 $this->drupalGet('test.php/test');
|
Chris@0
|
122 $this->assertResponse(200);
|
Chris@0
|
123 $this->assertText('This is a node');
|
Chris@0
|
124 }
|
Chris@0
|
125
|
Chris@0
|
126 /**
|
Chris@0
|
127 * Asserts that a file exists and requesting it returns a specific response.
|
Chris@0
|
128 *
|
Chris@0
|
129 * @param string $path
|
Chris@0
|
130 * Path to file. Without leading slash.
|
Chris@0
|
131 * @param int $response_code
|
Chris@0
|
132 * The expected response code. For example: 200, 403 or 404.
|
Chris@0
|
133 *
|
Chris@0
|
134 * @return bool
|
Chris@0
|
135 * TRUE if the assertion succeeded, FALSE otherwise.
|
Chris@0
|
136 */
|
Chris@0
|
137 protected function assertFileAccess($path, $response_code) {
|
Chris@0
|
138 $result = $this->assertTrue(file_exists(\Drupal::root() . '/' . $path), "The file $path exists.");
|
Chris@0
|
139 $this->drupalGet($path);
|
Chris@0
|
140 $result = $result && $this->assertResponse($response_code, "Response code to $path is $response_code.");
|
Chris@0
|
141 return $result;
|
Chris@0
|
142 }
|
Chris@0
|
143
|
Chris@0
|
144 /**
|
Chris@0
|
145 * Tests that SVGZ files are served with Content-Encoding: gzip.
|
Chris@0
|
146 */
|
Chris@0
|
147 public function testSvgzContentEncoding() {
|
Chris@0
|
148 $this->drupalGet('core/modules/system/tests/logo.svgz');
|
Chris@0
|
149 $this->assertResponse(200);
|
Chris@0
|
150 $header = $this->drupalGetHeader('Content-Encoding');
|
Chris@0
|
151 $this->assertEqual($header, 'gzip');
|
Chris@0
|
152 }
|
Chris@0
|
153
|
Chris@0
|
154 }
|