Files
CFDivePlatform/tests/Feature/AdminAccountCreationTest.php
a620906209 aeb8c975e2 security(auth): 移除公開 admin/register 端點,改由 app:create-admin 建立管理員
P0 漏洞:原 POST /api/admin/register 無任何防護,任何人可註冊管理員帳號。
- 移除路由、AuthController::registerAdmin、對應 Swagger 文件
- 新增 app:create-admin artisan command(密碼門檻 min:8)
- 補 AdminAccountCreationTest 防止端點被重新打開
- 同步 admin-auth 規格,並收錄 2026-06-11 稽核報告與路線圖文檔

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 17:36:33 +08:00

82 lines
2.8 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
/**
* 管理員帳號建立途徑防護。
*
* 公開的 POST /api/admin/register 曾允許任何人註冊管理員帳號(P0 漏洞,
* 2026-06-11 稽核移除)。這些測試確保該端點不會被重新打開,
* 且唯一合法途徑是主機端的 app:create-admin command。
*/
class AdminAccountCreationTest extends TestCase
{
use RefreshDatabase;
// ── 公開註冊端點必須保持關閉 ─────────────────────────────
public function test_public_admin_register_endpoint_is_closed(): void
{
$response = $this->postJson('/api/admin/register', [
'name' => 'Evil Admin',
'email' => 'evil@example.com',
'password' => 'password123',
'password_confirmation' => 'password123',
]);
$response->assertStatus(404);
$this->assertDatabaseMissing('users', ['email' => 'evil@example.com']);
$this->assertDatabaseMissing('users', ['email' => 'evil@example.com', 'role' => 'admin']);
}
// ── artisan command 為唯一建立途徑 ───────────────────────
public function test_create_admin_command_creates_admin_with_profile(): void
{
$this->artisan('app:create-admin', [
'name' => 'Ops Admin',
'email' => 'ops@example.com',
'--password' => 'StrongPass99',
])->assertSuccessful();
$this->assertDatabaseHas('users', [
'email' => 'ops@example.com',
'role' => 'admin',
]);
$admin = User::where('email', 'ops@example.com')->first();
$this->assertDatabaseHas('admin_profiles', ['user_id' => $admin->id]);
}
public function test_create_admin_command_rejects_duplicate_email(): void
{
User::factory()->create(['email' => 'exists@example.com']);
$this->artisan('app:create-admin', [
'name' => 'Dup Admin',
'email' => 'exists@example.com',
'--password' => 'StrongPass99',
])->assertFailed();
$this->assertDatabaseMissing('users', [
'email' => 'exists@example.com',
'role' => 'admin',
]);
}
public function test_create_admin_command_rejects_weak_password(): void
{
$this->artisan('app:create-admin', [
'name' => 'Weak Admin',
'email' => 'weak@example.com',
'--password' => 'short',
])->assertFailed();
$this->assertDatabaseMissing('users', ['email' => 'weak@example.com']);
}
}