[BUGFIX] pi_getLL() alternative language translation fails
[Packages/TYPO3.CMS.git] / typo3 / sysext / felogin / Tests / Unit / FrontendLoginTest.php
1 <?php
2 namespace TYPO3\CMS\Felogin\Tests\Unit;
3
4 /**
5 * Testcase for URL validation in class FrontendLoginController
6 *
7 * @author Helmut Hummel <helmut@typo3.org>
8 * @package TYPO3
9 * @subpackage felogin
10 */
11 class FrontendLoginTest extends \tx_phpunit_testcase {
12
13 /**
14 * @var array
15 */
16 private $backupGlobalVariables;
17
18 /**
19 * @var FrontendLoginController
20 */
21 private $txFelogin;
22
23 /**
24 * @var string
25 */
26 private $testHostName;
27
28 /**
29 * @var string
30 */
31 private $testSitePath;
32
33 /**
34 * @var string
35 */
36 private $testTableName;
37
38 public function setUp() {
39 $this->backupGlobalVariables = array(
40 '_SERVER' => $_SERVER,
41 'TYPO3_DB' => $GLOBALS['TYPO3_DB'],
42 'TSFE' => $GLOBALS['TSFE']
43 );
44 $this->testTableName = 'sys_domain';
45 $this->testHostName = 'hostname.tld';
46 $this->testSitePath = '/';
47 // We need to subclass because the method we want to test is protected
48 $className = uniqid('FeLogin_');
49 eval('
50 class ' . $className . ' extends TYPO3\\CMS\\Felogin\\Controller\\FrontendLoginController {
51 public function validateRedirectUrl($url) {
52 return parent::validateRedirectUrl($url);
53 }
54 }
55 ');
56 $this->txFelogin = new $className();
57 $this->txFelogin->cObj = $this->getMock('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer');
58 $this->setUpTSFE();
59 $this->setUpFakeSitePathAndHost();
60 }
61
62 private function setUpTSFE() {
63 $GLOBALS['TSFE'] = $this->getMock('TYPO3\\CMS\\Frontend\\Controller\\TypoScriptFrontendController', array(), array(), '', FALSE);
64 }
65
66 private function setUpFakeSitePathAndHost() {
67 $_SERVER['ORIG_PATH_INFO'] = ($_SERVER['PATH_INFO'] = ($_SERVER['ORIG_SCRIPT_NAME'] = ($_SERVER['SCRIPT_NAME'] = $this->testSitePath . TYPO3_mainDir)));
68 $_SERVER['HTTP_HOST'] = $this->testHostName;
69 }
70
71 private function setUpDatabaseMock() {
72 $GLOBALS['TYPO3_DB'] = $this->getMock('TYPO3\\CMS\\Core\\Database\\DatabaseConnection', array('exec_SELECTgetRows'));
73 $GLOBALS['TYPO3_DB']->expects($this->any())->method('exec_SELECTgetRows')->will($this->returnCallback(array($this, 'getDomainRecordsCallback')));
74 }
75
76 /**
77 * Callback method for pageIdCanBeDetermined test cases.
78 * Simulates TYPO3_DB->exec_SELECTgetRows().
79 *
80 * @param string $fields
81 * @param string $table
82 * @param string $where
83 * @return mixed
84 * @see setUpDatabaseMock
85 */
86 public function getDomainRecordsCallback($fields, $table, $where) {
87 if ($table !== $this->testTableName) {
88 return FALSE;
89 }
90 return array(
91 array('domainName' => 'domainhostname.tld'),
92 array('domainName' => 'otherhostname.tld/path'),
93 array('domainName' => 'sub.domainhostname.tld/path/')
94 );
95 }
96
97 public function tearDown() {
98 $this->txFelogin = NULL;
99 foreach ($this->backupGlobalVariables as $key => $data) {
100 $GLOBALS[$key] = $data;
101 }
102 $this->backupGlobalVariables = NULL;
103 }
104
105 /**
106 * @test
107 */
108 public function typo3SitePathEqualsStubSitePath() {
109 $this->assertEquals(\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_PATH'), $this->testSitePath);
110 }
111
112 /**
113 * @test
114 */
115 public function typo3SiteUrlEqualsStubSiteUrl() {
116 $this->assertEquals(\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL'), 'http://' . $this->testHostName . $this->testSitePath);
117 }
118
119 /**
120 * @test
121 */
122 public function typo3SitePathEqualsStubSitePathAfterChangingInTest() {
123 $this->testHostName = 'somenewhostname.com';
124 $this->testSitePath = '/somenewpath/';
125 $this->setUpFakeSitePathAndHost();
126 $this->assertEquals(\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_PATH'), $this->testSitePath);
127 }
128
129 /**
130 * @test
131 */
132 public function typo3SiteUrlEqualsStubSiteUrlAfterChangingInTest() {
133 $this->testHostName = 'somenewhostname.com';
134 $this->testSitePath = '/somenewpath/';
135 $this->setUpFakeSitePathAndHost();
136 $this->assertEquals(\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL'), 'http://' . $this->testHostName . $this->testSitePath);
137 }
138
139 /**
140 * Data provider for maliciousUrlsWillBeCleared
141 *
142 * @see maliciousUrlsWillBeCleared
143 */
144 public function variousUrlsDataProviderForMaliciousUrlsWillBeCleared() {
145 return array(
146 'absolute URL, hostname not in sys_domain, trailing slash' => array('http://badhost.tld/'),
147 'absolute URL, hostname not in sys_domain, no trailing slash' => array('http://badhost.tld'),
148 'absolute URL, subdomain in sys_domain, but main domain not, trailing slash' => array('http://domainhostname.tld.badhost.tld/'),
149 'absolute URL, subdomain in sys_domain, but main domain not, no trailing slash' => array('http://domainhostname.tld.badhost.tld'),
150 'non http absolute URL 1' => array('its://domainhostname.tld/itunes/'),
151 'non http absolute URL 2' => array('ftp://domainhostname.tld/download/'),
152 'XSS attempt 1' => array('javascript:alert(123)'),
153 'XSS attempt 2' => array('" onmouseover="alert(123)"'),
154 'invalid URL, HTML break out attempt' => array('" >blabuubb'),
155 'invalid URL, UNC path' => array('\\\\foo\\bar\\'),
156 'invalid URL, backslashes in path' => array('http://domainhostname.tld\\bla\\blupp'),
157 'invalid URL, linefeed in path' => array('http://domainhostname.tld/bla/blupp
158 '),
159 'invalid URL, only one slash after scheme' => array('http:/domainhostname.tld/bla/blupp'),
160 'invalid URL, illegal chars' => array('http://(<>domainhostname).tld/bla/blupp')
161 );
162 }
163
164 /**
165 * @test
166 * @dataProvider variousUrlsDataProviderForMaliciousUrlsWillBeCleared
167 */
168 public function maliciousUrlsWillBeCleared($url) {
169 $this->setUpDatabaseMock();
170 $this->assertEquals('', $this->txFelogin->validateRedirectUrl($url));
171 }
172
173 /**
174 * Data provider for cleanUrlsAreKept
175 *
176 * @see cleanUrlsAreKept
177 */
178 public function variousUrlsDataProviderForCleanUrlsAreKept() {
179 return array(
180 'sane absolute URL' => array('http://domainhostname.tld/'),
181 'sane absolute URL with script' => array('http://domainhostname.tld/index.php?id=1'),
182 'sane absolute URL with realurl' => array('http://domainhostname.tld/foo/bar/foo.html'),
183 'sane absolute URL with homedir' => array('http://domainhostname.tld/~user/'),
184 'sane absolute URL with some strange chars encoded' => array('http://domainhostname.tld/~user/a%cc%88o%cc%88%c3%9fa%cc%82/foo.html'),
185 'sane absolute URL (domain record with path)' => array('http://otherhostname.tld/path/'),
186 'sane absolute URL with script (domain record with path)' => array('http://otherhostname.tld/path/index.php?id=1'),
187 'sane absolute URL with realurl (domain record with path)' => array('http://otherhostname.tld/path/foo/bar/foo.html'),
188 'sane absolute URL (domain record with path and slash)' => array('http://sub.domainhostname.tld/path/'),
189 'sane absolute URL with script (domain record with path slash)' => array('http://sub.domainhostname.tld/path/index.php?id=1'),
190 'sane absolute URL with realurl (domain record with path slash)' => array('http://sub.domainhostname.tld/path/foo/bar/foo.html'),
191 'relative URL, no leading slash 1' => array('index.php?id=1'),
192 'relative URL, no leading slash 2' => array('foo/bar/index.php?id=2'),
193 'relative URL, leading slash, no realurl' => array('/index.php?id=1'),
194 'relative URL, leading slash, realurl' => array('/de/service/imprint.html')
195 );
196 }
197
198 /**
199 * @test
200 * @dataProvider variousUrlsDataProviderForCleanUrlsAreKept
201 */
202 public function cleanUrlsAreKept($url) {
203 $this->setUpDatabaseMock();
204 $this->assertEquals($url, $this->txFelogin->validateRedirectUrl($url));
205 }
206
207 /**
208 * Data provider for maliciousUrlsWillBeClearedTypo3InSubdirectory
209 *
210 * @see maliciousUrlsWillBeClearedTypo3InSubdirectory
211 */
212 public function variousUrlsDataProviderForMaliciousUrlsWillBeClearedTypo3InSubdirectory() {
213 return array(
214 'absolute URL, missing subdirectory' => array('http://hostname.tld/'),
215 'absolute URL, wrong subdirectory' => array('http://hostname.tld/hacker/index.php'),
216 'absolute URL, correct subdirectory, no trailing slash' => array('http://hostname.tld/subdir'),
217 'absolute URL, correct subdirectory of sys_domain record, no trailing slash' => array('http://otherhostname.tld/path'),
218 'absolute URL, correct subdirectory of sys_domain record, no trailing slash' => array('http://sub.domainhostname.tld/path'),
219 'relative URL, leading slash, no path' => array('/index.php?id=1'),
220 'relative URL, leading slash, wrong path' => array('/de/sub/site.html'),
221 'relative URL, leading slash, slash only' => array('/')
222 );
223 }
224
225 /**
226 * @test
227 * @dataProvider variousUrlsDataProviderForMaliciousUrlsWillBeClearedTypo3InSubdirectory
228 */
229 public function maliciousUrlsWillBeClearedTypo3InSubdirectory($url) {
230 $this->testSitePath = '/subdir/';
231 $this->setUpFakeSitePathAndHost();
232 $this->setUpDatabaseMock();
233 $this->assertEquals('', $this->txFelogin->validateRedirectUrl($url));
234 }
235
236 /**
237 * Data provider for cleanUrlsAreKeptTypo3InSubdirectory
238 *
239 * @see cleanUrlsAreKeptTypo3InSubdirectory
240 */
241 public function variousUrlsDataProviderForCleanUrlsAreKeptTypo3InSubdirectory() {
242 return array(
243 'absolute URL, correct subdirectory' => array('http://hostname.tld/subdir/'),
244 'absolute URL, correct subdirectory, realurl' => array('http://hostname.tld/subdir/de/imprint.html'),
245 'absolute URL, correct subdirectory, no realurl' => array('http://hostname.tld/subdir/index.php?id=10'),
246 'absolute URL, correct subdirectory of sys_domain record' => array('http://otherhostname.tld/path/'),
247 'absolute URL, correct subdirectory of sys_domain record' => array('http://sub.domainhostname.tld/path/'),
248 'relative URL, no leading slash, realurl' => array('de/service/imprint.html'),
249 'relative URL, no leading slash, no realurl' => array('index.php?id=1'),
250 'relative URL, no leading slash, no realurl' => array('foo/bar/index.php?id=2')
251 );
252 }
253
254 /**
255 * @test
256 * @dataProvider variousUrlsDataProviderForCleanUrlsAreKeptTypo3InSubdirectory
257 */
258 public function cleanUrlsAreKeptTypo3InSubdirectory($url) {
259 $this->testSitePath = '/subdir/';
260 $this->setUpFakeSitePathAndHost();
261 $this->setUpDatabaseMock();
262 $this->assertEquals($url, $this->txFelogin->validateRedirectUrl($url));
263 }
264
265 }
266
267 ?>