Cleanup: Updated copyright comments
[Packages/TYPO3.CMS.git] / typo3 / sysext / felogin / tests / tx_feloginTest.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2010-2011 Helmut Hummel <helmut@typo3.org>
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 *
17 * This script is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
24
25
26 require_once t3lib_extMgm::extPath('felogin', 'pi1/class.tx_felogin_pi1.php');
27
28 /**
29 * Testcase for URL validation in class tx_felogin_pi1
30 *
31 * @author Helmut Hummel <helmut@typo3.org>
32 * @package TYPO3
33 * @subpackage tests/typo3/sysext/felogin
34 */
35 class tx_feloginTest extends tx_phpunit_testcase {
36
37 /**
38 * @var array
39 */
40 private $backupGlobalVariables;
41
42 /**
43 * @var tx_felogin_pi1
44 */
45 private $txFelogin;
46
47 /**
48 * @var string
49 */
50 private $testHostName;
51
52 /**
53 * @var string
54 */
55 private $testSitePath;
56
57 /**
58 * @var string
59 */
60 private $testTableName;
61
62 public function setUp() {
63 $this->backupGlobalVariables = array(
64 '_SERVER' => $_SERVER,
65 'TYPO3_DB' => $GLOBALS['TYPO3_DB'],
66 'TSFE' => $GLOBALS['TSFE'],
67 );
68
69 $this->testTableName = 'sys_domain';
70 $this->testHostName = 'hostname.tld';
71 $this->testSitePath = '/';
72
73 // we need to subclass because the method we want to test is protected
74 $className = uniqid('FeLogin_');
75 eval('
76 class ' . $className. ' extends tx_felogin_pi1 {
77 public function validateRedirectUrl($url) {
78 return parent::validateRedirectUrl($url);
79 }
80 }
81 ');
82
83 $this->txFelogin = new $className();
84 $this->txFelogin->cObj = $this->getMock('tslib_cObj');
85
86 $this->setUpTSFE();
87 $this->setUpFakeSitePathAndHost();
88 }
89
90 private function setUpTSFE() {
91 $GLOBALS['TSFE'] = $this->getMock('tslib_fe', array(), array(), '', FALSE);
92 }
93
94 private function setUpFakeSitePathAndHost() {
95 $_SERVER['ORIG_PATH_INFO'] =
96 $_SERVER['PATH_INFO'] =
97 $_SERVER['ORIG_SCRIPT_NAME'] =
98 $_SERVER['SCRIPT_NAME'] = $this->testSitePath . TYPO3_mainDir;
99 $_SERVER['HTTP_HOST'] = $this->testHostName;
100 }
101
102 private function setUpDatabaseMock() {
103 $GLOBALS['TYPO3_DB'] = $this->getMock('t3lib_DB', array('exec_SELECTgetRows'));
104 $GLOBALS['TYPO3_DB']->expects($this->any())->method('exec_SELECTgetRows')->will(
105 $this->returnCallback(array($this, 'getDomainRecordsCallback'))
106 );
107 }
108
109 /**
110 * Callback method for pageIdCanBeDetermined test cases.
111 * Simulates TYPO3_DB->exec_SELECTgetRows().
112 *
113 * @param string $fields
114 * @param string $table
115 * @param string $where
116 * @return mixed
117 * @see setUpDatabaseMock
118 */
119 public function getDomainRecordsCallback($fields, $table, $where) {
120
121 if ($table !== $this->testTableName) {
122 return FALSE;
123 }
124
125 return array(
126 array('domainName' => 'domainhostname.tld'),
127 array('domainName' => 'otherhostname.tld/path'),
128 array('domainName' => 'sub.domainhostname.tld/path/')
129 );
130 }
131
132 public function tearDown() {
133 $this->txFelogin = null;
134
135 foreach ($this->backupGlobalVariables as $key => $data) {
136 $GLOBALS[$key] = $data;
137 }
138
139 $this->backupGlobalVariables = null;
140
141 }
142
143 /**
144 * @test
145 */
146 public function typo3SitePathEqualsStubSitePath() {
147 $this->assertEquals(t3lib_div::getIndpEnv('TYPO3_SITE_PATH'), $this->testSitePath);
148 }
149
150 /**
151 * @test
152 */
153 public function typo3SiteUrlEqualsStubSiteUrl() {
154 $this->assertEquals(t3lib_div::getIndpEnv('TYPO3_SITE_URL'), 'http://' . $this->testHostName . $this->testSitePath);
155 }
156
157 /**
158 * @test
159 */
160 public function typo3SitePathEqualsStubSitePathAfterChangingInTest() {
161 $this->testHostName = 'somenewhostname.com';
162 $this->testSitePath = '/somenewpath/';
163 $this->setUpFakeSitePathAndHost();
164
165 $this->assertEquals(t3lib_div::getIndpEnv('TYPO3_SITE_PATH'), $this->testSitePath);
166 }
167
168 /**
169 * @test
170 */
171 public function typo3SiteUrlEqualsStubSiteUrlAfterChangingInTest() {
172 $this->testHostName = 'somenewhostname.com';
173 $this->testSitePath = '/somenewpath/';
174 $this->setUpFakeSitePathAndHost();
175
176 $this->assertEquals(t3lib_div::getIndpEnv('TYPO3_SITE_URL'), 'http://' . $this->testHostName . $this->testSitePath);
177 }
178
179 /**
180 * Data provider for malicousUrlsWillBeCleared
181 *
182 * @see malicousUrlsWillBeCleared
183 */
184 public function variousUrlsDataProviderForMalicousUrlsWillBeCleared() {
185 return array(
186 'absolute URL, hostname not in sys_domain, trailing slash' => array('http://badhost.tld/'),
187 'absolute URL, hostname not in sys_domain, no trailing slash' => array('http://badhost.tld'),
188 'absolute URL, subdomain in sys_domain, but main domain not, trailing slash' => array('http://domainhostname.tld.badhost.tld/'),
189 'absolute URL, subdomain in sys_domain, but main domain not, no trailing slash' => array('http://domainhostname.tld.badhost.tld'),
190 'non http absolute URL 1' => array('its://domainhostname.tld/itunes/'),
191 'non http absolute URL 2' => array('ftp://domainhostname.tld/download/'),
192
193 'XSS attempt 1' => array('javascript:alert(123)'),
194 'XSS attempt 2' => array('" onmouseover="alert(123)"'),
195 'invalid URL, HTML break out attempt' => array('" >blabuubb'),
196 'invalid URL, UNC path' => array('\\\\foo\\bar\\'),
197 'invalid URL, backslashes in path' => array('http://domainhostname.tld\\bla\\blupp'),
198 'invalid URL, linefeed in path' => array("http://domainhostname.tld/bla/blupp\n"),
199 'invalid URL, only one slash after scheme' => array("http:/domainhostname.tld/bla/blupp"),
200 'invalid URL, illegal chars' => array("http://(<>domainhostname).tld/bla/blupp"),
201
202 );
203 }
204
205 /**
206 * @test
207 * @dataProvider variousUrlsDataProviderForMalicousUrlsWillBeCleared
208 */
209 public function malicousUrlsWillBeCleared($url) {
210 $this->setUpDatabaseMock();
211 $this->assertEquals('', $this->txFelogin->validateRedirectUrl($url));
212 }
213
214 /**
215 * Data provider for cleanUrlsAreKept
216 *
217 * @see cleanUrlsAreKept
218 */
219 public function variousUrlsDataProviderForCleanUrlsAreKept() {
220 return array(
221 'sane absolute URL' => array('http://domainhostname.tld/'),
222 'sane absolute URL with script' => array('http://domainhostname.tld/index.php?id=1'),
223 'sane absolute URL with realurl' => array('http://domainhostname.tld/foo/bar/foo.html'),
224 'sane absolute URL with homedir' => array('http://domainhostname.tld/~user/'),
225 'sane absolute URL with some strange chars encoded' => array('http://domainhostname.tld/~user/a%cc%88o%cc%88%c3%9fa%cc%82/foo.html'),
226
227 'sane absolute URL (domain record with path)' => array('http://otherhostname.tld/path/'),
228 'sane absolute URL with script (domain record with path)' => array('http://otherhostname.tld/path/index.php?id=1'),
229 'sane absolute URL with realurl (domain record with path)' => array('http://otherhostname.tld/path/foo/bar/foo.html'),
230
231 'sane absolute URL (domain record with path and slash)' => array('http://sub.domainhostname.tld/path/'),
232 'sane absolute URL with script (domain record with path slash)' => array('http://sub.domainhostname.tld/path/index.php?id=1'),
233 'sane absolute URL with realurl (domain record with path slash)' => array('http://sub.domainhostname.tld/path/foo/bar/foo.html'),
234
235 'relative URL, no leading slash 1' => array('index.php?id=1'),
236 'relative URL, no leading slash 2' => array('foo/bar/index.php?id=2'),
237 'relative URL, leading slash, no realurl' => array('/index.php?id=1'),
238 'relative URL, leading slash, realurl' => array('/de/service/imprint.html'),
239 );
240 }
241
242 /**
243 * @test
244 * @dataProvider variousUrlsDataProviderForCleanUrlsAreKept
245 */
246 public function cleanUrlsAreKept($url) {
247 $this->setUpDatabaseMock();
248 $this->assertEquals($url, $this->txFelogin->validateRedirectUrl($url));
249 }
250
251 /**
252 * Data provider for malicousUrlsWillBeClearedTypo3InSubdirectory
253 *
254 * @see malicousUrlsWillBeClearedTypo3InSubdirectory
255 */
256 public function variousUrlsDataProviderForMalicousUrlsWillBeClearedTypo3InSubdirectory() {
257 return array(
258 'absolute URL, missing subdirectory' => array('http://hostname.tld/'),
259 'absolute URL, wrong subdirectory' => array('http://hostname.tld/hacker/index.php'),
260 'absolute URL, correct subdirectory, no trailing slash' => array('http://hostname.tld/subdir'),
261 'absolute URL, correct subdirectory of sys_domain record, no trailing slash' => array('http://otherhostname.tld/path'),
262 'absolute URL, correct subdirectory of sys_domain record, no trailing slash' => array('http://sub.domainhostname.tld/path'),
263
264 'relative URL, leading slash, no path' => array('/index.php?id=1'),
265 'relative URL, leading slash, wrong path' => array('/de/sub/site.html'),
266 'relative URL, leading slash, slash only' => array('/'),
267 );
268 }
269
270 /**
271 * @test
272 * @dataProvider variousUrlsDataProviderForMalicousUrlsWillBeClearedTypo3InSubdirectory
273 */
274 public function malicousUrlsWillBeClearedTypo3InSubdirectory($url) {
275 $this->testSitePath = '/subdir/';
276 $this->setUpFakeSitePathAndHost();
277
278 $this->setUpDatabaseMock();
279 $this->assertEquals('', $this->txFelogin->validateRedirectUrl($url));
280 }
281
282 /**
283 * Data provider for cleanUrlsAreKeptTypo3InSubdirectory
284 *
285 * @see cleanUrlsAreKeptTypo3InSubdirectory
286 */
287 public function variousUrlsDataProviderForCleanUrlsAreKeptTypo3InSubdirectory() {
288 return array(
289 'absolute URL, correct subdirectory' => array('http://hostname.tld/subdir/'),
290 'absolute URL, correct subdirectory, realurl' => array('http://hostname.tld/subdir/de/imprint.html'),
291 'absolute URL, correct subdirectory, no realurl' => array('http://hostname.tld/subdir/index.php?id=10'),
292
293 'absolute URL, correct subdirectory of sys_domain record' => array('http://otherhostname.tld/path/'),
294 'absolute URL, correct subdirectory of sys_domain record' => array('http://sub.domainhostname.tld/path/'),
295
296 'relative URL, no leading slash, realurl' => array('de/service/imprint.html'),
297 'relative URL, no leading slash, no realurl' => array('index.php?id=1'),
298 'relative URL, no leading slash, no realurl' => array('foo/bar/index.php?id=2'),
299 );
300 }
301
302 /**
303 * @test
304 * @dataProvider variousUrlsDataProviderForCleanUrlsAreKeptTypo3InSubdirectory
305 */
306 public function cleanUrlsAreKeptTypo3InSubdirectory($url) {
307 $this->testSitePath = '/subdir/';
308 $this->setUpFakeSitePathAndHost();
309
310 $this->setUpDatabaseMock();
311 $this->assertEquals($url, $this->txFelogin->validateRedirectUrl($url));
312 }
313
314
315
316 }
317 ?>