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