TYPO3  7.6
FrontendLoginControllerTest.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Felogin\Tests\Unit\Controller;
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
19 
23 class FrontendLoginControllerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
24 {
28  protected $accessibleFixture;
29 
33  protected $testHostName;
34 
38  protected $testSitePath;
39 
43  protected $testTableName;
44 
48  protected function setUp()
49  {
50  $this->testTableName = 'sys_domain';
51  $this->testHostName = 'hostname.tld';
52  $this->testSitePath = '/';
53  $this->accessibleFixture = $this->getAccessibleMock(\TYPO3\CMS\Felogin\Controller\FrontendLoginController::class, array('dummy'));
54  $this->accessibleFixture->cObj = $this->getMock(\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class);
55  $this->accessibleFixture->_set('frontendController', $this->getMock(\TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController::class, array(), array(), '', false));
56  $this->setUpFakeSitePathAndHost();
57  }
58 
62  protected function setUpFakeSitePathAndHost()
63  {
65  $_SERVER['ORIG_PATH_INFO'] = $_SERVER['PATH_INFO'] = $_SERVER['ORIG_SCRIPT_NAME'] = $_SERVER['SCRIPT_NAME'] = $this->testSitePath . TYPO3_mainDir;
66  $_SERVER['HTTP_HOST'] = $this->testHostName;
67  }
68 
72  protected function setUpDatabaseMock()
73  {
74  $db = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection::class, array('exec_SELECTgetRows'));
75  $db
76  ->expects($this->any())
77  ->method('exec_SELECTgetRows')
78  ->will($this->returnCallback(array($this, 'getDomainRecordsCallback')));
79  $this->accessibleFixture->_set('databaseConnection', $db);
80  }
81 
92  public function getDomainRecordsCallback($fields, $table, $where)
93  {
94  if ($table !== $this->testTableName) {
95  return false;
96  }
97  return array(
98  array('domainName' => 'domainhostname.tld'),
99  array('domainName' => 'otherhostname.tld/path'),
100  array('domainName' => 'sub.domainhostname.tld/path/')
101  );
102  }
103 
108  {
109  $this->assertEquals(\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_PATH'), $this->testSitePath);
110  }
111 
116  {
117  $this->assertEquals(\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL'), ('http://' . $this->testHostName) . $this->testSitePath);
118  }
119 
124  {
125  $this->testHostName = 'somenewhostname.com';
126  $this->testSitePath = '/somenewpath/';
127  $this->setUpFakeSitePathAndHost();
128  $this->assertEquals(\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_PATH'), $this->testSitePath);
129  }
130 
135  {
136  $this->testHostName = 'somenewhostname.com';
137  $this->testSitePath = '/somenewpath/';
138  $this->setUpFakeSitePathAndHost();
139  $this->assertEquals(\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL'), ('http://' . $this->testHostName) . $this->testSitePath);
140  }
141 
148  {
149  return array(
150  'absolute URL, hostname not in sys_domain, trailing slash' => array('http://badhost.tld/'),
151  'absolute URL, hostname not in sys_domain, no trailing slash' => array('http://badhost.tld'),
152  'absolute URL, subdomain in sys_domain, but main domain not, trailing slash' => array('http://domainhostname.tld.badhost.tld/'),
153  'absolute URL, subdomain in sys_domain, but main domain not, no trailing slash' => array('http://domainhostname.tld.badhost.tld'),
154  'non http absolute URL 1' => array('its://domainhostname.tld/itunes/'),
155  'non http absolute URL 2' => array('ftp://domainhostname.tld/download/'),
156  'XSS attempt 1' => array('javascript:alert(123)'),
157  'XSS attempt 2' => array('" onmouseover="alert(123)"'),
158  'invalid URL, HTML break out attempt' => array('" >blabuubb'),
159  'invalid URL, UNC path' => array('\\\\foo\\bar\\'),
160  'invalid URL, backslashes in path' => array('http://domainhostname.tld\\bla\\blupp'),
161  'invalid URL, linefeed in path' => array('http://domainhostname.tld/bla/blupp' . LF),
162  'invalid URL, only one slash after scheme' => array('http:/domainhostname.tld/bla/blupp'),
163  'invalid URL, illegal chars' => array('http://(<>domainhostname).tld/bla/blupp'),
164  );
165  }
166 
173  {
174  $this->setUpDatabaseMock();
175  $this->assertEquals('', $this->accessibleFixture->_call('validateRedirectUrl', $url));
176  }
177 
184  {
185  return array(
186  'sane absolute URL' => array('http://domainhostname.tld/'),
187  'sane absolute URL with script' => array('http://domainhostname.tld/index.php?id=1'),
188  'sane absolute URL with realurl' => array('http://domainhostname.tld/foo/bar/foo.html'),
189  'sane absolute URL with homedir' => array('http://domainhostname.tld/~user/'),
190  'sane absolute URL with some strange chars encoded' => array('http://domainhostname.tld/~user/a%cc%88o%cc%88%c3%9fa%cc%82/foo.html'),
191  'sane absolute URL (domain record with path)' => array('http://otherhostname.tld/path/'),
192  'sane absolute URL with script (domain record with path)' => array('http://otherhostname.tld/path/index.php?id=1'),
193  'sane absolute URL with realurl (domain record with path)' => array('http://otherhostname.tld/path/foo/bar/foo.html'),
194  'sane absolute URL (domain record with path and slash)' => array('http://sub.domainhostname.tld/path/'),
195  'sane absolute URL with script (domain record with path slash)' => array('http://sub.domainhostname.tld/path/index.php?id=1'),
196  'sane absolute URL with realurl (domain record with path slash)' => array('http://sub.domainhostname.tld/path/foo/bar/foo.html'),
197  'relative URL, no leading slash 1' => array('index.php?id=1'),
198  'relative URL, no leading slash 2' => array('foo/bar/index.php?id=2'),
199  'relative URL, leading slash, no realurl' => array('/index.php?id=1'),
200  'relative URL, leading slash, realurl' => array('/de/service/imprint.html'),
201  );
202  }
203 
210  {
211  $this->setUpDatabaseMock();
212  $this->assertEquals($url, $this->accessibleFixture->_call('validateRedirectUrl', $url));
213  }
214 
221  {
222  return array(
223  'absolute URL, missing subdirectory' => array('http://hostname.tld/'),
224  'absolute URL, wrong subdirectory' => array('http://hostname.tld/hacker/index.php'),
225  'absolute URL, correct subdirectory, no trailing slash' => array('http://hostname.tld/subdir'),
226  'absolute URL, correct subdirectory of sys_domain record, no trailing slash' => array('http://otherhostname.tld/path'),
227  'absolute URL, correct subdirectory of sys_domain record, no trailing slash, subdomain' => array('http://sub.domainhostname.tld/path'),
228  'relative URL, leading slash, no path' => array('/index.php?id=1'),
229  'relative URL, leading slash, wrong path' => array('/de/sub/site.html'),
230  'relative URL, leading slash, slash only' => array('/'),
231  );
232  }
233 
240  {
241  $this->testSitePath = '/subdir/';
242  $this->setUpFakeSitePathAndHost();
243  $this->setUpDatabaseMock();
244  $this->assertEquals('', $this->accessibleFixture->_call('validateRedirectUrl', $url));
245  }
246 
253  {
254  return array(
255  'absolute URL, correct subdirectory' => array('http://hostname.tld/subdir/'),
256  'absolute URL, correct subdirectory, realurl' => array('http://hostname.tld/subdir/de/imprint.html'),
257  'absolute URL, correct subdirectory, no realurl' => array('http://hostname.tld/subdir/index.php?id=10'),
258  'absolute URL, correct subdirectory of sys_domain record' => array('http://otherhostname.tld/path/'),
259  'absolute URL, correct subdirectory of sys_domain record, subdomain' => array('http://sub.domainhostname.tld/path/'),
260  'relative URL, no leading slash, realurl' => array('de/service/imprint.html'),
261  'relative URL, no leading slash, no realurl' => array('index.php?id=1'),
262  'relative nested URL, no leading slash, no realurl' => array('foo/bar/index.php?id=2')
263  );
264  }
265 
272  {
273  $this->testSitePath = '/subdir/';
274  $this->setUpFakeSitePathAndHost();
275  $this->setUpDatabaseMock();
276  $this->assertEquals($url, $this->accessibleFixture->_call('validateRedirectUrl', $url));
277  }
278 
279 
280  /*************************
281  * Test concerning getPreverveGetVars
282  *************************/
283 
288  {
289  return array(
290  'special get var id is not preserved' => array(
291  array(
292  'id' => 42,
293  ),
294  '',
295  '',
296  ),
297  'simple additional parameter is not preserved if not specified in preservedGETvars' => array(
298  array(
299  'id' => 42,
300  'special' => 23,
301  ),
302  '',
303  '',
304  ),
305  'all params except ignored ones are preserved if preservedGETvars is set to "all"' => array(
306  array(
307  'id' => 42,
308  'special1' => 23,
309  'special2' => array(
310  'foo' => 'bar',
311  ),
312  'tx_felogin_pi1' => array(
313  'forgot' => 1,
314  ),
315  ),
316  'all',
317  '&special1=23&special2[foo]=bar',
318  ),
319  'preserve single parameter' => array(
320  array(
321  'L' => 42,
322  ),
323  'L',
324  '&L=42'
325  ),
326  'preserve whole parameter array' => array(
327  array(
328  'L' => 3,
329  'tx_someext' => array(
330  'foo' => 'simple',
331  'bar' => array(
332  'baz' => 'simple',
333  ),
334  ),
335  ),
336  'L,tx_someext',
337  '&L=3&tx_someext[foo]=simple&tx_someext[bar][baz]=simple',
338  ),
339  'preserve part of sub array' => array(
340  array(
341  'L' => 3,
342  'tx_someext' => array(
343  'foo' => 'simple',
344  'bar' => array(
345  'baz' => 'simple',
346  ),
347  ),
348  ),
349  'L,tx_someext[bar]',
350  '&L=3&tx_someext[bar][baz]=simple',
351  ),
352  'preserve keys on different levels' => array(
353  array(
354  'L' => 3,
355  'no-preserve' => 'whatever',
356  'tx_ext2' => array(
357  'foo' => 'simple',
358  ),
359  'tx_ext3' => array(
360  'bar' => array(
361  'baz' => 'simple',
362  ),
363  'go-away' => '',
364  ),
365  ),
366  'L,tx_ext2,tx_ext3[bar]',
367  '&L=3&tx_ext2[foo]=simple&tx_ext3[bar][baz]=simple',
368  ),
369  'preserved value that does not exist in get' => array(
370  array(),
371  'L,foo[bar]',
372  ''
373  ),
374  'url params are encoded' => array(
375  array('tx_ext1' => 'param with spaces and \\ %<>& /'),
376  'L,tx_ext1',
377  '&tx_ext1=param%20with%20spaces%20and%20%5C%20%25%3C%3E%26%20%2F'
378  ),
379  );
380  }
381 
390  public function getPreserveGetVarsReturnsCorrectResult(array $getArray, $preserveVars, $expected)
391  {
392  $_GET = $getArray;
393  $this->accessibleFixture->conf['preserveGETvars'] = $preserveVars;
394  $this->assertSame($expected, $this->accessibleFixture->_call('getPreserveGetVars'));
395  }
396 
397 
398  /**************************************************
399  * Tests concerning isInLocalDomain
400  **************************************************/
401 
408  {
409  return array(
410  'url https, current host http' => array(
411  'example.com', // HTTP_HOST
412  '0', // HTTPS
413  'https://example.com/foo.html' // URL
414  ),
415  'url http, current host https' => array(
416  'example.com',
417  '1',
418  'http://example.com/foo.html'
419  ),
420  'url https, current host https' => array(
421  'example.com',
422  '1',
423  'https://example.com/foo.html'
424  ),
425  'url http, current host http' => array(
426  'example.com',
427  '0',
428  'http://example.com/foo.html'
429  )
430  );
431  }
432 
440  public function isInCurrentDomainIgnoresScheme($host, $https, $url)
441  {
442  $_SERVER['HTTP_HOST'] = $host;
443  $_SERVER['HTTPS'] = $https;
444  $this->assertTrue($this->accessibleFixture->_call('isInCurrentDomain', $url));
445  }
446 
451  {
452  return array(
453  'simple difference' => array(
454  'example.com', // HTTP_HOST
455  'http://typo3.org/foo.html' // URL
456  ),
457  'subdomain different' => array(
458  'example.com',
459  'http://foo.example.com/bar.html'
460  )
461  );
462  }
463 
471  {
472  $_SERVER['HTTP_HOST'] = $host;
473  $this->assertFalse($this->accessibleFixture->_call('isInCurrentDomain', $url));
474  }
475 
479  public function processRedirectReferrerDomainsMatchesDomains()
480  {
481  $conf = array(
482  'redirectMode' => 'refererDomains',
483  'domains' => 'example.com'
484  );
485 
486  $this->accessibleFixture->_set('conf', $conf);
487  $this->accessibleFixture->_set('logintype', 'login');
488  $this->accessibleFixture->_set('referer', 'http://www.example.com/snafu');
490  $tsfe = $this->accessibleFixture->_get('frontendController');
491  $tsfe->loginUser = true;
492  $this->assertSame(array('http://www.example.com/snafu'), $this->accessibleFixture->_call('processRedirect'));
493  }
494 }