Auth.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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. session_destroy();
  100. }
  101. /**
  102. * Check if current user has a certain role, but User::ROLE_ADMIN will have access to all
  103. *
  104. * @param string $requiredRole
  105. *
  106. * @return bool
  107. */
  108. public static function hasPermission($requiredRole)
  109. {
  110. if(static::isLoggedIn()) {
  111. $user = static::getUser();
  112. return $user->getRole() === $requiredRole
  113. || $user->getRole() === User::ROLE_ADMIN;
  114. }
  115. return false;
  116. }
  117. /**
  118. * Checks the new password entered by user on certain criteria, and throws an Exception if its invalid.
  119. *
  120. * @param string $password
  121. * @param string $passwordRepeated
  122. *
  123. * @throws Exception Codes explained below
  124. * 2: One password field is empty
  125. * 3: Passwords aren't equal
  126. * 4: Passwort is too snort
  127. */
  128. public static function validateNewPassword($password, $passwordRepeated)
  129. {
  130. // Check if one passwort input is empty
  131. if(empty($password)){
  132. throw new Exception("First password field was'nt filled out.", 2);
  133. }
  134. elseif(empty($passwordRepeated)){
  135. throw new Exception("Repeat password field was'nt filled out.", 2);
  136. }
  137. else {
  138. // Check if password are equal
  139. if($password !== $passwordRepeated){
  140. throw new Exception("The repeated password must be equal to the first one.", 3);
  141. }
  142. else {
  143. // Check if password length is okay
  144. if(strlen($password) < MIN_PASS_LENGTH){
  145. throw new Exception("Passwords must be at least ".MIN_PASS_LENGTH." characters long.", 4);
  146. }
  147. }
  148. }
  149. }
  150. /**
  151. * @param string $password
  152. * @param string $hash
  153. *
  154. * @return bool
  155. */
  156. public static function checkPasswordByHash($password, $hash)
  157. {
  158. return crypt($password, $hash) === $hash;
  159. }
  160. /**
  161. * @return string
  162. */
  163. private static function getPasswordSchemaPrefix()
  164. {
  165. switch(PASS_HASH_SCHEMA){
  166. case "SHA-256":
  167. return '$5$rounds=5000$';
  168. case "BLOWFISH":
  169. return '$2a$09$';
  170. case "SHA-512":
  171. default:
  172. return '$6$rounds=5000$';
  173. }
  174. }
  175. /**
  176. * @param string $password
  177. *
  178. * @return string
  179. */
  180. public static function generatePasswordHash($password)
  181. {
  182. $salt = base64_encode(rand(1, 1000000) + microtime());
  183. $schemaPrefix = static::getPasswordSchemaPrefix();
  184. $hash = crypt($password, $schemaPrefix.$salt.'$');
  185. return $hash;
  186. }
  187. /**
  188. * @param string $userId
  189. * @param $password
  190. */
  191. public static function changeUserPassword($userId, $password)
  192. {
  193. $passwordHash = static::generatePasswordHash($password);
  194. /** @var User $user */
  195. $user = User::find($userId);
  196. if(!is_null($user)){
  197. $user->setPasswordHash($passwordHash);
  198. $user->save();
  199. }
  200. }
  201. }