| 
									
										
										
										
											2021-08-03 10:24:01 +00:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-10 09:26:18 +01:00
										 |  |  | declare(strict_types = 1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-03 10:24:01 +00:00
										 |  |  | // {{{ License
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // This file is part of GNU social - https://www.gnu.org/software/social
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // GNU social is free software: you can redistribute it and/or modify
 | 
					
						
							|  |  |  | // it under the terms of the GNU Affero General Public License as published by
 | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or
 | 
					
						
							|  |  |  | // (at your option) any later version.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // GNU social is distributed in the hope that it will be useful,
 | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					
						
							|  |  |  | // GNU Affero General Public License for more details.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // You should have received a copy of the GNU Affero General Public License
 | 
					
						
							|  |  |  | // along with GNU social.  If not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // }}}
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-19 20:17:56 +01:00
										 |  |  | namespace App\Tests\Controller; | 
					
						
							| 
									
										
										
										
											2021-08-03 10:24:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | use App\Util\GNUsocialTestCase; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class SecurityTest extends GNUsocialTestCase | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // --------- Login --------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private function testLogin(string $nickname, string $password) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // This calls static::bootKernel(), and creates a "client" that is acting as the browser
 | 
					
						
							|  |  |  |         $client  = static::createClient(); | 
					
						
							| 
									
										
										
										
											2021-11-11 12:24:45 +00:00
										 |  |  |         $crawler = $client->request('GET', '/main/login'); | 
					
						
							| 
									
										
										
										
											2021-08-03 10:24:01 +00:00
										 |  |  |         $this->assertResponseIsSuccessful(); | 
					
						
							|  |  |  |         // $form = $crawler->selectButton('Sign in')->form();
 | 
					
						
							|  |  |  |         $crawler = $client->submitForm('Sign in', [ | 
					
						
							| 
									
										
										
										
											2021-11-23 22:34:35 +00:00
										 |  |  |             '_username' => $nickname, | 
					
						
							|  |  |  |             '_password' => $password, | 
					
						
							| 
									
										
										
										
											2021-08-03 10:24:01 +00:00
										 |  |  |         ]); | 
					
						
							|  |  |  |         $this->assertResponseStatusCodeSame(302); | 
					
						
							|  |  |  |         $crawler = $client->followRedirect(); | 
					
						
							|  |  |  |         return [$client, $crawler]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function testLoginSuccess() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         [, $crawler] = self::testLogin($nickname = 'taken_user', 'foobar'); | 
					
						
							|  |  |  |         $this->assertResponseIsSuccessful(); | 
					
						
							|  |  |  |         $this->assertSelectorNotExists('.alert'); | 
					
						
							| 
									
										
										
										
											2021-12-23 13:27:31 +00:00
										 |  |  |         $this->assertRouteSame('root'); | 
					
						
							| 
									
										
										
										
											2021-11-11 12:24:45 +00:00
										 |  |  |         $this->assertSelectorTextContains('.profile-info .profile-info-nickname', $nickname); | 
					
						
							| 
									
										
										
										
											2021-08-03 10:24:01 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function testLoginAttemptAlreadyLoggedIn() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         [$client] = self::testLogin('taken_user', 'foobar'); // Normal login
 | 
					
						
							| 
									
										
										
										
											2021-11-11 12:24:45 +00:00
										 |  |  |         $crawler  = $client->request('GET', '/main/login'); // attempt to login again
 | 
					
						
							| 
									
										
										
										
											2021-08-03 10:24:01 +00:00
										 |  |  |         $client->followRedirect(); | 
					
						
							| 
									
										
										
										
											2021-12-23 13:27:31 +00:00
										 |  |  |         $this->assertRouteSame('root'); | 
					
						
							| 
									
										
										
										
											2021-08-03 10:24:01 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function testLoginFailure() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         self::testLogin('taken_user', 'wrong password'); | 
					
						
							|  |  |  |         $this->assertResponseIsSuccessful(); | 
					
						
							| 
									
										
										
										
											2021-11-14 23:15:24 +00:00
										 |  |  |         $this->assertSelectorTextContains('.alert', 'Invalid login credentials'); | 
					
						
							|  |  |  |         $this->assertRouteSame('security_login'); | 
					
						
							| 
									
										
										
										
											2021-08-03 10:24:01 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function testLoginEmail() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         self::testLogin('email@provider', 'foobar'); | 
					
						
							|  |  |  |         $this->assertResponseIsSuccessful(); | 
					
						
							|  |  |  |         $this->assertSelectorNotExists('.alert'); | 
					
						
							| 
									
										
										
										
											2021-12-23 13:27:31 +00:00
										 |  |  |         $this->assertRouteSame('root'); | 
					
						
							| 
									
										
										
										
											2021-11-11 12:24:45 +00:00
										 |  |  |         $this->assertSelectorTextContains('.profile-info .profile-info-nickname', 'taken_user'); | 
					
						
							| 
									
										
										
										
											2021-08-03 10:24:01 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // --------- Register --------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private function testRegister(string $nickname, string $email, string $password) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $client  = static::createClient(); | 
					
						
							| 
									
										
										
										
											2021-11-11 12:24:45 +00:00
										 |  |  |         $crawler = $client->request('GET', '/main/register'); | 
					
						
							| 
									
										
										
										
											2021-08-03 10:24:01 +00:00
										 |  |  |         $this->assertResponseIsSuccessful(); | 
					
						
							|  |  |  |         $crawler = $client->submitForm('Register', [ | 
					
						
							|  |  |  |             'register[nickname]'         => $nickname, | 
					
						
							|  |  |  |             'register[email]'            => $email, | 
					
						
							|  |  |  |             'register[password][first]'  => $password, | 
					
						
							|  |  |  |             'register[password][second]' => $password, | 
					
						
							|  |  |  |         ]); | 
					
						
							|  |  |  |         return [$client, $crawler]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function testRegisterSuccess() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         [$client,] = self::testRegister('new_nickname', 'new_email@email_provider', 'foobar'); | 
					
						
							|  |  |  |         $this->assertResponseStatusCodeSame(302); | 
					
						
							|  |  |  |         $client->followRedirect(); | 
					
						
							|  |  |  |         $this->assertResponseIsSuccessful(); | 
					
						
							|  |  |  |         $this->assertSelectorNotExists('.alert'); | 
					
						
							| 
									
										
										
										
											2021-12-23 13:27:31 +00:00
										 |  |  |         $this->assertRouteSame('root'); | 
					
						
							| 
									
										
										
										
											2021-11-11 12:24:45 +00:00
										 |  |  |         $this->assertSelectorTextContains('.profile-info .profile-info-nickname', 'new_nickname'); | 
					
						
							| 
									
										
										
										
											2021-08-03 10:24:01 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function testRegisterDifferentPassword() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $client  = static::createClient(); | 
					
						
							| 
									
										
										
										
											2021-11-11 12:24:45 +00:00
										 |  |  |         $crawler = $client->request('GET', '/main/register'); | 
					
						
							| 
									
										
										
										
											2021-08-03 10:24:01 +00:00
										 |  |  |         $this->assertResponseIsSuccessful(); | 
					
						
							|  |  |  |         $crawler = $client->submitForm('Register', [ | 
					
						
							|  |  |  |             'register[nickname]'         => 'new_user', | 
					
						
							|  |  |  |             'register[email]'            => 'new_email@provider', | 
					
						
							|  |  |  |             'register[password][first]'  => 'fooobar', | 
					
						
							|  |  |  |             'register[password][second]' => 'barquux', | 
					
						
							|  |  |  |         ]); | 
					
						
							|  |  |  |         $this->assertSelectorTextContains('form[name=register] ul li', 'The password fields must match'); | 
					
						
							|  |  |  |         $this->assertResponseStatusCodeSame(200); | 
					
						
							| 
									
										
										
										
											2021-11-14 23:15:24 +00:00
										 |  |  |         $this->assertRouteSame('security_register'); | 
					
						
							| 
									
										
										
										
											2021-08-03 10:24:01 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private function testRegisterPasswordLength(string $password, string $error) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         self::testRegister('new_nickname', 'email@provider', $password); | 
					
						
							|  |  |  |         $this->assertResponseIsSuccessful(); | 
					
						
							| 
									
										
										
										
											2021-09-06 14:29:50 +01:00
										 |  |  |         $this->assertSelectorTextContains('.help-block > ul > li', $error); | 
					
						
							| 
									
										
										
										
											2021-11-14 23:15:24 +00:00
										 |  |  |         $this->assertRouteSame('security_register'); | 
					
						
							| 
									
										
										
										
											2021-08-03 10:24:01 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-03 19:37:11 +00:00
										 |  |  |     public function testRegisterPasswordEmpty() | 
					
						
							| 
									
										
										
										
											2021-08-03 10:24:01 +00:00
										 |  |  |     { | 
					
						
							|  |  |  |         self::testRegisterPasswordLength('', error: 'Please enter a password'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function testRegisterPasswordShort() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         self::testRegisterPasswordLength('f', error: 'Your password should be at least'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function testRegisterPasswordLong() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         self::testRegisterPasswordLength(str_repeat('f', 128), error: 'Your password should be at most'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private function testRegisterNoEmail() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         self::testRegister('new_nickname', '', 'foobar'); | 
					
						
							|  |  |  |         $this->assertResponseIsSuccessful(); | 
					
						
							| 
									
										
										
										
											2021-09-06 14:29:50 +01:00
										 |  |  |         $this->assertSelectorTextContains('.help-block > ul > li', 'Please enter an email'); | 
					
						
							| 
									
										
										
										
											2021-11-14 23:15:24 +00:00
										 |  |  |         $this->assertRouteSame('security_register'); | 
					
						
							| 
									
										
										
										
											2021-08-03 10:24:01 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private function testRegisterNicknameLength(string $nickname, string $error) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         self::testRegister($nickname, 'email@provider', 'foobar'); | 
					
						
							|  |  |  |         $this->assertResponseIsSuccessful(); | 
					
						
							| 
									
										
										
										
											2021-09-06 14:29:50 +01:00
										 |  |  |         $this->assertSelectorTextContains('.help-block > ul > li', $error); | 
					
						
							| 
									
										
										
										
											2021-11-14 23:15:24 +00:00
										 |  |  |         $this->assertRouteSame('security_register'); | 
					
						
							| 
									
										
										
										
											2021-08-03 10:24:01 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function testRegisterNicknameEmpty() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         self::testRegisterNicknameLength('', error: 'Please enter a nickname'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function testRegisterNicknameLong() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         self::testRegisterNicknameLength(str_repeat('f', 128), error: 'Your nickname must be at most'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function testRegisterExistingNickname() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         [$client, $crawler] = self::testRegister('taken_user', 'new_new_email@email_provider', 'foobar'); | 
					
						
							|  |  |  |         $this->assertSelectorTextContains('.stacktrace', 'App\Util\Exception\NicknameTakenException'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function testRegisterExistingEmail() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         [$client, $crawler] = self::testRegister('other_new_nickname', 'email@provider', 'foobar'); | 
					
						
							|  |  |  |         $this->assertSelectorTextContains('.stacktrace', 'App\Util\Exception\EmailTakenException'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |