PageRenderTime 46ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/php/Login.php

https://bitbucket.org/randati/compohub
PHP | 146 lines | 109 code | 36 blank | 1 comment | 20 complexity | b75e826405346b69dafe0129deb31976 MD5 | raw file
  1. <?php
  2. require_once 'Database.php';
  3. class NotLoggedIn extends Exception { }
  4. class Login {
  5. private static $logged = null;
  6. public static $name;
  7. public static $email;
  8. public static $status;
  9. public static $id;
  10. public static function register($user, $email, $pass1, $pass2) {
  11. // Check that everything is okay
  12. if (strlen($user) > 30)
  13. return 'Username is too long!';
  14. if (strlen($user) < 1)
  15. return 'Username is too short!';
  16. if (!self::valid_name($user))
  17. return 'Username contains invalid characters!';
  18. if (DB::user_exists($user))
  19. return 'Username is already in use!';
  20. if (filter_var($email, FILTER_VALIDATE_EMAIL) !== $email)
  21. return 'Invalid email!';
  22. if (strlen($pass1) < 6)
  23. return 'Password is too short! It should be at least 6 characters.';
  24. if ($pass1 !== $pass2)
  25. return 'Passwords didn\'t match!';
  26. $salt = self::create_salt();
  27. $hash = self::create_hash($pass1, $salt);
  28. $succ = DB::add_user($user, $email, $hash);
  29. if (!$succ)
  30. return 'Something went horribly wrong! Try again or contact admin.';
  31. return true;
  32. }
  33. public static function log_in($user, $pass, $persistent) {
  34. if (!self::valid_name($user))
  35. return 'Invalid username!';
  36. $info = DB::get_user_info($user);
  37. if (!$info)
  38. return 'Invalid username!';
  39. if (!self::right_pass($pass, $info['hash']))
  40. return 'Wrong password!';
  41. self::create_cookie($info, $persistent);
  42. self::$logged = true;
  43. self::set_login_info($info);
  44. return true;
  45. }
  46. public static function is_logged_in() {
  47. if (self::$logged === true) return true;
  48. if (self::$logged === false) return false;
  49. if (!isset($_COOKIE['li_name'])) return false;
  50. if (!isset($_COOKIE['li_foo'])) return false;
  51. if (!isset($_COOKIE['li_bar'])) return false;
  52. $info = DB::get_user_info($_COOKIE['li_name']);
  53. if (!$info)
  54. return false;
  55. if ($info['name'] !== $_COOKIE['li_name'])
  56. return false;
  57. $hash = self::create_cookie_hash($info, $_COOKIE['li_bar']);
  58. if ($hash !== $_COOKIE['li_foo'])
  59. return false;
  60. self::set_login_info($info);
  61. return true;
  62. }
  63. public static function log_out() {
  64. setcookie('li_name', '', time() - 3600, '/');
  65. setcookie('li_foo', '', time() - 3600, '/');
  66. setcookie('li_bar', '', time() - 3600, '/');
  67. self::$logged = false;
  68. }
  69. public static function protect() {
  70. if (!Login::is_logged_in()) {
  71. echo 'Not logged in.';
  72. throw new NotLoggedIn();
  73. }
  74. }
  75. private static function set_login_info($info) {
  76. self::$name = $info['name'];
  77. self::$email = $info['email'];
  78. self::$id = $info['id'];
  79. self::$status = $info['status'];
  80. self::$logged = true;
  81. }
  82. private static function create_cookie($info, $persistent) {
  83. $exp = ($persistent ? 2000000000 : 0);
  84. $salt = self::create_cookie_salt();
  85. $hash = self::create_cookie_hash($info, $salt);
  86. setcookie('li_name', $info['name'], $exp, '/');
  87. setcookie('li_foo', $hash, $exp, '/');
  88. setcookie('li_bar', $salt, $exp, '/');
  89. }
  90. private static function create_cookie_hash($info, $salt) {
  91. $data = $info['name'] . $info['id'] . $info['hash'] . $info['status'] .
  92. $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT'] . $salt;
  93. return hash('sha256', $data);
  94. }
  95. private static function create_cookie_salt() {
  96. return hash('sha1', self::create_salt());
  97. }
  98. private static function valid_name($name) {
  99. return (preg_match('/^[a-zA-Z0-9_-]+$/', $name) === 1);
  100. }
  101. private static function create_salt() {
  102. return substr(str_replace('+', '.', base64_encode(sha1(uniqid(microtime(true)), true))), 0, 22);
  103. }
  104. private static function create_hash($pass, $salt) {
  105. return crypt($pass, '$2a$10$' . $salt);
  106. }
  107. private static function right_pass($pass, $hash) {
  108. return (crypt($pass, $hash) === $hash);
  109. }
  110. }