the browser-facing portion of osu!
at master 6.7 kB view raw
1<?php 2 3// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0. 4// See the LICENCE file in the repository root for full licence text. 5 6namespace Tests\Controllers; 7 8use App\Models\Country; 9use App\Models\LoginAttempt; 10use App\Models\User; 11use Tests\TestCase; 12 13class SessionsControllerTest extends TestCase 14{ 15 public function testLogin() 16 { 17 $password = 'password1'; 18 $user = User::factory()->create(compact('password')); 19 20 $this->expectCountChange(fn () => LoginAttempt::count(), 1); 21 $this->post(route('login'), [ 22 'username' => $user->username, 23 'password' => $password, 24 ])->assertSuccessful(); 25 26 $this->assertAuthenticated(); 27 } 28 29 public function testLoginInactiveUser() 30 { 31 $password = 'password1'; 32 $countryAcronym = (Country::first() ?? Country::factory()->create())->getKey(); 33 $user = User::factory()->create(['password' => $password, 'country_acronym' => $countryAcronym]); 34 $user->update(['user_lastvisit' => time() - $GLOBALS['cfg']['osu']['user']['inactive_seconds_verification'] - 1]); 35 36 $this->post(route('login'), [ 37 'username' => $user->username, 38 'password' => $password, 39 ], [ 40 'CF_IPCOUNTRY' => $countryAcronym, 41 ])->assertSuccessful(); 42 43 $this->assertAuthenticated(); 44 45 $this->get(route('home'))->assertStatus(401); 46 } 47 48 public function testLoginInactiveUserForceReset(): void 49 { 50 config_set('osu.user.inactive_force_password_reset', true); 51 52 $password = 'password1'; 53 $countryAcronym = (Country::first() ?? Country::factory()->create())->getKey(); 54 $user = User::factory()->create(['password' => $password, 'country_acronym' => $countryAcronym]); 55 $user->update(['user_lastvisit' => time() - $GLOBALS['cfg']['osu']['user']['inactive_seconds_verification'] - 1]); 56 57 $this->post(route('login'), [ 58 'username' => $user->username, 59 'password' => $password, 60 ], [ 61 'CF_IPCOUNTRY' => $countryAcronym, 62 ])->assertStatus(302); 63 64 $this->assertGuest(); 65 } 66 67 public function testLoginInactiveUserDifferentCountry() 68 { 69 $password = 'password1'; 70 $user = User::factory()->create(compact('password')); 71 $user->update(['user_lastvisit' => time() - $GLOBALS['cfg']['osu']['user']['inactive_seconds_verification'] - 1]); 72 73 $this->assertNotSame('', $user->fresh()->user_password); 74 75 $this->post(route('login'), [ 76 'username' => $user->username, 77 'password' => $password, 78 ], [ 79 'CF_IPCOUNTRY' => '__', 80 ])->assertStatus(302); 81 82 $this->assertGuest(); 83 $this->assertSame('', $user->fresh()->user_password); 84 } 85 86 public function testLoginMissingParameters() 87 { 88 $password = 'password1'; 89 $user = User::factory()->create(compact('password')); 90 91 $this->post(route('login'))->assertStatus(422); 92 $this->assertGuest(); 93 94 $this->post(route('login'), ['username' => $user->username])->assertStatus(422); 95 $this->assertGuest(); 96 97 $this->post(route('login'), compact('password'))->assertStatus(422); 98 $this->assertGuest(); 99 } 100 101 public function testLoginWrongPassword() 102 { 103 $password = 'password1'; 104 $user = User::factory()->create(compact('password')); 105 106 $this->post(route('login'), [ 107 'username' => $user->username, 108 'password' => "{$password}1", 109 ])->assertStatus(403); 110 111 $this->assertGuest(); 112 113 $record = LoginAttempt::find('127.0.0.1'); 114 $this->assertTrue($record->containsUser($user, 'fail:')); 115 $this->assertSame(1, $record->unique_ids); 116 $this->assertSame(1, $record->failed_attempts); 117 $this->assertSame(1, $record->total_attempts); 118 } 119 120 public function testLoginWrongPasswordTwiceDifferent() 121 { 122 $password = 'password1'; 123 $user = User::factory()->create(compact('password')); 124 125 $this->post(route('login'), [ 126 'username' => $user->username, 127 'password' => 'password2', 128 ])->assertStatus(403); 129 130 $this->post(route('login'), [ 131 'username' => $user->username, 132 'password' => 'password3', 133 ])->assertStatus(403); 134 135 $this->assertGuest(); 136 137 $record = LoginAttempt::find('127.0.0.1'); 138 $this->assertTrue($record->containsUser($user, 'fail:')); 139 $this->assertSame(1, $record->unique_ids); 140 $this->assertSame(2, $record->failed_attempts); 141 $this->assertSame(2, $record->total_attempts); 142 } 143 144 public function testLoginWrongPasswordTwiceSame() 145 { 146 $password = 'password1'; 147 $wrongPassword = 'password2'; 148 $user = User::factory()->create(compact('password')); 149 150 $this->post(route('login'), [ 151 'username' => $user->username, 152 'password' => $wrongPassword, 153 ])->assertStatus(403); 154 155 $this->post(route('login'), [ 156 'username' => $user->username, 157 'password' => $wrongPassword, 158 ])->assertStatus(403); 159 160 $this->assertGuest(); 161 162 $record = LoginAttempt::find('127.0.0.1'); 163 $this->assertTrue($record->containsUser($user, 'fail:')); 164 $this->assertSame(1, $record->unique_ids); 165 $this->assertSame(1, $record->failed_attempts); 166 $this->assertSame(1, $record->total_attempts); 167 } 168 169 public function testLoginWrongPasswordExtraFailedOnAnotherUser() 170 { 171 $password = 'password1'; 172 $ip = '127.0.0.1'; 173 $firstUser = User::factory()->create(compact('password')); 174 LoginAttempt::logAttempt($ip, $firstUser, 'fail', 'password2'); 175 176 $record = LoginAttempt::find('127.0.0.1'); 177 $this->assertTrue($record->containsUser($firstUser, 'fail:')); 178 $this->assertSame(1, $record->unique_ids); 179 $this->assertSame(1, $record->failed_attempts); 180 $this->assertSame(1, $record->total_attempts); 181 182 $secondUser = User::factory()->create(compact('password')); 183 184 $this->post(route('login'), [ 185 'username' => $secondUser->username, 186 'password' => "{$password}1", 187 ])->assertStatus(403); 188 189 $this->assertGuest(); 190 191 $record = LoginAttempt::find('127.0.0.1'); 192 $this->assertTrue($record->containsUser($secondUser, 'fail:')); 193 $this->assertSame(2, $record->unique_ids); 194 $this->assertSame(3, $record->failed_attempts); 195 $this->assertSame(2, $record->total_attempts); 196 } 197}