diff --git a/app/admin/controller/Module.php b/app/admin/controller/Module.php index c403ed675..a25d8f115 100644 --- a/app/admin/controller/Module.php +++ b/app/admin/controller/Module.php @@ -38,7 +38,7 @@ class Module extends Controller } /** - * 安装模块代码 + * 安装更新模块 * @auth true */ public function install() diff --git a/app/admin/controller/api/Update.php b/app/admin/controller/api/Update.php index aae87a427..3405fdb00 100644 --- a/app/admin/controller/api/Update.php +++ b/app/admin/controller/api/Update.php @@ -27,22 +27,19 @@ use think\admin\service\ModuleService; class Update extends Controller { - /** - * 获取模块信息 - */ - public function version() - { - $modules = ModuleService::instance()->getModules(); - $this->success('获取模块信息成功!', $modules); - } - /** * 读取文件内容 */ public function get() { - if (file_exists($file = $this->app->getRootPath() . decode(input('encode', '0')))) { - $this->success('读取文件成功!', ['content' => base64_encode(file_get_contents($file))]); + $filename = decode(input('encode', '0')); + if (!ModuleService::instance()->checkAllowDownload($filename)) { + $this->error('下载的文件不在认证规则中!'); + } + if (file_exists($realname = $this->app->getRootPath() . $filename)) { + $this->success('读取文件内容成功!', [ + 'content' => base64_encode(file_get_contents($realname)), + ]); } else { $this->error('读取文件内容失败!'); } @@ -59,4 +56,12 @@ class Update extends Controller )); } + /** + * 获取模块信息 + */ + public function version() + { + $this->success('获取模块信息成功!', ModuleService::instance()->getModules()); + } + } \ No newline at end of file diff --git a/app/admin/ver.php b/app/admin/ver.php index 0bec9a057..651dfbf37 100644 --- a/app/admin/ver.php +++ b/app/admin/ver.php @@ -17,11 +17,15 @@ return [ 'name' => 'admin', 'author' => 'Anyon', - 'version' => '2020.08.01.00', + 'version' => '2020.08.05.00', 'content' => 'ThinkAdmin 系统基础模块', 'changes' => [ + '2020.08.05.00' => [ + 'content' => '优化系统模块管理', + 'database' => ['select version()'], + ], '2020.08.03.00' => [ - 'content' => '模块初始化提交', + 'content' => '系统模块初始化提交', 'database' => ['select version()'], ], ], diff --git a/composer.lock b/composer.lock index 02ea75ba2..0a63db318 100644 --- a/composer.lock +++ b/composer.lock @@ -879,12 +879,12 @@ "source": { "type": "git", "url": "https://github.com/zoujingli/ThinkLibrary.git", - "reference": "d799064954094a3ca5d548d2b6e1e575a4dbeac5" + "reference": "8e1a13fd20d0a454ecccab056a0f6ebe477fe65f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/d799064954094a3ca5d548d2b6e1e575a4dbeac5", - "reference": "d799064954094a3ca5d548d2b6e1e575a4dbeac5", + "url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/8e1a13fd20d0a454ecccab056a0f6ebe477fe65f", + "reference": "8e1a13fd20d0a454ecccab056a0f6ebe477fe65f", "shasum": "", "mirrors": [ { @@ -928,7 +928,7 @@ ], "description": "ThinkPHP v6.0 Development Library", "homepage": "http://thinkadmin.top", - "time": "2020-08-03T09:33:56+00:00" + "time": "2020-08-05T02:41:59+00:00" }, { "name": "zoujingli/wechat-developer", diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index fa427f55a..9143ba59b 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -903,12 +903,12 @@ "source": { "type": "git", "url": "https://github.com/zoujingli/ThinkLibrary.git", - "reference": "d799064954094a3ca5d548d2b6e1e575a4dbeac5" + "reference": "8e1a13fd20d0a454ecccab056a0f6ebe477fe65f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/d799064954094a3ca5d548d2b6e1e575a4dbeac5", - "reference": "d799064954094a3ca5d548d2b6e1e575a4dbeac5", + "url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/8e1a13fd20d0a454ecccab056a0f6ebe477fe65f", + "reference": "8e1a13fd20d0a454ecccab056a0f6ebe477fe65f", "shasum": "", "mirrors": [ { @@ -924,7 +924,7 @@ "ext-json": "*", "topthink/framework": "^6.0" }, - "time": "2020-08-03T09:33:56+00:00", + "time": "2020-08-05T02:41:59+00:00", "type": "library", "extra": { "think": { diff --git a/vendor/services.php b/vendor/services.php index 07e65285b..bee730bc1 100644 --- a/vendor/services.php +++ b/vendor/services.php @@ -1,5 +1,5 @@ 'think\\admin\\Library', diff --git a/vendor/zoujingli/think-library/src/Library.php b/vendor/zoujingli/think-library/src/Library.php index 2e7a5c8e2..3fd62944c 100644 --- a/vendor/zoujingli/think-library/src/Library.php +++ b/vendor/zoujingli/think-library/src/Library.php @@ -62,18 +62,20 @@ class Library extends Service */ public function register() { + // 输入默认过滤 + $this->app->request->filter(['trim']); // 加载中文语言 $this->app->lang->load(__DIR__ . '/lang/zh-cn.php', 'zh-cn'); $this->app->lang->load(__DIR__ . '/lang/en-us.php', 'en-us'); - // 输入变量默认过滤 - $this->app->request->filter(['trim']); // 判断访问模式,兼容 CLI 访问控制器 if ($this->app->request->isCli()) { if (empty($_SERVER['REQUEST_URI']) && isset($_SERVER['argv'][1])) { $this->app->request->setPathinfo($_SERVER['argv'][1]); } } else { - if ($this->app->request->request('not_init_session', 0) == 0) { + $isSess = $this->app->request->request('not_init_session', 0) > 0; + $notYar = stripos($this->app->request->header('user-agent', ''), 'PHP Yar RPC-') !== false; + if ($notYar && $isSess) { // 注册会话初始化中间键 $this->app->middleware->add(SessionInit::class); // 注册语言包处理中间键 diff --git a/vendor/zoujingli/think-library/src/command/Install.php b/vendor/zoujingli/think-library/src/command/Install.php index 37aad8562..978d1da6b 100644 --- a/vendor/zoujingli/think-library/src/command/Install.php +++ b/vendor/zoujingli/think-library/src/command/Install.php @@ -117,7 +117,7 @@ class Install extends Command $data = InstallService::instance()->grenerateDifference($this->rules, $this->ignore); if (empty($data)) $this->output->writeln('No need to update the file if the file comparison is consistent'); else foreach ($data as $file) { - [$state, $mode, $name] = InstallService::instance()->fileSynchronization($file); + [$state, $mode, $name] = InstallService::instance()->updateFileByDownload($file); if ($state) { if ($mode === 'add') $this->output->writeln("--- {$name} add successfully"); if ($mode === 'mod') $this->output->writeln("--- {$name} update successfully"); diff --git a/vendor/zoujingli/think-library/src/service/AdminService.php b/vendor/zoujingli/think-library/src/service/AdminService.php index bf2142454..781f2bc8c 100644 --- a/vendor/zoujingli/think-library/src/service/AdminService.php +++ b/vendor/zoujingli/think-library/src/service/AdminService.php @@ -142,7 +142,7 @@ class AdminService extends Service */ public function clearCache() { - $this->app->cache->delete('system_auth_node'); + $this->app->cache->delete('SystemAuthNode'); return $this; } diff --git a/vendor/zoujingli/think-library/src/service/InstallService.php b/vendor/zoujingli/think-library/src/service/InstallService.php index b84cd3752..0e7779fc8 100644 --- a/vendor/zoujingli/think-library/src/service/InstallService.php +++ b/vendor/zoujingli/think-library/src/service/InstallService.php @@ -60,12 +60,12 @@ class InstallService extends Service */ protected function initialize() { - // 应用根目录 - $this->root = strtr($this->app->getRootPath(), '\\', '/'); // 应用框架版本 $this->version = $this->app->config->get('app.thinkadmin_ver') ?: 'v4'; // 线上应用代码 $this->server = "https://{$this->version}.thinkadmin.top"; + // 应用根目录 + $this->root = strtr($this->app->getRootPath(), '\\', '/'); } /** @@ -87,11 +87,11 @@ class InstallService extends Service } /** - * 同步更新文件 - * @param array $file + * 下载并更新文件 + * @param array $file 文件信息 * @return array */ - public function fileSynchronization($file) + public function updateFileByDownload(array $file): array { if (in_array($file['type'], ['add', 'mod'])) { if ($this->downloadFile(encode($file['name']))) { @@ -117,7 +117,8 @@ class InstallService extends Service */ private function downloadFile($encode) { - $result = json_decode(HttpExtend::get("{$this->server}?s=admin/api.update/get&encode={$encode}"), true); + $source = "{$this->server}/admin/api.update/get?encode={$encode}"; + $result = json_decode(HttpExtend::get($source), true); if (empty($result['code'])) return false; $filename = $this->root . decode($encode); file_exists(dirname($filename)) || mkdir(dirname($filename), 0755, true); @@ -141,10 +142,10 @@ class InstallService extends Service * @param array $ignore 忽略规则 * @return array */ - public function grenerateDifference($rules = [], $ignore = []) + public function grenerateDifference(array $rules = [], array $ignore = []): array { [$this->rules, $this->ignore, $data] = [$rules, $ignore, []]; - $result = json_decode(HttpExtend::post("{$this->server}?s=/admin/api.update/node", [ + $result = json_decode(HttpExtend::post("{$this->server}/admin/api.update/node", [ 'rules' => json_encode($this->rules), 'ignore' => json_encode($this->ignore), ]), true); if (!empty($result['code'])) { @@ -164,24 +165,24 @@ class InstallService extends Service * @param array $local 本地文件列表信息 * @return array */ - private function grenerateDifferenceContrast(array $serve = [], array $local = []) + private function grenerateDifferenceContrast(array $serve = [], array $local = []): array { // 数据扁平化 - [$_serve, $_local, $_new] = [[], [], []]; + [$_serve, $_local, $_diffy] = [[], [], []]; foreach ($serve as $t) $_serve[$t['name']] = $t; foreach ($local as $t) $_local[$t['name']] = $t; unset($serve, $local); // 线上数据差异计算 - foreach ($_serve as $t) isset($_local[$t['name']]) ? array_push($_new, [ + foreach ($_serve as $t) isset($_local[$t['name']]) ? array_push($_diffy, [ 'type' => $t['hash'] === $_local[$t['name']]['hash'] ? null : 'mod', 'name' => $t['name'], - ]) : array_push($_new, ['type' => 'add', 'name' => $t['name']]); + ]) : array_push($_diffy, ['type' => 'add', 'name' => $t['name']]); // 本地数据增量计算 - foreach ($_local as $t) if (!isset($_serve[$t['name']])) array_push($_new, ['type' => 'del', 'name' => $t['name']]); + foreach ($_local as $t) if (!isset($_serve[$t['name']])) array_push($_diffy, ['type' => 'del', 'name' => $t['name']]); unset($_serve, $_local); - usort($_new, function ($a, $b) { + usort($_diffy, function ($a, $b) { return $a['name'] !== $b['name'] ? ($a['name'] > $b['name'] ? 1 : -1) : 0; }); - return $_new; + return $_diffy; } /** @@ -191,7 +192,7 @@ class InstallService extends Service * @param array $data 扫描结果列表 * @return array */ - public function getList(array $rules, array $ignore = [], array $data = []) + public function getList(array $rules, array $ignore = [], array $data = []): array { // 扫描规则文件 foreach ($rules as $key => $rule) { @@ -199,9 +200,10 @@ class InstallService extends Service $data = array_merge($data, $this->scanList("{$this->root}{$name}")); } // 清除忽略文件 - foreach ($data as $key => $item) foreach ($ignore as $ingore) { - if (stripos($item['name'], $ingore) === 0) unset($data[$key]); + foreach ($data as $key => $item) foreach ($ignore as $igr) { + if (stripos($item['name'], $igr) === 0) unset($data[$key]); } + // 返回文件数据 return ['rules' => $rules, 'ignore' => $ignore, 'list' => $data]; } @@ -211,7 +213,7 @@ class InstallService extends Service * @param array $data 扫描结果 * @return array */ - private function scanList($path, $data = []) + private function scanList($path, $data = []): array { if (file_exists($path)) if (is_dir($path)) foreach (scandir($path) as $sub) { if (strpos($sub, '.') !== 0) if (is_dir($temp = "{$path}/{$sub}")) { @@ -227,14 +229,14 @@ class InstallService extends Service /** * 获取指定文件信息 - * @param string $filename + * @param string $realname 文件路径 * @return array */ - private function getInfo($filename) + private function getInfo($realname): array { return [ - 'name' => str_replace($this->root, '', $filename), - 'hash' => md5(preg_replace('/\s+/', '', file_get_contents($filename))), + 'name' => str_replace($this->root, '', $realname), + 'hash' => md5(preg_replace('/\s+/', '', file_get_contents($realname))), ]; } } \ No newline at end of file diff --git a/vendor/zoujingli/think-library/src/service/ModuleService.php b/vendor/zoujingli/think-library/src/service/ModuleService.php index def9c7de2..670f747ba 100644 --- a/vendor/zoujingli/think-library/src/service/ModuleService.php +++ b/vendor/zoujingli/think-library/src/service/ModuleService.php @@ -81,7 +81,7 @@ class ModuleService extends Service } else { $lines = []; foreach ($data as $file) { - [$state, $mode, $name] = InstallService::instance()->fileSynchronization($file); + [$state, $mode, $name] = InstallService::instance()->updateFileByDownload($file); if ($state) { if ($mode === 'add') $lines[] = "add {$name} successed"; if ($mode === 'mod') $lines[] = "modify {$name} successed"; @@ -113,6 +113,39 @@ class ModuleService extends Service return $data; } + /** + * 获取允许下载的规则 + * @return array + */ + public function getAllowDownloadRule(): array + { + $data = $this->app->cache->get('moduleAllowRule', []); + if (is_array($data) && count($data) > 0) return $data; + $data = ['config', 'public/static']; + foreach (array_keys($this->getModules()) as $name) $data[] = "app/{$name}"; + $this->app->cache->set('moduleAllowRule', $data, 30); + return $data; + } + + /** + * 检查文件是否可下载 + * @param string $name 文件名称 + * @return boolean + */ + public function checkAllowDownload($name): bool + { + // 禁止下载数据库配置文件 + if (stripos($name, 'database.php') !== false) { + return false; + } + // 检查允许下载的文件规则 + foreach ($this->getAllowDownloadRule() as $rule) { + if (stripos($name, $rule) !== false) return true; + } + // 不在允许下载的文件规则 + return false; + } + /** * 获取模块版本信息 * @param string $name 模块名称 diff --git a/vendor/zoujingli/think-library/src/service/NodeService.php b/vendor/zoujingli/think-library/src/service/NodeService.php index 7cad7d218..52e8033f3 100644 --- a/vendor/zoujingli/think-library/src/service/NodeService.php +++ b/vendor/zoujingli/think-library/src/service/NodeService.php @@ -94,7 +94,7 @@ class NodeService extends Service static $data = []; if (empty($force)) { if (count($data) > 0) return $data; - $data = $this->app->cache->get('system_auth_node', []); + $data = $this->app->cache->get('SystemAuthNode', []); if (count($data) > 0) return $data; } else { $data = []; @@ -113,7 +113,7 @@ class NodeService extends Service } } $data = array_change_key_case($data, CASE_LOWER); - $this->app->cache->set('system_auth_node', $data); + $this->app->cache->set('SystemAuthNode', $data); return $data; } diff --git a/vendor/zoujingli/think-library/src/service/OpenService.php b/vendor/zoujingli/think-library/src/service/OpenService.php index 4ca3e4980..793a277ca 100644 --- a/vendor/zoujingli/think-library/src/service/OpenService.php +++ b/vendor/zoujingli/think-library/src/service/OpenService.php @@ -55,6 +55,17 @@ class OpenService extends Service $this->appkey = $appkey ?: sysconf('data.cuci_open_appkey'); } + /** + * 接口数据签名 + * @param array $data [time, nostr, json, sign] + * @return array + */ + public function signData(array $data): array + { + [$time, $nostr, $json] = [time(), uniqid(), json_encode($data, JSON_UNESCAPED_UNICODE)]; + return [$time, $nostr, $json, md5("{$this->appid}#{$json}#{$time}#{$this->appkey}#{$nostr}")]; + } + /** * 接口数据请求 * @param string $uri 接口地址 @@ -64,11 +75,10 @@ class OpenService extends Service */ public function doRequest(string $uri, array $data = []): array { - [$time, $nostr, $json] = [time(), uniqid(), json_encode($data)]; - $sign = md5($this->appid . '#' . $json . '#' . $time . '#' . $this->appkey . '#' . $nostr); - $data = ['appid' => $this->appid, 'time' => $time, 'nostr' => $nostr, 'sign' => $sign, 'data' => $json]; - $result = json_decode(HttpExtend::post("https://open.cuci.cc/{$uri}", $data), true); - if (empty($result)) throw new \think\admin\Exception('接口响应异常'); + [$time, $nostr, $json, $sign] = $this->signData($data); + $post = ['appid' => $this->appid, 'time' => $time, 'nostr' => $nostr, 'sign' => $sign, 'data' => $json]; + $result = json_decode(HttpExtend::post("https://open.cuci.cc/{$uri}", $post), true); + if (empty($result)) throw new \think\admin\Exception('服务端接口响应异常'); if (empty($result['code'])) throw new \think\admin\Exception($result['info']); return $result['data'] ?? []; }