feat: 初始化知识库系统项目

- 实现基于 Laravel 11 和 Filament 3.X 的文档管理系统
- 添加用户认证和分组管理功能
- 实现文档上传、分类和权限控制
- 集成 Word 文档自动转换为 Markdown
- 集成 Meilisearch 全文搜索引擎
- 实现文档在线预览功能
- 添加安全日志和审计功能
- 完整的简体中文界面
- 包含完整的项目文档和部署指南

技术栈:
- Laravel 11.x
- Filament 3.X
- Meilisearch 1.5+
- Pandoc 文档转换
- Redis 队列系统
- Pest PHP 测试框架
This commit is contained in:
Knowledge Base System
2025-12-05 14:44:44 +08:00
commit acf549c43c
165 changed files with 32838 additions and 0 deletions

View File

@@ -0,0 +1,193 @@
<?php
namespace Tests\Feature;
use App\Models\Document;
use App\Models\Group;
use App\Models\User;
use App\Services\SecurityLogger;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Log;
use Tests\TestCase;
class SecurityLoggerTest extends TestCase
{
use RefreshDatabase;
/**
* 测试记录未授权访问尝试
* 需求7.3
*/
public function test_logs_unauthorized_access_attempt(): void
{
// 创建测试数据
$user = User::factory()->create();
$group = Group::factory()->create();
$document = Document::factory()->create([
'type' => 'dedicated',
'group_id' => $group->id,
]);
// 模拟日志记录
Log::shouldReceive('channel')
->with('security')
->once()
->andReturnSelf();
Log::shouldReceive('warning')
->once()
->with('未授权访问尝试', \Mockery::on(function ($context) use ($user, $document) {
return $context['event'] === 'unauthorized_access'
&& $context['action'] === 'view'
&& $context['user_id'] === $user->id
&& $context['document_id'] === $document->id;
}));
// 执行测试
$securityLogger = new SecurityLogger();
$securityLogger->logUnauthorizedAccess($user, $document, 'view');
}
/**
* 测试 DocumentPolicy 在权限验证失败时记录日志
* 需求7.3
*/
public function test_document_policy_logs_unauthorized_view_attempt(): void
{
// 创建测试数据
$user = User::factory()->create();
$otherGroup = Group::factory()->create();
$document = Document::factory()->create([
'type' => 'dedicated',
'group_id' => $otherGroup->id,
]);
// 模拟日志记录
Log::shouldReceive('channel')
->with('security')
->once()
->andReturnSelf();
Log::shouldReceive('warning')
->once()
->with('未授权访问尝试', \Mockery::on(function ($context) {
return $context['event'] === 'unauthorized_access'
&& $context['action'] === 'view';
}));
// 尝试查看文档(应该失败并记录日志)
$canView = $user->can('view', $document);
$this->assertFalse($canView);
}
/**
* 测试 DocumentPolicy 在更新权限验证失败时记录日志
* 需求7.3
*/
public function test_document_policy_logs_unauthorized_update_attempt(): void
{
// 创建测试数据
$uploader = User::factory()->create();
$otherUser = User::factory()->create();
$document = Document::factory()->create([
'uploaded_by' => $uploader->id,
]);
// 模拟日志记录
Log::shouldReceive('channel')
->with('security')
->once()
->andReturnSelf();
Log::shouldReceive('warning')
->once()
->with('未授权访问尝试', \Mockery::on(function ($context) {
return $context['event'] === 'unauthorized_access'
&& $context['action'] === 'update';
}));
// 尝试更新文档(应该失败并记录日志)
$canUpdate = $otherUser->can('update', $document);
$this->assertFalse($canUpdate);
}
/**
* 测试 DocumentPolicy 在删除权限验证失败时记录日志
* 需求7.3
*/
public function test_document_policy_logs_unauthorized_delete_attempt(): void
{
// 创建测试数据
$uploader = User::factory()->create();
$otherUser = User::factory()->create();
$document = Document::factory()->create([
'uploaded_by' => $uploader->id,
]);
// 模拟日志记录
Log::shouldReceive('channel')
->with('security')
->once()
->andReturnSelf();
Log::shouldReceive('warning')
->once()
->with('未授权访问尝试', \Mockery::on(function ($context) {
return $context['event'] === 'unauthorized_access'
&& $context['action'] === 'delete';
}));
// 尝试删除文档(应该失败并记录日志)
$canDelete = $otherUser->can('delete', $document);
$this->assertFalse($canDelete);
}
/**
* 测试安全日志包含完整的上下文信息
* 需求7.3
*/
public function test_security_log_contains_complete_context(): void
{
// 创建测试数据
$user = User::factory()->create([
'name' => '测试用户',
'email' => 'test@example.com',
]);
$group = Group::factory()->create();
$document = Document::factory()->create([
'title' => '测试文档',
'type' => 'dedicated',
'group_id' => $group->id,
]);
// 模拟日志记录并验证上下文
Log::shouldReceive('channel')
->with('security')
->once()
->andReturnSelf();
Log::shouldReceive('warning')
->once()
->with('未授权访问尝试', \Mockery::on(function ($context) use ($user, $document, $group) {
return $context['event'] === 'unauthorized_access'
&& $context['action'] === 'view'
&& $context['user_id'] === $user->id
&& $context['user_name'] === '测试用户'
&& $context['user_email'] === 'test@example.com'
&& $context['document_id'] === $document->id
&& $context['document_title'] === '测试文档'
&& $context['document_type'] === 'dedicated'
&& $context['document_group_id'] === $group->id
&& isset($context['ip_address'])
&& isset($context['timestamp'])
&& isset($context['user_agent']);
}));
// 执行测试
$securityLogger = new SecurityLogger();
$securityLogger->logUnauthorizedAccess($user, $document, 'view');
}
}