238 lines
7.4 KiB
PHP
238 lines
7.4 KiB
PHP
|
<?php
|
||
|
|
||
|
namespace app\admin\controller\webscan;
|
||
|
|
||
|
use app\common\controller\Backend;
|
||
|
use think\Db;
|
||
|
|
||
|
/**
|
||
|
*文件校验
|
||
|
*/
|
||
|
class Verifies extends Backend
|
||
|
{
|
||
|
//文件校验结果缓存名
|
||
|
private $result_cache_name = 'InconformityCacheArr';
|
||
|
//本地需要校验的文件缓存名
|
||
|
private $loca_cache_name = "WebscanVerifiesCache";
|
||
|
|
||
|
public function _initialize()
|
||
|
{
|
||
|
parent::_initialize();
|
||
|
$this->model = new \app\common\model\webscan\WebscanVerifies();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 校验首页
|
||
|
* @return string|\think\response\Json
|
||
|
* @throws \think\Exception
|
||
|
*/
|
||
|
public function index()
|
||
|
{
|
||
|
|
||
|
if ($this->request->isAjax()) {
|
||
|
/*$search=$this->request->param('search');
|
||
|
$limit=$this->request->param('limit','10','intval');
|
||
|
$offset=$this->request->param('offset','0','intval');
|
||
|
$sort=$this->request->param('sort');
|
||
|
$order=$this->request->param('order');*/
|
||
|
$files_arr = cache($this->result_cache_name);
|
||
|
$count = count($files_arr);
|
||
|
//分页处理
|
||
|
//$files_arr=array_slice($files_arr,$offset,$limit);
|
||
|
$result = array("total" => $count, "rows" => $files_arr);
|
||
|
return json($result);
|
||
|
} else {
|
||
|
$verifi_data = $this->model->where('method', 'local')->count();
|
||
|
|
||
|
if (!$verifi_data) cache($this->loca_cache_name, null);//删除缓存
|
||
|
|
||
|
return $this->view->fetch('', ['verifi_data' => $verifi_data]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 查看文件
|
||
|
*/
|
||
|
public function show($filename)
|
||
|
{
|
||
|
if (file_exists(ROOT_PATH . $filename)) {
|
||
|
show_source(ROOT_PATH . $filename);
|
||
|
} else {
|
||
|
$this->error("文件不存在");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*加入信任
|
||
|
* @param $filename
|
||
|
*/
|
||
|
public function trust($index)
|
||
|
{
|
||
|
$files_arr = cache($this->result_cache_name);
|
||
|
$temp = $files_arr[$index];
|
||
|
|
||
|
if ($temp) {
|
||
|
unset($files_arr[$index]);
|
||
|
$info = $this->model->where('method', $temp['method'])->where('filename', $temp['filename'])->find();
|
||
|
if ($info) {
|
||
|
$info->md5 = $temp['md5'];
|
||
|
$info->save();
|
||
|
} else {
|
||
|
$this->model->insert($temp);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
cache($this->result_cache_name, array_values($files_arr));
|
||
|
$this->success();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*批量信任
|
||
|
* @param $filename
|
||
|
*/
|
||
|
public function trusts($ids)
|
||
|
{
|
||
|
if (!$ids) $this->error("请选择");
|
||
|
|
||
|
$ids = explode(',', $ids);
|
||
|
$files_arr = cache($this->result_cache_name);
|
||
|
|
||
|
//TODO 待优化
|
||
|
foreach ($ids as $index) {
|
||
|
$temp = $files_arr[$index];
|
||
|
if ($temp) {
|
||
|
unset($files_arr[$index]);
|
||
|
$info = $this->model->where('method', $temp['method'])->where('filename', $temp['filename'])->find();
|
||
|
if ($info) {
|
||
|
$info->md5 = $temp['md5'];
|
||
|
$info->save();
|
||
|
} else {
|
||
|
$this->model->insert($temp);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
cache($this->result_cache_name, array_values($files_arr));
|
||
|
$this->success();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 初始化数据
|
||
|
*/
|
||
|
public function build()
|
||
|
{
|
||
|
$verifi_data = $this->model->where('method', 'local')->count();
|
||
|
|
||
|
if (!$verifi_data) {
|
||
|
cache($this->loca_cache_name, null);//删除缓存
|
||
|
} else {
|
||
|
$this->error("已经初始化");
|
||
|
}
|
||
|
|
||
|
$files_arr = $this->readFiles();
|
||
|
|
||
|
if ($files_arr) {
|
||
|
$this->model->insertAll($files_arr);
|
||
|
$this->success("初始化数据成功");
|
||
|
} else {
|
||
|
$this->error("初始化失败");
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*遍历检查
|
||
|
* @param $dir
|
||
|
* @return array
|
||
|
*/
|
||
|
public function bianli()
|
||
|
{
|
||
|
$limit = $this->request->param('limit', '1000', 'intval');
|
||
|
$offset = $this->request->param('offset', '0', 'intval');
|
||
|
|
||
|
if ($offset == 0) {
|
||
|
cache($this->result_cache_name, null);//清空之前的结果
|
||
|
}
|
||
|
|
||
|
$files_arr = $this->readFiles();
|
||
|
$count = count($files_arr);
|
||
|
//分页处理
|
||
|
$files_arr = array_slice($files_arr, $offset, $limit);
|
||
|
|
||
|
if ($files_arr) {
|
||
|
$md5_arr = array_column($files_arr, 'md5');
|
||
|
$subQuery = Db::name('webscan_verifies')->field('md5')->where('md5', 'in', $md5_arr)->buildSql();
|
||
|
$sql = "SELECT md5,method,filename,mktime FROM (";
|
||
|
$tempsql = "";
|
||
|
|
||
|
foreach ($files_arr as $row) {
|
||
|
//TODO待优化
|
||
|
$tempsql .= $tempsql ? " UNION SELECT '" . $row['md5'] . "' as md5, '" . $row['method'] . "' as method ,'" . addslashes($row['filename']) . "' as filename ,'" . $row['mktime'] . "' as mktime " : " SELECT '" . $row['md5'] . "' as md5, '" . $row['method'] . "' as method ,'" . addslashes($row['filename']) . "' as filename ,'" . $row['mktime'] . "' as mktime ";
|
||
|
}
|
||
|
|
||
|
$sql = $sql . $tempsql . ")a WHERE md5 NOT IN(" . $subQuery . ")";
|
||
|
$result = Db::query($sql);
|
||
|
$InconformityCacheArr = cache($this->result_cache_name);
|
||
|
$InconformityCacheArr = $InconformityCacheArr ?: [];
|
||
|
|
||
|
if ($result) {
|
||
|
$InconformityCacheArr = $InconformityCacheArr ? array_merge($InconformityCacheArr, $result) : $result;
|
||
|
cache($this->result_cache_name, $InconformityCacheArr);
|
||
|
}
|
||
|
|
||
|
$this->success("正在检测中,已检测" . ($offset + $limit) . "个文件,有" . count($InconformityCacheArr) . "个文件不一致", url('webscan.verifies/bianli', ['offset' => ($offset + $limit)]));
|
||
|
|
||
|
}
|
||
|
|
||
|
$this->success("检测完成{$count}", url('webscan.verifies/index'));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 读取本地的文件数据
|
||
|
* @return mixed
|
||
|
*/
|
||
|
protected function readFiles()
|
||
|
{
|
||
|
$files_arr = cache($this->loca_cache_name);
|
||
|
|
||
|
if (!$files_arr) {
|
||
|
$config = get_addon_config('webscan');
|
||
|
$suffix = explode('|', $config['files_suffix']);
|
||
|
$dir = $config['ignore_dir'];//忽略的文件夹
|
||
|
$files = new \RecursiveIteratorIterator(
|
||
|
new \RecursiveDirectoryIterator(ROOT_PATH), \RecursiveIteratorIterator::LEAVES_ONLY
|
||
|
);
|
||
|
$i = 0;
|
||
|
|
||
|
foreach ($files as $name => $file) {
|
||
|
$temp_str = str_replace(ROOT_PATH, '', $name);
|
||
|
$search = ["/", "?", "=", ".", "&", '|', '\\'];
|
||
|
$replace = ["\/", "\?", "\=", "\.", "\&", '|^', '\/'];
|
||
|
$white_url = str_replace($search, $replace, $dir);
|
||
|
if (preg_match("/^" . $white_url . "/is", $temp_str)) {
|
||
|
continue;
|
||
|
}
|
||
|
if (!$file->isDir()) {
|
||
|
if (in_array($file->getExtension(), $suffix)) {
|
||
|
$files_arr[$i]['md5'] = md5_file($name);
|
||
|
$files_arr[$i]['filename'] = $temp_str;
|
||
|
$files_arr[$i]['method'] = 'local';
|
||
|
$files_arr[$i]['mktime'] = $file->getMTime();
|
||
|
}
|
||
|
$i++;
|
||
|
}
|
||
|
}
|
||
|
unset($files);
|
||
|
|
||
|
if ($files_arr) {
|
||
|
cache($this->loca_cache_name, $files_arr, 86400);//缓存一天
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
return $files_arr;
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|