88 خطوط
2.7 KiB
PHP
88 خطوط
2.7 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\File;
|
|
use App\Models\Project;
|
|
use App\Models\User;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Http\UploadedFile;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Tests\TestCase;
|
|
|
|
class SecurityHardeningTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
public function test_login_is_rate_limited(): void
|
|
{
|
|
for ($i = 0; $i < 5; $i++) {
|
|
$this->postJson('/api/login', [
|
|
'email' => 'missing@example.com',
|
|
'password' => 'wrong-password',
|
|
])->assertUnauthorized();
|
|
}
|
|
|
|
$this->postJson('/api/login', [
|
|
'email' => 'missing@example.com',
|
|
'password' => 'wrong-password',
|
|
])->assertTooManyRequests();
|
|
}
|
|
|
|
public function test_file_upload_rejects_executable_files(): void
|
|
{
|
|
Storage::fake('local');
|
|
|
|
$user = User::factory()->create(['status' => 'active']);
|
|
$this->grantAdminRole($user);
|
|
$project = Project::create([
|
|
'title' => 'Security test project',
|
|
'project_manager_id' => $user->id,
|
|
'created_by' => $user->id,
|
|
]);
|
|
$token = $user->createToken('api-token')->plainTextToken;
|
|
|
|
$this->withToken($token)
|
|
->postJson('/api/files', [
|
|
'project_id' => $project->id,
|
|
'file' => UploadedFile::fake()->create('payload.php', 4, 'application/x-php'),
|
|
])
|
|
->assertUnprocessable();
|
|
}
|
|
|
|
public function test_file_resource_does_not_expose_storage_path(): void
|
|
{
|
|
$user = User::factory()->create(['status' => 'active']);
|
|
$this->grantAdminRole($user);
|
|
$file = File::create([
|
|
'name' => 'safe.pdf',
|
|
'original_name' => 'safe.pdf',
|
|
'path' => 'files/private-safe.pdf',
|
|
'mime_type' => 'application/pdf',
|
|
'size' => 123,
|
|
'fileable_type' => Project::class,
|
|
'fileable_id' => 1,
|
|
'user_id' => $user->id,
|
|
]);
|
|
|
|
$token = $user->createToken('api-token')->plainTextToken;
|
|
|
|
$this->withToken($token)
|
|
->getJson('/api/files')
|
|
->assertOk()
|
|
->assertJsonMissingPath('data.0.path')
|
|
->assertJsonPath('data.0.download_url', url("/api/files/{$file->id}"));
|
|
}
|
|
|
|
public function test_user_without_permission_cannot_access_user_management(): void
|
|
{
|
|
$user = User::factory()->create(['status' => 'active']);
|
|
$token = $user->createToken('api-token')->plainTextToken;
|
|
|
|
$this->withToken($token)
|
|
->getJson('/api/users')
|
|
->assertForbidden()
|
|
->assertJsonPath('success', false);
|
|
}
|
|
}
|