国内流行的内容管理系统(CMS)多端全媒体解决方案 https://www.dedebiz.com
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.

userlogin.class.php 15KB

4 months ago
2 years ago
2 years ago
10 months ago
10 months ago
10 months ago
3 years ago
1 year ago
1 year ago
2 years ago
3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. <?php
  2. if (!defined('DEDEINC')) exit('dedebiz');
  3. /**
  4. * 管理员登录
  5. *
  6. * @version $id:userlogin.class.php 15:59 2010年7月5日 tianya $
  7. * @package DedeBIZ.Libraries
  8. * @copyright Copyright (c) 2022 DedeBIZ.COM
  9. * @license GNU GPL v2 (https://www.dedebiz.com/license)
  10. * @link https://www.dedebiz.com
  11. */
  12. session_start();
  13. /**
  14. * 检验会员是否有权使用某功能,这个函数是一个回值函数CheckPurview函数只是对他回值的一个处理过程
  15. *
  16. * @access public
  17. * @param string $n 功能名称
  18. * @return mixed 如果具有则返回TRUE
  19. */
  20. function TestPurview($n)
  21. {
  22. $rs = FALSE;
  23. $purview = $GLOBALS['cuserLogin']->getPurview();
  24. if (preg_match('/admin_AllowAll/i', $purview)) {
  25. return TRUE;
  26. }
  27. if ($n == '') {
  28. return TRUE;
  29. }
  30. if (!isset($GLOBALS['groupRanks'])) {
  31. $GLOBALS['groupRanks'] = explode(' ', $purview);
  32. }
  33. $ns = explode(',', $n);
  34. foreach ($ns as $n) {
  35. //只要找到一个匹配的权限,即可认为会员有权浏览此页面
  36. if ($n == '') {
  37. continue;
  38. }
  39. if (in_array($n, $GLOBALS['groupRanks'])) {
  40. $rs = TRUE;
  41. break;
  42. }
  43. }
  44. return $rs;
  45. }
  46. /**
  47. * 对权限检测后返回操作对话框
  48. *
  49. * @access public
  50. * @param string $n 功能名称
  51. * @return void
  52. */
  53. function CheckPurview($n)
  54. {
  55. if (!TestPurview($n)) {
  56. ShowMsg("您没有权限进行此操作", "-1");
  57. exit();
  58. }
  59. }
  60. /**
  61. * 是否没权限限制,超级管理员
  62. *
  63. * @access public
  64. * @param string
  65. * @return bool
  66. */
  67. function TestAdmin()
  68. {
  69. $purview = $GLOBALS['cuserLogin']->getPurview();
  70. if (preg_match('/admin_AllowAll/i', $purview)) {
  71. return TRUE;
  72. } else {
  73. return FALSE;
  74. }
  75. }
  76. $DedeUserCatalogs = array();
  77. /**
  78. * 检测会员是否有权限操作某栏目
  79. *
  80. * @access public
  81. * @param int $cid 栏目id
  82. * @param string $msg 返回消息
  83. * @return string
  84. */
  85. function CheckCatalog($cid, $msg)
  86. {
  87. global $cfg_admin_channel, $admin_catalogs;
  88. if ($cfg_admin_channel == 'all' || TestAdmin()) {
  89. return TRUE;
  90. }
  91. if (!in_array($cid, $admin_catalogs)) {
  92. ShowMsg("$msg", "-1");
  93. exit();
  94. }
  95. return TRUE;
  96. }
  97. /**
  98. * 发布文档临时附件信息缓存,前先清空附件信息,完成后把它与文档关连
  99. *
  100. * @access public
  101. * @param string $fid 文件id
  102. * @param string $filename 文件名称
  103. * @return void
  104. */
  105. function AddMyAddon($fid, $filename)
  106. {
  107. $cacheFile = DEDEDATA.'/cache/addon-'.session_id().'.inc';
  108. if (!file_exists($cacheFile)) {
  109. $fp = fopen($cacheFile, 'w');
  110. fwrite($fp, '<'.'?php'."\r\n");
  111. fwrite($fp, "\$myaddons = array();\r\n");
  112. fwrite($fp, "\$maNum = 0;\r\n");
  113. fclose($fp);
  114. }
  115. include($cacheFile);
  116. $fp = fopen($cacheFile, 'a');
  117. $arrPos = $maNum;
  118. $maNum++;
  119. fwrite($fp, "\$myaddons[\$maNum] = array('$fid', '$filename');\r\n");
  120. fwrite($fp, "\$maNum = $maNum;\r\n");
  121. fclose($fp);
  122. }
  123. /**
  124. * 清理附件,如果关连的文档id,先把上一批附件传给这个文档id
  125. *
  126. * @access public
  127. * @param string $aid 文档id
  128. * @param string $title 文档标题
  129. * @return void
  130. */
  131. function ClearMyAddon($aid = 0, $title = '')
  132. {
  133. global $dsql;
  134. $cacheFile = DEDEDATA.'/cache/addon-'.session_id().'.inc';
  135. $_SESSION['bigfile_info'] = array();
  136. $_SESSION['file_info'] = array();
  137. if (!file_exists($cacheFile)) {
  138. return;
  139. }
  140. //把附件与文档关连
  141. if (!empty($aid)) {
  142. include($cacheFile);
  143. foreach ($myaddons as $addons) {
  144. if (!empty($title)) {
  145. $dsql->ExecuteNoneQuery("Update `#@__uploads` set arcid='$aid',title='$title' where aid='{$addons[0]}'");
  146. } else {
  147. $dsql->ExecuteNoneQuery("Update `#@__uploads` set arcid='$aid' where aid='{$addons[0]}' ");
  148. }
  149. }
  150. }
  151. @unlink($cacheFile);
  152. }
  153. /**
  154. * 登录类
  155. *
  156. * @package userLogin
  157. * @subpackage DedeBIZ.Libraries
  158. * @link https://www.dedebiz.com
  159. */
  160. class userLogin
  161. {
  162. var $userName = '';
  163. var $userPwd = '';
  164. var $userID = '';
  165. var $adminDir = '';
  166. var $userType = '';
  167. var $userChannel = '';
  168. var $userPurview = '';
  169. var $userFace = '';
  170. var $keepUserIDTag = 'dede_admin_id';
  171. var $keepUserTypeTag = 'dede_admin_type';
  172. var $keepUserChannelTag = 'dede_admin_channel';
  173. var $keepUserNameTag = 'dede_admin_name';
  174. var $keepUserPurviewTag = 'dede_admin_purview';
  175. var $keepAdminStyleTag = 'dede_admin_style';
  176. var $keepUserFace = 'dede_admin_face';
  177. var $adminStyle = 'DedeBIZ';
  178. //php5构造函数
  179. function __construct($admindir = '')
  180. {
  181. global $admin_path;
  182. if (isset($_SESSION[$this->keepUserIDTag])) {
  183. $this->userID = $_SESSION[$this->keepUserIDTag];
  184. $this->userType = $_SESSION[$this->keepUserTypeTag];
  185. $this->userChannel = $_SESSION[$this->keepUserChannelTag];
  186. $this->userName = $_SESSION[$this->keepUserNameTag];
  187. $this->userPurview = $_SESSION[$this->keepUserPurviewTag];
  188. $this->adminStyle = $_SESSION[$this->keepAdminStyleTag];
  189. $this->userFace = $_SESSION[$this->keepUserFace];
  190. }
  191. if ($admindir != '') {
  192. $this->adminDir = $admindir;
  193. } else {
  194. $this->adminDir = $admin_path;
  195. }
  196. }
  197. function userLogin($admindir = '')
  198. {
  199. $this->__construct($admindir);
  200. }
  201. /**
  202. * 检验会员是否正确
  203. *
  204. * @access public
  205. * @param string $username 账号
  206. * @param string $userpwd 密码
  207. * @return string
  208. */
  209. function checkUser($username, $userpwd)
  210. {
  211. global $dsql;
  212. //只允许账号和密码用0-9,a-z,A-Z,'@','_','.','-'这些字符
  213. $this->userName = preg_replace("/[^0-9a-zA-Z_@!\.-]/", '', $username);
  214. $this->userPwd = preg_replace("/[^0-9a-zA-Z_@!\.-]/", '', $userpwd);
  215. $pwd = substr(md5($this->userPwd), 5, 20);
  216. $dsql->SetQuery("SELECT admin.*,atype.purviews,member.face FROM `#@__admin` admin LEFT JOIN `#@__admintype` atype ON atype.`rank`=admin.usertype LEFT JOIN `#@__member` member ON member.mid = admin.id WHERE admin.userid LIKE '".$this->userName."' LIMIT 0,1");
  217. $dsql->Execute();
  218. $row = $dsql->GetObject();
  219. if (!isset($row->pwd)) {
  220. return -1;
  221. } else if (!empty($row->pwd_new) && !password_verify($this->userPwd, $row->pwd_new)) {
  222. $this->loginError($row->id);
  223. return -2;
  224. } else if (!empty($row->pwd) && $pwd != $row->pwd) {
  225. $this->loginError($row->id);
  226. return -2;
  227. } else {
  228. $upsql = '';
  229. if (empty($row->pwd_new) && function_exists('password_hash')) {
  230. //升级密码
  231. $newpwd = password_hash($this->userPwd, PASSWORD_BCRYPT);
  232. $upsql .= ",pwd='',pwd_new='{$newpwd}'";
  233. }
  234. $loginip = GetIP();
  235. $this->userID = $row->id;
  236. $this->userType = $row->usertype;
  237. $this->userChannel = $row->typeid;
  238. $this->userName = $row->uname;
  239. $this->userPurview = $row->purviews;
  240. $this->userFace = $row->face;
  241. $inquery = "UPDATE `#@__admin` SET loginip='$loginip',logintime='".time()."'{$upsql},loginerr=0 WHERE id='".$row->id."'";
  242. $dsql->ExecuteNoneQuery($inquery);
  243. $sql = "UPDATE `#@__member` SET logintime=".time().", loginip='$loginip' WHERE mid=".$row->id;
  244. $dsql->ExecuteNoneQuery($sql);
  245. return 1;
  246. }
  247. }
  248. /**
  249. * 是否需要验证码
  250. *
  251. * @param mixed $username
  252. * @return bool
  253. */
  254. function isNeedCheckCode($username)
  255. {
  256. $num = $this->getLoginError($username);
  257. return $num >= 3 ? true : false;
  258. }
  259. /**
  260. * 1分钟以内登录错误的次数
  261. *
  262. * @param mixed $username
  263. * @return int 登录错误次数
  264. */
  265. function getLoginError($username)
  266. {
  267. global $dsql;
  268. if (!TableHasField("#@__admin", "loginerr")) {
  269. return 0;
  270. }
  271. $this->userName = preg_replace("/[^0-9a-zA-Z_@!\.-]/", '', $username);
  272. $row = $dsql->GetOne("SELECT loginerr,logintime FROM `#@__admin` WHERE userid LIKE '$this->userName'");
  273. if (is_array($row)) {
  274. //1分钟内如果输错3次则需要验证码
  275. return (time() - (int)$row['logintime']) < 60 ? (int)$row['loginerr'] : 0;
  276. } else {
  277. return -1;
  278. }
  279. }
  280. /**
  281. * 记录登录错误
  282. *
  283. * @return void
  284. */
  285. function loginError($adminid)
  286. {
  287. global $dsql;
  288. $loginip = GetIP();
  289. $inquery = "UPDATE `#@__admin` SET loginip='$loginip',logintime='".time()."',loginerr=loginerr+1 WHERE id='".$adminid."'";
  290. $dsql->ExecuteNoneQuery($inquery);
  291. }
  292. /**
  293. * 保持会员的会话状态
  294. *
  295. * @access public
  296. * @return int 成功返回 1,失败返回 -1
  297. */
  298. function keepUser()
  299. {
  300. if ($this->userID != '' && $this->userType != '') {
  301. global $admincachefile, $adminstyle;
  302. if (empty($adminstyle)) $adminstyle = 'DedeBIZ';
  303. @session_register($this->keepUserIDTag);
  304. $_SESSION[$this->keepUserIDTag] = $this->userID;
  305. @session_register($this->keepUserTypeTag);
  306. $_SESSION[$this->keepUserTypeTag] = $this->userType;
  307. @session_register($this->keepUserChannelTag);
  308. $_SESSION[$this->keepUserChannelTag] = $this->userChannel;
  309. @session_register($this->keepUserNameTag);
  310. $_SESSION[$this->keepUserNameTag] = $this->userName;
  311. @session_register($this->keepUserPurviewTag);
  312. $_SESSION[$this->keepUserPurviewTag] = $this->userPurview;
  313. @session_register($this->keepAdminStyleTag);
  314. $_SESSION[$this->keepAdminStyleTag] = $adminstyle;
  315. @session_register($this->keepUserFace);
  316. $_SESSION[$this->keepUserFace] = $this->userFace;
  317. PutCookie('DedeUserID', $this->userID, 3600 * 24, '/');
  318. PutCookie('DedeLoginTime', time(), 3600 * 24, '/');
  319. $this->ReWriteAdminChannel();
  320. return 1;
  321. } else {
  322. return -1;
  323. }
  324. }
  325. /**
  326. * 重写会员权限栏目
  327. *
  328. * @access public
  329. * @return void
  330. */
  331. function ReWriteAdminChannel()
  332. {
  333. //$this->userChannel
  334. $cacheFile = DEDEDATA.'/cache/admincat_'.$this->userID.'.inc';
  335. //管理员管理的栏目列表
  336. $typeid = trim($this->userChannel);
  337. if (empty($typeid) || $this->getUserType() >= 10) {
  338. $firstConfig = "\$cfg_admin_channel = 'all';\r\n\$admin_catalogs = array();\r\n";
  339. } else {
  340. $firstConfig = "\$cfg_admin_channel = 'array';\r\n";
  341. }
  342. $fp = fopen($cacheFile, 'w');
  343. fwrite($fp, '<'.'?php'."\r\n");
  344. fwrite($fp, $firstConfig);
  345. if (!empty($typeid)) {
  346. $typeids = explode(',', $typeid);
  347. $typeid = '';
  348. foreach ($typeids as $tid) {
  349. $typeid .= ($typeid == '' ? GetSonIdsUL($tid) : ','.GetSonIdsUL($tid));
  350. }
  351. $typeids = explode(',', $typeid);
  352. $typeidsnew = array_unique($typeids);
  353. $typeid = join(',', $typeidsnew);
  354. fwrite($fp, "\$admin_catalogs = array($typeid);\r\n");
  355. }
  356. fwrite($fp, '?'.'>');
  357. fclose($fp);
  358. }
  359. /**
  360. * 结束会员的会话状态
  361. *
  362. * @access public
  363. * @return void
  364. */
  365. function exitUser()
  366. {
  367. ClearMyAddon();
  368. @session_unregister($this->keepUserIDTag);
  369. @session_unregister($this->keepUserTypeTag);
  370. @session_unregister($this->keepUserChannelTag);
  371. @session_unregister($this->keepUserNameTag);
  372. @session_unregister($this->keepUserPurviewTag);
  373. @session_unregister($this->keepUserFace);
  374. DropCookie('dedeAdmindir');
  375. DropCookie('DedeUserID');
  376. DropCookie('DedeLoginTime');
  377. $_SESSION = array();
  378. }
  379. /**
  380. * 获得会员管理栏目的值
  381. *
  382. * @access public
  383. * @return string
  384. */
  385. function getUserChannel()
  386. {
  387. if ($this->userChannel != '') {
  388. return $this->userChannel;
  389. } else {
  390. return '';
  391. }
  392. }
  393. /**
  394. * 获得会员的权限值
  395. *
  396. * @access public
  397. * @return int
  398. */
  399. function getUserType()
  400. {
  401. if ($this->userType != '') {
  402. return $this->userType;
  403. } else {
  404. return -1;
  405. }
  406. }
  407. function getUserFace()
  408. {
  409. if ($this->userFace != '') {
  410. return $this->userFace;
  411. } else {
  412. return '/static/web/img/admin.png';
  413. }
  414. }
  415. /**
  416. * 获取会员权限值
  417. *
  418. * @access public
  419. * @return int
  420. */
  421. function getUserRank()
  422. {
  423. return $this->getUserType();
  424. }
  425. /**
  426. * 获得会员的id
  427. *
  428. * @access public
  429. * @return int
  430. */
  431. function getUserID()
  432. {
  433. if ($this->userID != '') {
  434. return $this->userID;
  435. } else {
  436. return -1;
  437. }
  438. }
  439. /**
  440. * 获得会员的名称
  441. *
  442. * @access public
  443. * @return string
  444. */
  445. function getUserName()
  446. {
  447. if ($this->userName != '') {
  448. return $this->userName;
  449. } else {
  450. return -1;
  451. }
  452. }
  453. /**
  454. * 会员权限表
  455. *
  456. * @access public
  457. * @return string
  458. */
  459. function getPurview()
  460. {
  461. return $this->userPurview;
  462. }
  463. }
  464. /**
  465. * 获得某id的所有下级id
  466. *
  467. * @access public
  468. * @param int $id 栏目id
  469. * @param int $channel 栏目id
  470. * @param int $addthis 是否加入当前这个栏目
  471. * @return string
  472. */
  473. function GetSonIdsUL($id, $channel = 0, $addthis = TRUE)
  474. {
  475. global $cfg_Cs;
  476. $GLOBALS['idArray'] = array();
  477. if (!is_array($cfg_Cs)) {
  478. require_once(DEDEDATA."/cache/inc_catalog_base.inc");
  479. }
  480. GetSonIdsLogicUL($id, $cfg_Cs, $channel, $addthis);
  481. $rquery = join(',', $GLOBALS['idArray']);
  482. return $rquery;
  483. }
  484. /**
  485. * 递归逻辑
  486. *
  487. * @access public
  488. * @param int $id 栏目id
  489. * @param array $sArr 缓存数组
  490. * @param int $channel 栏目id
  491. * @param int $addthis 是否加入当前这个栏目
  492. * @return void
  493. */
  494. function GetSonIdsLogicUL($id, $sArr, $channel = 0, $addthis = FALSE)
  495. {
  496. if ($id != 0 && $addthis) {
  497. $GLOBALS['idArray'][$id] = $id;
  498. }
  499. foreach ($sArr as $k => $v) {
  500. if ($v[0] == $id && ($channel == 0 || $v[1] == $channel)) {
  501. GetSonIdsLogicUL($k, $sArr, $channel, TRUE);
  502. }
  503. }
  504. }
  505. ?>