Security.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. <?php
  2. namespace app\common\event;
  3. use Throwable;
  4. use think\Request;
  5. use ba\TableManager;
  6. use think\facade\Db;
  7. use think\facade\Log;
  8. use app\admin\library\Auth;
  9. use app\admin\model\SensitiveDataLog;
  10. use app\admin\model\DataRecycle;
  11. use app\admin\model\DataRecycleLog;
  12. use app\admin\model\SensitiveData;
  13. class Security
  14. {
  15. protected array $listenAction = ['edit', 'del'];
  16. public function handle(Request $request): bool
  17. {
  18. $action = $request->action(true);
  19. if (!in_array($action, $this->listenAction) || (!$request->isPost() && !$request->isDelete())) {
  20. return true;
  21. }
  22. if ($action == 'del') {
  23. $dataIds = $request->param('ids');
  24. try {
  25. $recycle = DataRecycle::where('status', '1')
  26. ->where('controller_as', $request->controllerPath)
  27. ->find();
  28. if (!$recycle) {
  29. return true;
  30. }
  31. $recycleData = Db::connect(TableManager::getConnection($recycle['connection']))
  32. ->name($recycle['data_table'])
  33. ->whereIn($recycle['primary_key'], $dataIds)
  34. ->select()
  35. ->toArray();
  36. $recycleDataArr = [];
  37. $auth = Auth::instance();
  38. $adminId = $auth->isLogin() ? $auth->id : 0;
  39. foreach ($recycleData as $recycleDatum) {
  40. $recycleDataArr[] = [
  41. 'admin_id' => $adminId,
  42. 'recycle_id' => $recycle['id'],
  43. 'data' => json_encode($recycleDatum, JSON_UNESCAPED_UNICODE),
  44. 'connection' => $recycle['connection'],
  45. 'data_table' => $recycle['data_table'],
  46. 'primary_key' => $recycle['primary_key'],
  47. 'ip' => $request->ip(),
  48. 'useragent' => substr($request->server('HTTP_USER_AGENT'), 0, 255),
  49. ];
  50. }
  51. if (!$recycleDataArr) {
  52. return true;
  53. }
  54. // saveAll 方法自带事务
  55. $dataRecycleLogModel = new DataRecycleLog();
  56. if (!$dataRecycleLogModel->saveAll($recycleDataArr)) {
  57. Log::record('[ DataSecurity ] Failed to recycle data:' . var_export($recycleDataArr, true), 'warning');
  58. }
  59. } catch (Throwable $e) {
  60. Log::record('[ DataSecurity ]' . $e->getMessage(), 'warning');
  61. }
  62. return true;
  63. }
  64. try {
  65. $sensitiveData = SensitiveData::where('status', '1')
  66. ->where('controller_as', $request->controllerPath)
  67. ->find();
  68. if (!$sensitiveData) {
  69. return true;
  70. }
  71. $sensitiveData = $sensitiveData->toArray();
  72. $dataId = $request->param($sensitiveData['primary_key']);
  73. $editData = Db::connect(TableManager::getConnection($sensitiveData['connection']))
  74. ->name($sensitiveData['data_table'])
  75. ->field(array_keys($sensitiveData['data_fields']))
  76. ->where($sensitiveData['primary_key'], $dataId)
  77. ->find();
  78. if (!$editData) {
  79. return true;
  80. }
  81. $auth = Auth::instance();
  82. $adminId = $auth->isLogin() ? $auth->id : 0;
  83. $newData = $request->post();
  84. foreach ($sensitiveData['data_fields'] as $field => $title) {
  85. if (isset($editData[$field]) && isset($newData[$field]) && $editData[$field] != $newData[$field]) {
  86. /*
  87. * 其他跳过规则可添加至此处
  88. * 1. 如果字段名中包含 password,修改值为空则忽略,修改值不为空,则密码记录为 ******
  89. */
  90. if (stripos('password', $field) !== false) {
  91. if (!$newData[$field]) {
  92. continue;
  93. } else {
  94. $newData[$field] = "******";
  95. }
  96. }
  97. $sensitiveDataLog[] = [
  98. 'admin_id' => $adminId,
  99. 'sensitive_id' => $sensitiveData['id'],
  100. 'connection' => $sensitiveData['connection'],
  101. 'data_table' => $sensitiveData['data_table'],
  102. 'primary_key' => $sensitiveData['primary_key'],
  103. 'data_field' => $field,
  104. 'data_comment' => $title,
  105. 'id_value' => $dataId,
  106. 'before' => $editData[$field],
  107. 'after' => $newData[$field],
  108. 'ip' => $request->ip(),
  109. 'useragent' => substr($request->server('HTTP_USER_AGENT'), 0, 255),
  110. ];
  111. }
  112. }
  113. if (!isset($sensitiveDataLog) || !$sensitiveDataLog) {
  114. return true;
  115. }
  116. $sensitiveDataLogModel = new SensitiveDataLog();
  117. if (!$sensitiveDataLogModel->saveAll($sensitiveDataLog)) {
  118. Log::record('[ DataSecurity ] Sensitive data recording failed:' . var_export($sensitiveDataLog, true), 'warning');
  119. }
  120. } catch (Throwable $e) {
  121. Log::record('[ DataSecurity ]' . $e->getMessage(), 'warning');
  122. }
  123. return true;
  124. }
  125. }