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

技术栈:
- Laravel 11.x
- Filament 3.X
- Meilisearch 1.5+
- Pandoc 文档转换
- Redis 队列系统
- Pest PHP 测试框架
2025-12-05 14:44:44 +08:00

202 lines
5.8 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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;
}
}