Files
dafuweng-buildadmin/dafuweng-webman/app/common/event/Security.php
2026-03-07 19:42:22 +08:00

155 lines
6.1 KiB
PHP
Raw 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
declare(strict_types=1);
namespace app\common\event;
/**
* 后台安全事件(数据回收、敏感数据记录)
* 迁移自 app/common/event/Security.php需 Admin、Token、DataRecycle 等模型支持
*/
class Security
{
protected array $listenAction = ['edit', 'del'];
/**
* @param mixed $auth Auth 实例backendInit 传入)
*/
public function handle(mixed $auth): bool
{
$request = function_exists('request') ? request() : null;
if (!$request) {
return true;
}
$action = $this->getActionFromPath($request->path());
if (!in_array($action, $this->listenAction)) {
return true;
}
if ($action === 'del' && $request->method() !== 'POST' && $request->method() !== 'DELETE') {
return true;
}
if ($action === 'edit' && $request->method() !== 'POST') {
return true;
}
if (!class_exists(\app\admin\model\DataRecycle::class) || !class_exists(\app\admin\model\SensitiveData::class)) {
return true;
}
if ($action === 'del') {
return $this->handleDel($request, $auth);
}
return $this->handleEdit($request, $auth);
}
protected function getActionFromPath(string $path): string
{
$parts = explode('/', trim($path, '/'));
return $parts[array_key_last($parts)] ?? '';
}
protected function handleDel($request, $auth): bool
{
$dataIds = $request->post('ids') ?? $request->get('ids');
if (!$dataIds) {
return true;
}
try {
$controllerPath = get_controller_path($request) ?? '';
$recycle = \app\admin\model\DataRecycle::where('status', 1)
->where('controller_as', $controllerPath)
->find();
if (!$recycle) {
return true;
}
$connection = class_exists(\ba\TableManager::class)
? \ba\TableManager::getConnection($recycle['connection'])
: null;
$db = $connection ? \support\think\Db::connect($connection) : \support\think\Db::connect();
$recycleData = $db->name($recycle['data_table'])
->whereIn($recycle['primary_key'], $dataIds)
->select()
->toArray();
$recycleDataArr = [];
$adminId = $auth && $auth->isLogin() ? $auth->id : 0;
foreach ($recycleData as $item) {
$recycleDataArr[] = [
'admin_id' => $adminId,
'recycle_id' => $recycle['id'],
'data' => json_encode($item, JSON_UNESCAPED_UNICODE),
'connection' => $recycle['connection'],
'data_table' => $recycle['data_table'],
'primary_key' => $recycle['primary_key'],
'ip' => $request->getRealIp(),
'useragent' => substr($request->header('user-agent', ''), 0, 255),
];
}
if ($recycleDataArr) {
$model = new \app\admin\model\DataRecycleLog();
$model->saveAll($recycleDataArr);
}
} catch (\Throwable $e) {
\support\Log::warning('[DataSecurity] ' . $e->getMessage());
}
return true;
}
protected function handleEdit($request, $auth): bool
{
try {
$controllerPath = get_controller_path($request) ?? '';
$sensitiveData = \app\admin\model\SensitiveData::where('status', 1)
->where('controller_as', $controllerPath)
->find();
if (!$sensitiveData) {
return true;
}
$sensitiveData = $sensitiveData->toArray();
$dataId = $request->post($sensitiveData['primary_key']) ?? $request->get($sensitiveData['primary_key']);
$connection = class_exists(\ba\TableManager::class)
? \ba\TableManager::getConnection($sensitiveData['connection'])
: null;
$db = $connection ? \support\think\Db::connect($connection) : \support\think\Db::connect();
$editData = $db->name($sensitiveData['data_table'])
->field(array_keys($sensitiveData['data_fields']))
->where($sensitiveData['primary_key'], $dataId)
->find();
if (!$editData) {
return true;
}
$newData = $request->post();
$sensitiveDataLog = [];
foreach ($sensitiveData['data_fields'] as $field => $title) {
if (isset($editData[$field]) && isset($newData[$field]) && $editData[$field] != $newData[$field]) {
$newVal = $newData[$field];
if (stripos($field, 'password') !== false && $newVal) {
$newVal = '******';
}
$sensitiveDataLog[] = [
'admin_id' => $auth && $auth->isLogin() ? $auth->id : 0,
'sensitive_id' => $sensitiveData['id'],
'connection' => $sensitiveData['connection'],
'data_table' => $sensitiveData['data_table'],
'primary_key' => $sensitiveData['primary_key'],
'data_field' => $field,
'data_comment' => $title,
'id_value' => $dataId,
'before' => $editData[$field],
'after' => $newVal,
'ip' => $request->getRealIp(),
'useragent' => substr($request->header('user-agent', ''), 0, 255),
];
}
}
if ($sensitiveDataLog) {
$model = new \app\admin\model\SensitiveDataLog();
$model->saveAll($sensitiveDataLog);
}
} catch (\Throwable $e) {
\support\Log::warning('[DataSecurity] ' . $e->getMessage());
}
return true;
}
}