Auth.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. <?php
  2. class Auth
  3. {
  4. const SESSION_IDENTIFIER = 'uid';
  5. /**
  6. * @var User|null
  7. */
  8. private static $loggedInUser = null;
  9. /**
  10. * Init Authentication
  11. */
  12. public static function init()
  13. {
  14. static::loginUserViaSession();
  15. }
  16. /**
  17. * Check whether the user is logged in or not.
  18. *
  19. * @return bool
  20. */
  21. public static function isLoggedIn()
  22. {
  23. return !is_null(static::$loggedInUser);
  24. }
  25. /**
  26. * Get the currently logged in user.
  27. *
  28. * @return null|User
  29. */
  30. public static function getUser()
  31. {
  32. return static::$loggedInUser;
  33. }
  34. /**
  35. * @param AbstractModel $user
  36. */
  37. private static function loginUserByModel($user)
  38. {
  39. static::$loggedInUser = $user;
  40. }
  41. /**
  42. * Checks session for logged in user, validates the login and finally logs him in.
  43. */
  44. private static function loginUserViaSession()
  45. {
  46. global $_SESSION;
  47. if(isset($_SESSION[static::SESSION_IDENTIFIER])
  48. && !empty($_SESSION[static::SESSION_IDENTIFIER])
  49. ){
  50. $userId = $_SESSION[static::SESSION_IDENTIFIER];
  51. /** @var User $user */
  52. $user = User::find($userId);
  53. // check if user still exists in database
  54. if(!is_null($user)){
  55. static::loginUserByModel($user);
  56. }
  57. }
  58. }
  59. /**
  60. * Login user with provided credentials and save login in session
  61. *
  62. * @param string $email
  63. * @param string $password
  64. *
  65. * @return bool
  66. */
  67. public static function login($email, $password)
  68. {
  69. $email = strtolower($email);
  70. $emailInParts = explode("@", $email);
  71. if(count($emailInParts) !== 2){
  72. return false;
  73. }
  74. $username = $emailInParts[0];
  75. $domain = $emailInParts[1];
  76. /** @var User $user */
  77. $user = User::findWhereFirst(
  78. array(
  79. array(DBC_USERS_USERNAME, $username),
  80. array(DBC_USERS_DOMAIN, $domain),
  81. )
  82. );
  83. // Check if user exists
  84. if(!is_null($user)){
  85. if(static::checkPasswordByHash($password, $user->getPasswordHash())){
  86. static::loginUserByModel($user);
  87. $_SESSION[static::SESSION_IDENTIFIER] = $user->getId();
  88. return true;
  89. }
  90. }
  91. return false;
  92. }
  93. /**
  94. * @return void
  95. */
  96. public static function logout()
  97. {
  98. unset($_SESSION[static::SESSION_IDENTIFIER]);
  99. static::$loggedInUser = null;
  100. if(session_status() === PHP_SESSION_ACTIVE){
  101. session_destroy();
  102. }
  103. }
  104. /**
  105. * Check if current user has a certain role, but User::ROLE_ADMIN will have access to all
  106. *
  107. * @param string $requiredRole
  108. *
  109. * @return bool
  110. */
  111. public static function hasPermission($requiredRole)
  112. {
  113. if(static::isLoggedIn()){
  114. $user = static::getUser();
  115. return $user->getRole() === $requiredRole
  116. || $user->getRole() === User::ROLE_ADMIN;
  117. }
  118. return false;
  119. }
  120. /**
  121. * Checks the new password entered by user on certain criteria, and throws an Exception if its invalid.
  122. *
  123. * @param string $password
  124. * @param string $passwordRepeated
  125. *
  126. * @throws Exception Codes explained below
  127. * 2: One password field is empty
  128. * 3: Passwords aren't equal
  129. * 4: Passwort is too snort
  130. */
  131. public static function validateNewPassword($password, $passwordRepeated)
  132. {
  133. // Check if one passwort input is empty
  134. if(empty($password)){
  135. throw new Exception("First password field was'nt filled out.", 2);
  136. }
  137. if(empty($passwordRepeated)){
  138. throw new Exception("Repeat password field was'nt filled out.", 2);
  139. }
  140. // Check if password are equal
  141. if($password !== $passwordRepeated){
  142. throw new Exception("The repeated password must be equal to the first one.", 3);
  143. }
  144. // Check if password length is okay
  145. if(strlen($password) < MIN_PASS_LENGTH){
  146. throw new Exception("Passwords must be at least ".MIN_PASS_LENGTH." characters long.", 4);
  147. }
  148. }
  149. /**
  150. * @param string $password
  151. * @param string $hash
  152. *
  153. * @return bool
  154. */
  155. public static function checkPasswordByHash($password, $hash)
  156. {
  157. return crypt($password, $hash) === $hash;
  158. }
  159. /**
  160. * @return string
  161. */
  162. private static function getPasswordSchemaPrefix()
  163. {
  164. $map = array(
  165. 'SHA-256' => '$5$rounds=5000$',
  166. 'BLOWFISH' => '$2a$09$',
  167. 'SHA-512' => '$6$rounds=5000$',
  168. );
  169. if(isset($map[PASS_HASH_SCHEMA])){
  170. return $map[PASS_HASH_SCHEMA];
  171. }
  172. return $map['SHA-512'];
  173. }
  174. /**
  175. * @param string $password
  176. *
  177. * @return string
  178. */
  179. public static function generatePasswordHash($password)
  180. {
  181. $salt = base64_encode(rand(1, 1000000) + microtime());
  182. $schemaPrefix = static::getPasswordSchemaPrefix();
  183. $hash = crypt($password, $schemaPrefix.$salt.'$');
  184. return $hash;
  185. }
  186. /**
  187. * @param string $userId
  188. * @param $password
  189. */
  190. public static function changeUserPassword($userId, $password)
  191. {
  192. $passwordHash = static::generatePasswordHash($password);
  193. /** @var User $user */
  194. $user = User::find($userId);
  195. if(!is_null($user)){
  196. $user->setPasswordHash($passwordHash);
  197. $user->save();
  198. }
  199. }
  200. }