PageRenderTime 45ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/html/include/functions/User.php

https://github.com/Xedecimal/Pass-Store
PHP | 216 lines | 107 code | 23 blank | 86 comment | 8 complexity | 6e669eb2bd55aa43280a8d0b918f7386 MD5 | raw file
  1. <?php
  2. /**
  3. * Functions and object for the "User"
  4. */
  5. /**
  6. * Generate a "hash" for the username and a password
  7. *
  8. * @param string $Username The username to generate the hash with
  9. * @param string $Password The password to generate the hash with
  10. *
  11. * @return string The resulting hash
  12. */
  13. function user_hash($Username, $Password) {
  14. return crypt(user_key($Username, $Password), '$6$rounds=50000$' . substr(hash('sha512', uniqid()), 0, 16));
  15. }
  16. /**
  17. * Generate a user "key"
  18. *
  19. * @param string $Username The username to generate the key with
  20. * @param string $Password The password to generate the key with
  21. *
  22. * @return string The resulting key
  23. */
  24. function user_key($Username, $Password) {
  25. return hash('sha512', $Username . $Password);
  26. }
  27. /**
  28. * Compared a username and password with a hashed password to see if they match
  29. *
  30. * @param string $Username The username to generate the key with
  31. * @param string $Password The password to generate the key with
  32. * @param string $HashedPassword The hashed password to compare against
  33. *
  34. * @return bool Whether they matched or not
  35. */
  36. function user_compare($Username, $Password, $HashedPassword) {
  37. return (crypt(user_key($Username, $Password), $HashedPassword) == $HashedPassword);
  38. }
  39. /**
  40. * Check whether a user with this username exists
  41. *
  42. * @param string $User Username to check
  43. *
  44. * @return bool Whether the user exists or not
  45. */
  46. function user_exists($User) {
  47. $stmt = $GLOBALS['pdo']->prepare('
  48. SELECT count(*)
  49. FROM `users`
  50. WHERE `username` = :username');
  51. $stmt->bindValue(':username', s($User));
  52. $stmt->execute();
  53. return ($stmt->fetchColumn() > 0);
  54. }
  55. /**
  56. * Create a user with the specified username and password
  57. *
  58. * @param string $Username The password to generate the key with
  59. * @param string $Password The username to generate the key with
  60. *
  61. * @return string The ID of the new user
  62. */
  63. function user_create($Username, $Password) {
  64. if (user_exists($Username)) {
  65. return false;
  66. }
  67. $stmt = $GLOBALS['pdo']->prepare('
  68. INSERT INTO `users`
  69. (
  70. `username`
  71. , `password`
  72. ) VALUES (
  73. :username
  74. , :password
  75. )');
  76. $stmt->bindValue(':username', s($Username));
  77. $stmt->bindValue(':password', user_hash($Username, $Password));
  78. $stmt->execute();
  79. $uid = $GLOBALS['pdo']->lastInsertId();
  80. $stmt->closeCursor();
  81. // Create a group for the new user
  82. lib('Group');
  83. $gid = group_create(s($Username), 'user');
  84. group_add($gid, $uid);
  85. return $uid;
  86. }
  87. /**
  88. * Authenticate a user with the given Username and Password
  89. *
  90. * @param string $Username The username
  91. * @param string $Password The password
  92. *
  93. * @return bool Whether the authentication suceeded or not
  94. */
  95. function user_authenticate($Username, $Password) {
  96. $stmt = $GLOBALS['pdo']->prepare('
  97. SELECT `password`
  98. FROM `users`
  99. WHERE `username` = :username
  100. ');
  101. $stmt->bindValue(':username', $Username);
  102. $stmt->execute();
  103. if ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
  104. if (user_compare($Username, $Password, $row['password'])) {
  105. $user = new User($Username, user_key($Username, $Password));
  106. $_SESSION['user'] = &$user;
  107. session_regenerate_id();
  108. return true;
  109. }
  110. }
  111. return false;
  112. }
  113. /**
  114. * Log out the user that's currently logged in
  115. *
  116. * @return void
  117. */
  118. function user_logout() {
  119. unset($_SESSION['user']);
  120. session_regenerate_id();
  121. }
  122. /**
  123. * The User class
  124. */
  125. class User {
  126. public $id;
  127. public $username;
  128. public $group;
  129. private $decryptionKey;
  130. /**
  131. * Construct the user class
  132. *
  133. * @param string $Username The username
  134. * @param string $key The decrpytion key
  135. */
  136. function __construct($Username, $key) {
  137. if (!user_exists($Username)) {
  138. return false;
  139. }
  140. $this->username = $Username;
  141. $this->rehash();
  142. $_SESSION['user'] = &$this;
  143. $this->decryptionKey = $key;
  144. }
  145. /**
  146. * Update the users object with new information from the database
  147. *
  148. * @return void
  149. */
  150. function rehash() {
  151. $stmt = $GLOBALS['pdo']->prepare('
  152. SELECT `id`, `username`
  153. FROM `users`
  154. WHERE
  155. `username` = :username
  156. ');
  157. $stmt->bindParam(':username', $this->username);
  158. $stmt->setFetchMode(PDO::FETCH_INTO, $this);
  159. $stmt->execute();
  160. $stmt->fetch();
  161. }
  162. /**
  163. * Decrypt the given encryped data
  164. *
  165. * @param binary $Encrypted The encrypted data
  166. *
  167. * @return string Decrypted string
  168. */
  169. function decrypt($Encrypted) {
  170. // Check that the private key we're using for decryption exists
  171. if ((is_readable(PATH . '/keys/' . $this->username . '.pem')) && (!empty($this->decryptionKey))) {
  172. $PrivKey = openssl_get_privatekey(file_get_contents(PATH . '/keys/' . $this->username . '.pem'), $this->decryptionKey);
  173. openssl_private_decrypt($Encrypted, $Decrypted, $PrivKey);
  174. return $Decrypted;
  175. }
  176. return false;
  177. }
  178. /**
  179. * Encrypt the given text with this users keys
  180. *
  181. * @param string $PlainText The text to encrypt
  182. *
  183. * @return binary The encrypted data
  184. */
  185. function encrypt($PlainText) {
  186. if (is_readable(PATH . 'keys/' . $this->username . '.pub')) {
  187. openssl_public_encrypt($PlainText, $Encrypted, file_get_contents(PATH . '/keys/' . $this->username . '.pub'));
  188. return $Encrypted;
  189. }
  190. return false;
  191. }
  192. }
  193. ?>