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