Security.php 5.2 KB

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