You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

407 lines
14 KiB

1 year ago
1 year ago
1 year ago
1 year ago
  1. <?php
  2. namespace app\controller;
  3. use think\facade\Db;
  4. use app\BaseController;
  5. use app\lib\Plugins;
  6. class Api extends BaseController
  7. {
  8. //获取插件列表
  9. public function get_plugin_list(){
  10. if(!$this->checklist()) return '';
  11. $record = Db::name('record')->where('ip',$this->clientip)->find();
  12. if($record){
  13. Db::name('record')->where('id',$record['id'])->update(['usetime'=>date("Y-m-d H:i:s")]);
  14. }else{
  15. Db::name('record')->insert(['ip'=>$this->clientip, 'addtime'=>date("Y-m-d H:i:s"), 'usetime'=>date("Y-m-d H:i:s")]);
  16. }
  17. $json_arr = Plugins::get_plugin_list();
  18. if(!$json_arr) return json((object)[]);
  19. return json($json_arr);
  20. }
  21. //获取插件列表(win)
  22. public function get_plugin_list_win(){
  23. if(!$this->checklist()) return '';
  24. $record = Db::name('record')->where('ip',$this->clientip)->find();
  25. if($record){
  26. Db::name('record')->where('id',$record['id'])->update(['usetime'=>date("Y-m-d H:i:s")]);
  27. }else{
  28. Db::name('record')->insert(['ip'=>$this->clientip, 'addtime'=>date("Y-m-d H:i:s"), 'usetime'=>date("Y-m-d H:i:s")]);
  29. }
  30. $json_file = get_data_dir('Windows').'config/plugin_list.json';
  31. if(file_exists($json_file)){
  32. $data = file_get_contents($json_file);
  33. $json_arr = json_decode($data, true);
  34. if($json_arr){
  35. return json($json_arr);
  36. }
  37. }
  38. return json((object)[]);
  39. }
  40. //下载插件包
  41. public function download_plugin(){
  42. $plugin_name = input('post.name');
  43. $version = input('post.version');
  44. $os = input('post.os');
  45. if(!$plugin_name || !$version){
  46. return '参数不能为空';
  47. }
  48. if(!in_array($os,['Windows','Linux'])) $os = 'Linux';
  49. if(!preg_match('/^[a-zA-Z0-9_]+$/', $plugin_name) || !preg_match('/^[0-9.]+$/', $version)){
  50. return '参数不正确';
  51. }
  52. if(!$this->checklist()) '你的服务器被禁止使用此云端';
  53. $filepath = get_data_dir($os).'plugins/package/'.$plugin_name.'-'.$version.'.zip';
  54. if(file_exists($filepath)){
  55. $filename = $plugin_name.'.zip';
  56. $this->output_file($filepath, $filename);
  57. }else{
  58. return '云端不存在该插件包';
  59. }
  60. }
  61. //下载插件主文件
  62. public function download_plugin_main(){
  63. $plugin_name = input('post.name');
  64. $version = input('post.version');
  65. $os = input('post.os');
  66. if(!$plugin_name || !$version){
  67. return '参数不能为空';
  68. }
  69. if(!in_array($os,['Windows','Linux'])) $os = 'Linux';
  70. if(!preg_match('/^[a-zA-Z0-9_]+$/', $plugin_name) || !preg_match('/^[0-9.]+$/', $version)){
  71. return '参数不正确';
  72. }
  73. if(!$this->checklist()) '你的服务器被禁止使用此云端';
  74. $filepath = get_data_dir($os).'plugins/main/'.$plugin_name.'-'.$version.'.dat';
  75. if(file_exists($filepath)){
  76. $filename = $plugin_name.'_main.py';
  77. $this->output_file($filepath, $filename);
  78. }else{
  79. $filepath = get_data_dir($os).'plugins/folder/'.$plugin_name.'-'.$version.'/'.$plugin_name.'/'.$plugin_name.'_main.py';
  80. if(file_exists($filepath)){
  81. $filename = $plugin_name.'_main.py';
  82. $this->output_file($filepath, $filename);
  83. }else{
  84. return '云端不存在该插件主文件';
  85. }
  86. }
  87. }
  88. //下载插件其他文件
  89. public function download_plugin_other(){
  90. $fname = input('get.fname');
  91. if(!$fname){
  92. return json(['status'=>false, 'msg'=>'参数不能为空']);
  93. }
  94. if(strpos(dirname($fname),'.')!==false)return json(['status'=>false, 'msg'=>'参数不正确']);
  95. if(!$this->checklist()) return json(['status'=>false, 'msg'=>'你的服务器被禁止使用此云端']);
  96. $filepath = get_data_dir().'plugins/other/'.$fname;
  97. if(file_exists($filepath)){
  98. $filename = basename($fname);
  99. $this->output_file($filepath, $filename);
  100. }else{
  101. return json(['status'=>false, 'msg'=>'云端不存在该插件文件']);
  102. }
  103. }
  104. public function get_update_logs(){
  105. $type = input('get.type');
  106. if($type == 'Windows'){
  107. $version = config_get('new_version_win');
  108. $data = [
  109. [
  110. 'title' => 'Linux面板'.$version,
  111. 'body' => config_get('update_msg_win'),
  112. 'addtime' => config_get('update_date_win')
  113. ]
  114. ];
  115. }else{
  116. $version = config_get('new_version');
  117. $data = [
  118. [
  119. 'title' => 'Linux面板'.$version,
  120. 'body' => config_get('update_msg'),
  121. 'addtime' => config_get('update_date')
  122. ]
  123. ];
  124. }
  125. return jsonp($data);
  126. }
  127. public function get_version(){
  128. $version = config_get('new_version');
  129. return $version;
  130. }
  131. public function get_version_win(){
  132. $version = config_get('new_version_win');
  133. return $version;
  134. }
  135. //安装统计
  136. public function setup_count(){
  137. return 'ok';
  138. }
  139. //检测更新
  140. public function check_update(){
  141. $version = config_get('new_version');
  142. $down_url = request()->root(true).'/install/update/LinuxPanel-'.$version.'.zip';
  143. $data = [
  144. 'force' => false,
  145. 'version' => $version,
  146. 'downUrl' => $down_url,
  147. 'updateMsg' => config_get('update_msg'),
  148. 'uptime' => config_get('update_date'),
  149. 'is_beta' => 0,
  150. 'adviser' => -1,
  151. 'btb' => '',
  152. 'beta' => [
  153. 'version' => $version,
  154. 'downUrl' => $down_url,
  155. 'updateMsg' => config_get('update_msg'),
  156. 'uptime' => config_get('update_date'),
  157. ]
  158. ];
  159. return json($data);
  160. }
  161. //检测更新(win)
  162. public function check_update_win(){
  163. $version = config_get('new_version_win');
  164. $down_url = request()->root(true).'/win/panel/panel_'.$version.'.zip';
  165. $data = [
  166. 'force' => false,
  167. 'version' => $version,
  168. 'downUrl' => $down_url,
  169. 'updateMsg' => config_get('update_msg_win'),
  170. 'uptime' => config_get('update_date_win'),
  171. 'is_beta' => 0,
  172. 'py_version' => '3.8.6',
  173. 'adviser' => -1,
  174. 'is_rec' => -1,
  175. 'btb' => '',
  176. 'beta' => [
  177. 'py_version' => '3.8.6',
  178. 'version' => $version,
  179. 'downUrl' => $down_url,
  180. 'updateMsg' => config_get('update_msg_win'),
  181. 'uptime' => config_get('update_date_win'),
  182. ]
  183. ];
  184. return json($data);
  185. }
  186. //宝塔云监控获取最新版本
  187. public function btm_latest_version(){
  188. $data = [
  189. 'version' => config_get('new_version_btm'),
  190. 'description' => config_get('update_msg_btm'),
  191. 'create_time' => config_get('update_date_btm')
  192. ];
  193. return json($data);
  194. }
  195. //宝塔云监控更新日志
  196. public function btm_update_history(){
  197. $data = [
  198. [
  199. 'version' => config_get('new_version_btm'),
  200. 'description' => config_get('update_msg_btm'),
  201. 'create_time' => config_get('update_date_btm')
  202. ]
  203. ];
  204. return json($data);
  205. }
  206. //获取内测版更新日志
  207. public function get_beta_logs(){
  208. return json(['beta_ps'=>'当前暂无内测版', 'list'=>[]]);
  209. }
  210. //检查用户绑定是否正确
  211. public function check_auth_key(){
  212. return '1';
  213. }
  214. //从云端验证域名是否可访问
  215. public function check_domain(){
  216. $domain = input('post.domain',null,'trim');
  217. $ssl = input('post.ssl/d');
  218. if(!$domain) return json(['status'=>false, 'msg'=>'域名不能为空']);
  219. if(!strpos($domain,'.')) return json(['status'=>false, 'msg'=>'域名格式不正确']);
  220. $domain = str_replace('*.','',$domain);
  221. $ip = gethostbyname($domain);
  222. if(!$ip || $ip == $domain){
  223. return json(['status'=>false, 'msg'=>'无法访问']);
  224. }else{
  225. return json(['status'=>true, 'msg'=>'访问正常']);
  226. }
  227. }
  228. //同步时间
  229. public function get_time(){
  230. return time();
  231. }
  232. //同步时间
  233. public function get_win_date(){
  234. return date("Y-m-d H:i:s");
  235. }
  236. //查询是否专业版(废弃)
  237. public function is_pro(){
  238. return json(['endtime'=>true, 'code'=>1]);
  239. }
  240. //获取产品推荐信息
  241. public function get_plugin_remarks(){
  242. return json(['list'=>[], 'pro_list'=>[], 'kfqq'=>'', 'kf'=>'', 'qun'=>'']);
  243. }
  244. //获取指定插件评分
  245. public function get_plugin_socre(){
  246. return json(['total'=>0, 'split'=>[0,0,0,0,0],'page'=>"<div><span class='Pcurrent'>1</span><span class='Pcount'>共计0条数据</span></div>",'data'=>[]]);
  247. }
  248. //提交插件评分
  249. public function plugin_score(){
  250. return json(['status'=>true, 'msg'=>'您的评分已成功提交,感谢您的支持!']);
  251. }
  252. //获取IP地址
  253. public function get_ip_address(){
  254. return $this->clientip;
  255. }
  256. //绑定账号
  257. public function get_auth_token(){
  258. if(!$_POST['data']) return json(['status'=>false, 'msg'=>'参数不能为空']);
  259. $reqData = hex2bin($_POST['data']);
  260. parse_str($reqData, $arr);
  261. $serverid = $arr['serverid'];
  262. $userinfo = ['uid'=>1, 'username'=>'Administrator', 'address'=>'127.0.0.1', 'serverid'=>$serverid, 'access_key'=>random(32), 'secret_key'=>random(48), 'ukey'=>md5(time()), 'state'=>1];
  263. $data = bin2hex(urlencode(json_encode($userinfo)));
  264. return json(['status'=>true, 'msg'=>'登录成功!', 'data'=>$data]);
  265. }
  266. //绑定账号新
  267. public function authorization_login(){
  268. if(!$_POST['data']) return json(['status'=>false, 'msg'=>'参数不能为空']);
  269. $reqData = hex2bin($_POST['data']);
  270. parse_str($reqData, $arr);
  271. $serverid = $arr['serverid'];
  272. $userinfo = ['uid'=>1, 'username'=>'Administrator', 'ip'=>'127.0.0.1', 'server_id'=>$serverid, 'access_key'=>random(32), 'secret_key'=>random(48)];
  273. $data = bin2hex(urlencode(json_encode($userinfo)));
  274. return json(['status'=>true, 'msg'=>'登录成功!', 'data'=>$data]);
  275. }
  276. //刷新授权信息
  277. public function authorization_info(){
  278. if(!$_POST['data']) return json(['status'=>false, 'msg'=>'参数不能为空']);
  279. $reqData = hex2bin($_POST['data']);
  280. parse_str($reqData, $arr);
  281. $id = isset($arr['id'])&&$arr['id']>0?$arr['id']:1;
  282. $userinfo = ['id'=>$id, 'product'=>$arr['product'], 'status'=>2, 'clients'=>9999, 'durations'=>0, 'end_time'=>strtotime('+10 year')];
  283. $data = bin2hex(urlencode(json_encode($userinfo)));
  284. return json(['status'=>true, 'data'=>$data]);
  285. }
  286. //一键部署列表
  287. public function get_deplist(){
  288. $os = input('post.os');
  289. $json_arr = Plugins::get_deplist($os);
  290. if(!$json_arr) return json([]);
  291. return json($json_arr);
  292. }
  293. //获取宝塔SSL列表
  294. public function get_ssl_list(){
  295. $data = bin2hex('[]');
  296. return json(['status'=>true, 'msg'=>'', 'data'=>$data]);
  297. }
  298. public function return_success(){
  299. return json(['status'=>true, 'msg'=>1, 'data'=>(object)[]]);
  300. }
  301. public function return_error(){
  302. return json(['status'=>false, 'msg'=>'不支持当前操作']);
  303. }
  304. public function return_error2(){
  305. return json(['success'=>false, 'res'=>'不支持当前操作']);
  306. }
  307. public function return_empty(){
  308. return '';
  309. }
  310. public function return_empty_array(){
  311. return json([]);
  312. }
  313. public function return_page_data(){
  314. return json(['page'=>"<div><span class='Pcurrent'>1</span><span class='Pnumber'>1/0</span><span class='Pline'>从1-1000条</span><span class='Pcount'>共计0条数据</span></div>", 'data'=>[]]);
  315. }
  316. public function btwaf_getspiders(){
  317. $result = cache('btwaf_getspiders');
  318. if($result){
  319. return json($result);
  320. }
  321. $bt_url = config_get('bt_url');
  322. $bt_key = config_get('bt_key');
  323. if(!$bt_url || !$bt_key) return json([]);
  324. $btapi = new \app\lib\Btapi($bt_url, $bt_key);
  325. $result = $btapi->btwaf_getspiders();
  326. if(isset($result['status']) && $result['status']){
  327. cache('btwaf_getspiders', $result['data'], 3600 * 24 * 3);
  328. return json($result['data']);
  329. }
  330. return json($result);
  331. }
  332. //检查黑白名单
  333. private function checklist(){
  334. if(config_get('whitelist') == 1){
  335. if(Db::name('white')->where('ip', $this->clientip)->where('enable', 1)->find()){
  336. return true;
  337. }
  338. return false;
  339. }else{
  340. if(Db::name('black')->where('ip', $this->clientip)->where('enable', 1)->find()){
  341. return false;
  342. }
  343. return true;
  344. }
  345. }
  346. //下载大文件
  347. private function output_file($filepath, $filename){
  348. $filesize = filesize($filepath);
  349. $filemd5 = md5_file($filepath);
  350. ob_clean();
  351. header("Content-Type: application/octet-stream");
  352. header("Content-Disposition: attachment; filename={$filename}.zip");
  353. header("Content-Length: {$filesize}");
  354. header("File-size: {$filesize}");
  355. header("Content-md5: {$filemd5}");
  356. $read_buffer = 1024 * 100;
  357. $handle = fopen($filepath, 'rb');
  358. $sum_buffer = 0;
  359. while(!feof($handle) && $sum_buffer<$filesize) {
  360. echo fread($handle, min($read_buffer, ($filesize - $sum_buffer) + 1));
  361. $sum_buffer += $read_buffer;
  362. flush();
  363. }
  364. fclose($handle);
  365. exit;
  366. }
  367. }