IndexController.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. <?php
  2. /**
  3. * @copyright (C)2016-2099 Hnaoyun Inc.
  4. * @author XingMeng
  5. * @email hnxsh@foxmail.com
  6. * @date 2017年3月13日
  7. * 默认主页
  8. */
  9. namespace app\admin\controller;
  10. use core\basic\Controller;
  11. use app\admin\model\IndexModel;
  12. class IndexController extends Controller
  13. {
  14. private $model;
  15. public function __construct()
  16. {
  17. $this->model = new IndexModel();
  18. }
  19. // 登录页面
  20. public function index()
  21. {
  22. if (session('sid')) {
  23. location(url('admin/Index/home'));
  24. }
  25. $this->assign('admin_check_code', $this->config('admin_check_code'));
  26. $this->display('index.html');
  27. }
  28. // 主页面
  29. public function home()
  30. {
  31. // 手动修改数据名称
  32. if (get('action') == 'moddb') {
  33. if ($this->modDB()) {
  34. alert_back('修改成功!');
  35. } else {
  36. alert_back('修改失败!');
  37. }
  38. }
  39. // 删除修改后老数据库(上一步无法直接修改删除)
  40. if (issetSession('deldb')) {
  41. @unlink(ROOT_PATH . session('deldb'));
  42. unset($_SESSION['deldb']);
  43. }
  44. $dbsecurity = true;
  45. // 如果是sqlite数据库,并且路径为默认的,则标记为不安全
  46. if (get_db_type() == 'sqlite') {
  47. // 数据库配置含有默认名字则进行修改
  48. if (strpos($this->config('database.dbname'), 'pbootcms') !== false) {
  49. if (get_user_ip() != '127.0.0.1' && $this->modDB()) { // 非本地测试时尝试自动修改数据库名称
  50. $dbsecurity = true;
  51. } else {
  52. $dbsecurity = false;
  53. }
  54. } elseif (file_exists(ROOT_PATH . '/data/pbootcms.db')) { // 存在多余的默认数据库文件则改名
  55. rename(ROOT_PATH . '/data/pbootcms.db', ROOT_PATH . '/data/' . get_uniqid() . '.db');
  56. }
  57. } elseif (file_exists(ROOT_PATH . '/data/pbootcms.db')) {
  58. rename(ROOT_PATH . '/data/pbootcms.db', ROOT_PATH . '/data/' . get_uniqid() . '.db');
  59. }
  60. $this->assign('dbsecurity', $dbsecurity);
  61. if (! session('pwsecurity')) {
  62. location(url('/admin/Index/ucenter'));
  63. }
  64. $this->assign('server', get_server_info());
  65. $this->assign('branch', $this->config('upgrade_branch') == '3.X.dev' ? '3.X.dev' : '3.X');
  66. $this->assign('revise', $this->config('revise_version') ?: '0');
  67. $this->assign('snuser', $this->config('sn_user') ?: '0');
  68. $this->assign('site', get_http_url());
  69. $this->assign('user_info', $this->model->getUserInfo(session('ucode')));
  70. $this->assign('sum_msg', model('admin.content.Message')->getCount());
  71. // 内容模型菜单
  72. $model = model('admin.content.Model');
  73. $models = $model->getModelMenu();
  74. foreach ($models as $key => $value) {
  75. $models[$key]->count = $model->getModelCount($value->mcode)->count;
  76. }
  77. $this->assign('model_msg', $models);
  78. $this->display('system/home.html');
  79. }
  80. // 异步登录验证
  81. public function login()
  82. {
  83. if (! $_POST) {
  84. return;
  85. }
  86. // 在安装了gd库时才执行验证码验证
  87. if (extension_loaded("gd") && $this->config('admin_check_code') && strtolower(post('checkcode', 'var')) != session('checkcode')) {
  88. json(0, '验证码错误!');
  89. }
  90. // 就收数据
  91. $username = post('username');
  92. $password = post('password');
  93. if (! preg_match('/^[\x{4e00}-\x{9fa5}\w\-\.@]+$/u', $username)) {
  94. json(0, '用户名含有不允许的特殊字符!');
  95. }
  96. if (! $username) {
  97. json(0, '用户名不能为空!');
  98. }
  99. if (! $password) {
  100. json(0, '密码不能为空!');
  101. }
  102. if (! ! $time = $this->checkLoginBlack()) {
  103. $this->log('登录锁定!');
  104. json(0, '您登录失败次数太多已被锁定,请' . $time . '秒后再试!');
  105. }
  106. // 执行用户登录
  107. $where = array(
  108. 'username' => $username,
  109. 'password' => encrypt_string($password)
  110. );
  111. // 判断数据库写入权限
  112. if ((get_db_type() == 'sqlite') && ! is_writable(ROOT_PATH . $this->config('database.dbname'))) {
  113. json(0, '数据库目录写入权限不足!');
  114. }
  115. if (! ! $login = $this->model->login($where)) {
  116. session_regenerate_id(true);
  117. session('sid', encrypt_string(session_id() . $login->id)); // 会话标识
  118. session('M', M);
  119. session('id', $login->id); // 用户id
  120. session('ucode', $login->ucode); // 用户编码
  121. session('username', $login->username); // 用户名
  122. session('realname', $login->realname); // 真实名字
  123. if ($where['password'] != '14e1b600b1fd579f47433b88e8d85291') {
  124. session('pwsecurity', true);
  125. }
  126. session('acodes', $login->acodes); // 用户管理区域
  127. if ($login->acodes) { // 当前显示区域
  128. session('acode', $login->acodes[0]);
  129. } else {
  130. session('acode', '');
  131. }
  132. session('rcodes', $login->rcodes); // 用户角色代码表
  133. session('levels', $login->levels); // 用户权限URL列表
  134. session('menu_tree', $login->menus); // 菜单树
  135. session('area_map', $login->area_map); // 区域代码名称映射表
  136. session('area_tree', $login->area_tree); // 用户区域树
  137. $this->log('登录成功!');
  138. json(1, url('admin/Index/home'));
  139. } else {
  140. $this->setLoginBlack();
  141. $this->log('登录失败!');
  142. session('checkcode', mt_rand(10000, 99999)); // 登录失败,随机打乱原有验证码
  143. json(0, '用户名或密码错误!');
  144. }
  145. }
  146. // 退出登录
  147. public function loginOut()
  148. {
  149. session_unset();
  150. location(url('/admin/Index/index'));
  151. }
  152. // 用户中心,修改密码
  153. public function ucenter()
  154. {
  155. if ($_POST) {
  156. $username = post('username'); // 用户名
  157. $realname = post('realname'); // 真实姓名
  158. $cpassword = post('cpassword'); // 现在密码
  159. $password = post('password'); // 新密码
  160. $rpassword = post('rpassword'); // 确认密码
  161. if (! $username) {
  162. alert_back('用户名不能为空!');
  163. }
  164. if (! $cpassword) {
  165. alert_back('当前密码不能为空!');
  166. }
  167. if (! preg_match('/^[\x{4e00}-\x{9fa5}\w\-\.@]+$/u', $username)) {
  168. alert_back('用户名含有不允许的特殊字符!');
  169. }
  170. $data = array(
  171. 'username' => $username,
  172. 'realname' => $realname,
  173. 'update_user' => $username
  174. );
  175. // 如果有修改密码,则添加数据
  176. if ($password) {
  177. if ($password != $rpassword) {
  178. alert_back('确认密码不正确!');
  179. }
  180. $data['password'] = encrypt_string($password);
  181. if ($data['password'] != '14e1b600b1fd579f47433b88e8d85291') {
  182. session('pwsecurity', true);
  183. } else {
  184. session('pwsecurity', false);
  185. }
  186. }
  187. // 检查现有密码
  188. if ($this->model->checkUserPwd(encrypt_string($cpassword))) {
  189. if ($this->model->modUserInfo($data)) {
  190. session('username', post('username'));
  191. session('realname', post('realname'));
  192. $this->log('用户资料成功!');
  193. success('用户资料修改成功!', - 1);
  194. }
  195. } else {
  196. $this->log('用户资料修改时当前密码错误!');
  197. alert_location('当前密码错误!', - 1);
  198. }
  199. }
  200. $this->display('system/ucenter.html');
  201. }
  202. // 切换显示的数据区域
  203. public function area()
  204. {
  205. if ($_POST) {
  206. $acode = post('acode');
  207. if (in_array($acode, session('acodes'))) {
  208. session('acode', $acode);
  209. cookie('lg', $acode); // 同步切换前台语言
  210. }
  211. location(url('admin/Index/home'));
  212. }
  213. }
  214. // 清理缓存
  215. public function clearCache()
  216. {
  217. if (get('delall')) {
  218. $rs = path_delete(RUN_PATH);
  219. } else {
  220. $rs = (path_delete(RUN_PATH . '/cache') && path_delete(RUN_PATH . '/complile') && path_delete(RUN_PATH . '/config') && path_delete(RUN_PATH . '/upgrade') && path_delete(RUN_PATH . '/image'));
  221. }
  222. cache_config(); // 清理缓存后立即生成新的配置
  223. if ($rs) {
  224. if (extension_loaded('Zend OPcache')) {
  225. opcache_reset(); // 在启用了OPcache加速器时同时清理
  226. }
  227. $this->log('清理缓存成功!');
  228. alert_back('清理缓存成功!', 1);
  229. } else {
  230. $this->log('清理缓存失败!');
  231. alert_back('清理缓存失败!', 0);
  232. }
  233. }
  234. // 清理会话
  235. public function clearSession()
  236. {
  237. ignore_user_abort(true); // 后台运行
  238. set_time_limit(7200);
  239. ob_start();
  240. $output['code'] = 1;
  241. $output['data'] = '执行成功,后台自动清理中!';
  242. $output['tourl'] = '';
  243. echo json_encode($output);
  244. ob_end_flush();
  245. flush();
  246. $rs = path_delete(RUN_PATH . '/session', false, array(
  247. 'sess_' . session_id()
  248. ));
  249. }
  250. // 文件上传方法
  251. public function upload()
  252. {
  253. $upload = upload('upload');
  254. if (is_array($upload)) {
  255. json(1, $upload);
  256. } else {
  257. json(0, $upload);
  258. }
  259. }
  260. // 检查是否在黑名单
  261. private function checkLoginBlack()
  262. {
  263. // 读取黑名单
  264. $ip_black = RUN_PATH . '/data/' . md5('login_black') . '.php';
  265. if (file_exists($ip_black)) {
  266. $data = require $ip_black;
  267. $user_ip = get_user_ip();
  268. $lock_time = $this->config('lock_time') ?: 900;
  269. $lock_count = $this->config('lock_count') ?: 5;
  270. if (isset($data[$user_ip]) && $data[$user_ip]['count'] >= $lock_count && time() - $data[$user_ip]['time'] < $lock_time) {
  271. return $lock_time - (time() - $data[$user_ip]['time']); // 返回剩余秒数
  272. }
  273. }
  274. return false;
  275. }
  276. // 添加登录黑名单
  277. private function setLoginBlack()
  278. {
  279. // 读取黑名单
  280. $ip_black = RUN_PATH . '/data/' . md5('login_black') . '.php';
  281. if (file_exists($ip_black)) {
  282. $data = require $ip_black;
  283. } else {
  284. $data = array();
  285. }
  286. // 添加IP
  287. $user_ip = get_user_ip();
  288. $lock_time = $this->config('lock_time') ?: 900;
  289. $lock_count = $this->config('lock_count') ?: 5;
  290. if (isset($data[$user_ip]) && $data[$user_ip]['count'] < $lock_count && time() - $data[$user_ip]['time'] < $lock_time) {
  291. $data[$user_ip] = array(
  292. 'time' => time(),
  293. 'count' => $data[get_user_ip()]['count'] + 1
  294. );
  295. } else {
  296. $data[$user_ip] = array(
  297. 'time' => time(),
  298. 'count' => 1
  299. );
  300. }
  301. // 写入黑名单
  302. check_file($ip_black, true);
  303. return file_put_contents($ip_black, "<?php\nreturn " . var_export($data, true) . ";");
  304. }
  305. // 修改数据库名称
  306. private function modDB()
  307. {
  308. $file = CONF_PATH . '/database.php';
  309. $sname = $this->config('database.dbname');
  310. $dname = '/data/' . get_uniqid() . '.db';
  311. $sconfig = file_get_contents($file);
  312. $dconfig = str_replace($sname, $dname, $sconfig);
  313. if (file_put_contents($file, $dconfig)) {
  314. if (! copy(ROOT_PATH . $sname, ROOT_PATH . $dname)) {
  315. file_put_contents($file, $sconfig); // 回滚配置
  316. } else {
  317. session('deldb', $sname);
  318. return true;
  319. }
  320. }
  321. return false;
  322. }
  323. }