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:
201
app/Policies/DocumentPolicy.php
Normal file
201
app/Policies/DocumentPolicy.php
Normal file
@@ -0,0 +1,201 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\Document;
|
||||
use App\Models\User;
|
||||
use App\Services\SecurityLogger;
|
||||
use Illuminate\Auth\Access\Response;
|
||||
|
||||
class DocumentPolicy
|
||||
{
|
||||
/**
|
||||
* 安全日志记录器
|
||||
*/
|
||||
protected SecurityLogger $securityLogger;
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(SecurityLogger $securityLogger)
|
||||
{
|
||||
$this->securityLogger = $securityLogger;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断用户是否可以查看文档列表
|
||||
* 所有已认证用户都可以查看文档列表(但列表会根据权限过滤)
|
||||
*
|
||||
* @param User $user
|
||||
* @return bool
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
// 所有已认证用户都可以查看文档列表
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断用户是否可以查看特定文档
|
||||
* 需求:3.1, 3.4, 7.1, 7.2, 7.3
|
||||
* - 全局文档:所有用户都可以查看
|
||||
* - 专用文档:只有所属分组的用户可以查看
|
||||
* - 记录未授权访问尝试
|
||||
*
|
||||
* @param User $user
|
||||
* @param Document $document
|
||||
* @return bool
|
||||
*/
|
||||
public function view(User $user, Document $document): bool
|
||||
{
|
||||
// 如果是全局文档,所有用户都可以查看
|
||||
if ($document->type === 'global') {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 如果是专用文档,检查用户是否属于该文档的分组
|
||||
if ($document->type === 'dedicated') {
|
||||
// 如果文档没有关联分组,拒绝访问
|
||||
if (!$document->group_id) {
|
||||
$this->securityLogger->logUnauthorizedAccess($user, $document, 'view');
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查用户是否属于该文档的分组
|
||||
$hasAccess = $user->groups()->where('groups.id', $document->group_id)->exists();
|
||||
|
||||
// 如果没有权限,记录未授权访问尝试
|
||||
if (!$hasAccess) {
|
||||
$this->securityLogger->logUnauthorizedAccess($user, $document, 'view');
|
||||
}
|
||||
|
||||
return $hasAccess;
|
||||
}
|
||||
|
||||
// 其他情况拒绝访问
|
||||
$this->securityLogger->logUnauthorizedAccess($user, $document, 'view');
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断用户是否可以创建文档
|
||||
* 假设所有已认证用户都可以创建文档(可根据实际需求调整)
|
||||
*
|
||||
* @param User $user
|
||||
* @return bool
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
// 所有已认证用户都可以创建文档
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断用户是否可以更新文档
|
||||
* 只有文档的上传者可以更新文档(可根据实际需求调整为管理员也可以)
|
||||
* 需求:7.3
|
||||
*
|
||||
* @param User $user
|
||||
* @param Document $document
|
||||
* @return bool
|
||||
*/
|
||||
public function update(User $user, Document $document): bool
|
||||
{
|
||||
// 只有文档的上传者可以更新
|
||||
$canUpdate = $document->uploaded_by === $user->id;
|
||||
|
||||
// 如果没有权限,记录未授权访问尝试
|
||||
if (!$canUpdate) {
|
||||
$this->securityLogger->logUnauthorizedAccess($user, $document, 'update');
|
||||
}
|
||||
|
||||
return $canUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断用户是否可以删除文档
|
||||
* 只有文档的上传者可以删除文档(可根据实际需求调整为管理员也可以)
|
||||
* 需求:7.3
|
||||
*
|
||||
* @param User $user
|
||||
* @param Document $document
|
||||
* @return bool
|
||||
*/
|
||||
public function delete(User $user, Document $document): bool
|
||||
{
|
||||
// 只有文档的上传者可以删除
|
||||
$canDelete = $document->uploaded_by === $user->id;
|
||||
|
||||
// 如果没有权限,记录未授权访问尝试
|
||||
if (!$canDelete) {
|
||||
$this->securityLogger->logUnauthorizedAccess($user, $document, 'delete');
|
||||
}
|
||||
|
||||
return $canDelete;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断用户是否可以下载文档
|
||||
* 需求:4.1, 4.2, 7.1, 7.2, 7.3
|
||||
* 下载权限与查看权限相同:
|
||||
* - 全局文档:所有用户都可以下载
|
||||
* - 专用文档:只有所属分组的用户可以下载
|
||||
* - 记录未授权下载尝试
|
||||
*
|
||||
* @param User $user
|
||||
* @param Document $document
|
||||
* @return bool
|
||||
*/
|
||||
public function download(User $user, Document $document): bool
|
||||
{
|
||||
// 下载权限与查看权限相同
|
||||
$canDownload = $this->view($user, $document);
|
||||
|
||||
// 注意:view 方法已经记录了未授权访问,这里不需要重复记录
|
||||
// 但如果需要区分 view 和 download 操作,可以在这里单独记录
|
||||
|
||||
return $canDownload;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断用户是否可以恢复已删除的文档
|
||||
* 需求:7.3
|
||||
*
|
||||
* @param User $user
|
||||
* @param Document $document
|
||||
* @return bool
|
||||
*/
|
||||
public function restore(User $user, Document $document): bool
|
||||
{
|
||||
// 只有文档的上传者可以恢复
|
||||
$canRestore = $document->uploaded_by === $user->id;
|
||||
|
||||
// 如果没有权限,记录未授权访问尝试
|
||||
if (!$canRestore) {
|
||||
$this->securityLogger->logUnauthorizedAccess($user, $document, 'restore');
|
||||
}
|
||||
|
||||
return $canRestore;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断用户是否可以永久删除文档
|
||||
* 需求:7.3
|
||||
*
|
||||
* @param User $user
|
||||
* @param Document $document
|
||||
* @return bool
|
||||
*/
|
||||
public function forceDelete(User $user, Document $document): bool
|
||||
{
|
||||
// 只有文档的上传者可以永久删除
|
||||
$canForceDelete = $document->uploaded_by === $user->id;
|
||||
|
||||
// 如果没有权限,记录未授权访问尝试
|
||||
if (!$canForceDelete) {
|
||||
$this->securityLogger->logUnauthorizedAccess($user, $document, 'forceDelete');
|
||||
}
|
||||
|
||||
return $canForceDelete;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user