new funcionality
This commit is contained in:
125
tests/Feature/RateLimitingTest.php
Normal file
125
tests/Feature/RateLimitingTest.php
Normal file
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Models\User;
|
||||
use Database\Seeders\RolesAndPermissionsSeeder;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
class RateLimitingTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_login_is_throttled_after_five_attempts(): void
|
||||
{
|
||||
$user = User::factory()->approved()->create(['password' => bcrypt('correct-password')]);
|
||||
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
$this->postJson('/web-api/login', [
|
||||
'email' => $user->email,
|
||||
'password' => 'wrong-password',
|
||||
])->assertUnprocessable();
|
||||
}
|
||||
|
||||
$this->postJson('/web-api/login', [
|
||||
'email' => $user->email,
|
||||
'password' => 'wrong-password',
|
||||
])->assertStatus(429);
|
||||
|
||||
// El throttle es por (email, ip): otro email desde la misma IP no está afectado.
|
||||
$other = User::factory()->approved()->create(['password' => bcrypt('correct-password')]);
|
||||
$this->postJson('/web-api/login', [
|
||||
'email' => $other->email,
|
||||
'password' => 'correct-password',
|
||||
])->assertOk();
|
||||
}
|
||||
|
||||
public function test_register_is_throttled_after_five_attempts(): void
|
||||
{
|
||||
// El primer registro de una instalación vacía toma un camino distinto
|
||||
// (bootstrap admin, 200 en vez de 201, y siembra roles/permisos) — se
|
||||
// crea un usuario previo y se siembran los roles a mano para que
|
||||
// todos los intentos del loop pasen por el camino normal.
|
||||
(new RolesAndPermissionsSeeder)->run();
|
||||
User::factory()->approved()->create();
|
||||
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
$this->postJson('/web-api/register', [
|
||||
'name' => "User {$i}",
|
||||
'email' => "user{$i}@example.com",
|
||||
'password' => 'password123',
|
||||
'password_confirmation' => 'password123',
|
||||
])->assertCreated();
|
||||
}
|
||||
|
||||
$this->postJson('/web-api/register', [
|
||||
'name' => 'One Too Many',
|
||||
'email' => 'onetoomany@example.com',
|
||||
'password' => 'password123',
|
||||
'password_confirmation' => 'password123',
|
||||
])->assertStatus(429);
|
||||
}
|
||||
|
||||
public function test_oauth_token_endpoint_is_throttled_per_client(): void
|
||||
{
|
||||
$owner = User::factory()->approved()->create();
|
||||
$response = $this->actingAs($owner)->postJson('/web-api/clients', [
|
||||
'name' => 'Throttle Test Client',
|
||||
'grant_type' => 'client_credentials',
|
||||
]);
|
||||
$response->assertCreated();
|
||||
$clientId = $response->json('client.id');
|
||||
|
||||
for ($i = 0; $i < 20; $i++) {
|
||||
$this->postJson('/oauth/token', [
|
||||
'grant_type' => 'client_credentials',
|
||||
'client_id' => $clientId,
|
||||
'client_secret' => 'wrong-secret',
|
||||
])->assertStatus(401);
|
||||
}
|
||||
|
||||
$this->postJson('/oauth/token', [
|
||||
'grant_type' => 'client_credentials',
|
||||
'client_id' => $clientId,
|
||||
'client_secret' => 'wrong-secret',
|
||||
])->assertStatus(429);
|
||||
}
|
||||
|
||||
public function test_oauth_token_throttle_is_scoped_per_client_not_globally(): void
|
||||
{
|
||||
$owner = User::factory()->approved()->create();
|
||||
|
||||
$clientA = $this->actingAs($owner)->postJson('/web-api/clients', [
|
||||
'name' => 'Client A',
|
||||
'grant_type' => 'client_credentials',
|
||||
])->json('client.id');
|
||||
|
||||
for ($i = 0; $i < 20; $i++) {
|
||||
$this->postJson('/oauth/token', [
|
||||
'grant_type' => 'client_credentials',
|
||||
'client_id' => $clientA,
|
||||
'client_secret' => 'wrong-secret',
|
||||
]);
|
||||
}
|
||||
$this->postJson('/oauth/token', [
|
||||
'grant_type' => 'client_credentials',
|
||||
'client_id' => $clientA,
|
||||
'client_secret' => 'wrong-secret',
|
||||
])->assertStatus(429);
|
||||
|
||||
$clientBResponse = $this->actingAs($owner)->postJson('/web-api/clients', [
|
||||
'name' => 'Client B',
|
||||
'grant_type' => 'client_credentials',
|
||||
]);
|
||||
$clientBSecret = $clientBResponse->json('plain_secret');
|
||||
$clientBId = $clientBResponse->json('client.id');
|
||||
|
||||
$this->postJson('/oauth/token', [
|
||||
'grant_type' => 'client_credentials',
|
||||
'client_id' => $clientBId,
|
||||
'client_secret' => $clientBSecret,
|
||||
'scope' => 'users:read',
|
||||
])->assertOk();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user