PageRenderTime 27ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/nova/modules/core/libraries/Nova_auth.php

https://github.com/anodyne/nova
PHP | 587 lines | 363 code | 124 blank | 100 comment | 42 complexity | 32e6fa7f380205ee5628dc179544659b MD5 | raw file
  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3. * Authentication library
  4. *
  5. * @package Nova
  6. * @category Library
  7. * @author Anodyne Productions
  8. * @copyright 2013 Anodyne Productions
  9. */
  10. abstract class Nova_auth {
  11. /**
  12. * The number of allowed log in attempts before lockout
  13. */
  14. public static $allowed_login_attempts = 5;
  15. /**
  16. * The standard lockout time in seconds
  17. */
  18. public static $lockout_time = 1800;
  19. public function __construct()
  20. {
  21. log_message('debug', 'Auth Library Initialized');
  22. }
  23. public static function can($uri = null, $redirect = true, $partial = false)
  24. {
  25. if ( ! static::is_logged_in()) return false;
  26. return static::check_access($uri, $redirect, $partial);
  27. }
  28. public static function cannot($uri = null, $redirect = true, $partial = false)
  29. {
  30. if ( ! static::is_logged_in()) return true;
  31. return ! static::check_access($uri, $redirect, $partial);
  32. }
  33. public static function check_access($uri = null, $redirect = true, $partial = false)
  34. {
  35. // get an instance of CI
  36. $ci =& get_instance();
  37. // set the URI
  38. if (empty($uri))
  39. {
  40. $uri = $ci->uri->segment(1) .'/'. $ci->uri->segment(2);
  41. }
  42. if ($partial)
  43. {
  44. $array = explode('/', $uri);
  45. $uri = $array[0];
  46. }
  47. if ( ! $partial)
  48. {
  49. $access = $ci->session->userdata('access');
  50. $access = ( ! $access) ? array() : $access;
  51. if ( ! array_key_exists($uri, $access))
  52. {
  53. if ($redirect)
  54. {
  55. $ci->session->set_flashdata('referer', $uri);
  56. redirect('admin/error/1');
  57. }
  58. return false;
  59. }
  60. }
  61. else
  62. {
  63. foreach ($ci->session->userdata('access') as $a => $b)
  64. {
  65. if (strpos($a, $uri) !== false)
  66. {
  67. return true;
  68. }
  69. return false;
  70. }
  71. }
  72. return true;
  73. }
  74. /**
  75. * Get a user's access level for the URI passed to the method.
  76. *
  77. * @access public
  78. * @param string the URI
  79. * @return mixed the access level or FALSE if there is no level
  80. */
  81. public static function get_access_level($uri = '')
  82. {
  83. // get an instance of CI
  84. $ci =& get_instance();
  85. // make sure we have a URI to work with
  86. $uri = (empty($uri)) ? $ci->uri->segment(1).'/'.$ci->uri->segment(2) : $uri;
  87. // obviously you need to be logged in to have an access level
  88. if (self::is_logged_in())
  89. {
  90. // grab the access stuff from the session
  91. $session = $ci->session->userdata('access');
  92. // split out the segments
  93. $segments = (is_array($uri)) ? $uri[1] .'/'. $uri[2] : $uri;
  94. // find the URI in the access array if it's there
  95. if (is_array($session) and array_key_exists($segments, $session))
  96. {
  97. return $session[$segments];
  98. }
  99. }
  100. return false;
  101. }
  102. public static function hash($string = '')
  103. {
  104. // get an instance of CI
  105. $ci =& get_instance();
  106. // load the resources
  107. $ci->load->model('system_model', 'sys');
  108. // grab the Nova UID
  109. $uid = $ci->sys->get_nova_uid();
  110. // double hash the UID
  111. $uid = sha1(sha1($uid));
  112. // hash the string with the salt
  113. $string = sha1($uid . $string);
  114. return $string;
  115. }
  116. public static function is_gamemaster($user = '')
  117. {
  118. // get an instance of CI
  119. $ci =& get_instance();
  120. // load the resources
  121. $ci->load->model('users_model', 'user');
  122. $gm = $ci->user->get_user($user, 'is_game_master');
  123. $retval = ($gm == 'y');
  124. return $retval;
  125. }
  126. public static function is_logged_in($redirect = false)
  127. {
  128. // get an instance of CI
  129. $ci =& get_instance();
  130. if ( ! $ci->session->userdata('userid'))
  131. {
  132. $auto = self::_autologin();
  133. if ($auto)
  134. {
  135. return true;
  136. }
  137. if ($redirect)
  138. {
  139. redirect('login/index/error/1');
  140. }
  141. return false;
  142. }
  143. return true;
  144. }
  145. public static function is_sysadmin($user = '')
  146. {
  147. // get an instance of CI
  148. $ci =& get_instance();
  149. // load the resources
  150. $ci->load->model('users_model', 'user');
  151. $admin = $ci->user->get_user($user, 'is_sysadmin');
  152. $retval = ($admin == 'y');
  153. return $retval;
  154. }
  155. public static function is_webmaster($user = '')
  156. {
  157. // get an instance of CI
  158. $ci =& get_instance();
  159. // load the resources
  160. $ci->load->model('users_model', 'user');
  161. $web = $ci->user->get_user($user, 'is_webmaster');
  162. $retval = ($web == 'y');
  163. return $retval;
  164. }
  165. public static function login($email = '', $password = '', $remember = '', $autologin_attempt = false)
  166. {
  167. // get an instance of CI
  168. $ci =& get_instance();
  169. // load the resources
  170. $ci->load->model('users_model', 'user');
  171. $ci->load->model('system_model', 'sys');
  172. $ci->load->model('settings_model', 'settings');
  173. // xss clean of the data coming in
  174. $email = $ci->security->xss_clean($email);
  175. $password = $ci->security->xss_clean($password);
  176. $remember = $ci->security->xss_clean($remember);
  177. // set the variables
  178. $retval = 0;
  179. $maintenance = $ci->settings->get_setting('maintenance');
  180. if ($email == '')
  181. {
  182. $retval = 2;
  183. return $retval;
  184. }
  185. if ($password == '')
  186. {
  187. $retval = 3;
  188. return $retval;
  189. }
  190. $attempts = self::_check_login_attempts($email);
  191. if ( ! $attempts)
  192. {
  193. $retval = 6;
  194. return $retval;
  195. }
  196. // check to see if the account exists
  197. $login = $ci->user->get_user_details_by_email($email);
  198. if ($login->num_rows() == 0)
  199. {
  200. // email doesn't exist
  201. $retval = 2;
  202. }
  203. elseif ($login->num_rows() > 1)
  204. {
  205. // more than one account found - contact the GM
  206. $retval = 4;
  207. }
  208. else
  209. {
  210. // assign the object to a variable
  211. $person = $login->row();
  212. if ($person->password == $password)
  213. {
  214. if ($maintenance == 'on' and $person->is_sysadmin == 'n')
  215. {
  216. // maintenance mode active
  217. $retval = 5;
  218. }
  219. elseif ($person->status == 'pending')
  220. {
  221. // they haven't been approved yet
  222. $retval = 7;
  223. }
  224. else
  225. {
  226. // clear the login attempts if there are any
  227. $ci->sys->delete_login_attempts($email);
  228. // update the login record
  229. $ci->user->update_login_record($person->userid, now());
  230. // set the session
  231. self::_set_session($person);
  232. }
  233. }
  234. else
  235. {
  236. // password is wrong
  237. $retval = 3;
  238. if ( ! $autologin_attempt)
  239. {
  240. // create the attempt array
  241. $login_attempt = array(
  242. 'login_ip' => $ci->input->ip_address(),
  243. 'login_email' => $email,
  244. 'login_time' => now()
  245. );
  246. // add a record to login attempt table
  247. $ci->sys->add_login_attempt($login_attempt);
  248. }
  249. }
  250. }
  251. if ($remember == 'yes')
  252. {
  253. // set the cookie
  254. self::_set_cookie($email, $password);
  255. }
  256. return $retval;
  257. }
  258. public static function logout()
  259. {
  260. // get an instance of CI
  261. $ci =& get_instance();
  262. // destroy the cookie
  263. self::_destroy_cookie();
  264. // destroy the session
  265. $ci->session->sess_destroy();
  266. }
  267. public static function set($param = '', $value = '')
  268. {
  269. self::$param = $value;
  270. }
  271. public static function verify($email = '', $password = '')
  272. {
  273. // get an instance of CI
  274. $ci =& get_instance();
  275. // load the resources
  276. $ci->load->model('users_model', 'user');
  277. // hash the password
  278. $password = self::hash($password);
  279. $retval = 0;
  280. $login = $ci->user->get_user_details_by_email($email);
  281. if ($login->num_rows() == 0)
  282. {
  283. // email doesn't exist
  284. $retval = 2;
  285. }
  286. elseif ($login->num_rows() > 1)
  287. {
  288. // more than one account found - contact the GM
  289. $retval = 4;
  290. }
  291. else
  292. {
  293. // assign the object to a variable
  294. $person = $login->row();
  295. if ($person->password == $password)
  296. {
  297. $retval = 0;
  298. }
  299. else
  300. {
  301. // password is wrong
  302. $retval = 3;
  303. }
  304. }
  305. return $retval;
  306. }
  307. protected static function _check_login_attempts($email = '')
  308. {
  309. // get an instance of CI
  310. $ci =& get_instance();
  311. // load the resources
  312. $ci->load->model('users_model', 'user');
  313. $ci->load->model('system_model', 'sys');
  314. $attempts = $ci->sys->count_login_attempts($email);
  315. if ($attempts < self::$allowed_login_attempts)
  316. {
  317. return true;
  318. }
  319. else
  320. {
  321. $item = $ci->sys->get_last_login_attempt($email);
  322. $timeframe = now() - $item->login_time;
  323. if ($timeframe > self::$lockout_time)
  324. {
  325. // clear the login attempts if there are any
  326. $ci->sys->delete_login_attempts($email);
  327. return true;
  328. }
  329. return false;
  330. }
  331. }
  332. protected static function _autologin()
  333. {
  334. // get an instance of CI
  335. $ci =& get_instance();
  336. // load the resources
  337. $ci->load->model('system_model', 'sys');
  338. // load the CI resources
  339. $ci->load->helper('cookie');
  340. // grab nova's unique identifier
  341. $uid = $ci->sys->get_nova_uid();
  342. // get the cookie
  343. $cookie = get_cookie('nova_'. $uid, true);
  344. if ($cookie !== false and is_array($cookie))
  345. {
  346. $login = self::login($cookie['email'], $cookie['password'], null, true);
  347. return $login;
  348. }
  349. return false;
  350. }
  351. protected static function _destroy_cookie()
  352. {
  353. // get an instance of CI
  354. $ci =& get_instance();
  355. // load the resources
  356. $ci->load->model('system_model', 'sys');
  357. // load the CI resources
  358. $ci->load->helper('cookie');
  359. // grab nova's unique identifier
  360. $uid = $ci->sys->get_nova_uid();
  361. // set the cookie data
  362. $c_data = array(
  363. 'email' => array(
  364. 'name' => $uid .'[email]',
  365. 'value' => '',
  366. 'expire' => '0',
  367. 'prefix' => 'nova_'),
  368. 'password' => array(
  369. 'name' => $uid .'[password]',
  370. 'value' => '',
  371. 'expire' => '0',
  372. 'prefix' => 'nova_')
  373. );
  374. // destroy the cookie
  375. delete_cookie($c_data['email']);
  376. delete_cookie($c_data['password']);
  377. }
  378. protected static function _set_access($role = '')
  379. {
  380. // get an instance of CI
  381. $ci =& get_instance();
  382. // load the resources
  383. $ci->load->model('access_model', 'access');
  384. // a string of page ids
  385. $page_ids = $ci->access->get_role_data($role);
  386. // get all the page data for those page ids
  387. $pages = $ci->access->get_pages($page_ids);
  388. return $pages;
  389. }
  390. protected static function _set_cookie($email = '', $password = '')
  391. {
  392. // get an instance of CI
  393. $ci =& get_instance();
  394. // load the resources
  395. $ci->load->model('system_model', 'sys');
  396. // load the CI resources
  397. $ci->load->helper('cookie');
  398. // grab nova's unique identifier
  399. $uid = $ci->sys->get_nova_uid();
  400. // set the cookie data
  401. $c_data = array(
  402. 'email' => array(
  403. 'name' => $uid .'[email]',
  404. 'value' => $email,
  405. 'expire' => '1209600',
  406. 'prefix' => 'nova_'),
  407. 'password' => array(
  408. 'name' => $uid .'[password]',
  409. 'value' => $password,
  410. 'expire' => '1209600',
  411. 'prefix' => 'nova_')
  412. );
  413. // set the cookie
  414. set_cookie($c_data['email']);
  415. set_cookie($c_data['password']);
  416. }
  417. protected static function _set_session($person = '')
  418. {
  419. // get an instance of CI
  420. $ci =& get_instance();
  421. // load the resources
  422. $ci->load->model('users_model', 'user');
  423. $ci->load->model('menu_model');
  424. $ci->load->model('characters_model', 'char');
  425. $characters = $ci->char->get_user_characters($person->userid, '', 'array');
  426. // set the data that goes in to the session
  427. $array['userid'] = $person->userid;
  428. $array['skin_main'] = $person->skin_main;
  429. $array['skin_admin'] = $person->skin_admin;
  430. $array['skin_wiki'] = $person->skin_wiki;
  431. $array['display_rank'] = $person->display_rank;
  432. $array['language'] = $person->language;
  433. $array['timezone'] = $person->timezone;
  434. $array['dst'] = $person->daylight_savings;
  435. $array['main_char'] = $person->main_char;
  436. $array['characters'] = $characters;
  437. $array['role'] = $person->access_role;
  438. $array['access'] = self::_set_access($person->access_role);
  439. // put my links into an array
  440. $my_links = explode(',', $person->my_links);
  441. if (count($my_links) > 0)
  442. {
  443. foreach ($my_links as $value)
  444. {
  445. $menus = $ci->menu_model->get_menu_item($value);
  446. if ($menus->num_rows() > 0)
  447. {
  448. $item = $menus->row();
  449. $array['my_links'][] = anchor($item->menu_link, $item->menu_name);
  450. }
  451. }
  452. }
  453. // set first launch in the flashdata
  454. $ci->session->set_flashdata('first_launch', $person->is_firstlaunch);
  455. $ci->session->set_flashdata('password_reset', $person->password_reset);
  456. // set the session data
  457. $ci->session->set_userdata($array);
  458. // load the database utility class
  459. $ci->load->dbutil();
  460. // optimize the sessions table
  461. $ci->dbutil->optimize_table('sessions');
  462. }
  463. }