User.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. <?php
  2. namespace Grav\Common\User;
  3. use Grav\Common\Data\Blueprints;
  4. use Grav\Common\Data\Data;
  5. use Grav\Common\File\CompiledYamlFile;
  6. use Grav\Common\GravTrait;
  7. use Grav\Common\Utils;
  8. /**
  9. * User object
  10. *
  11. * @property mixed authenticated
  12. * @property mixed password
  13. * @property bool|string hashed_password
  14. * @author RocketTheme
  15. * @license MIT
  16. */
  17. class User extends Data
  18. {
  19. use GravTrait;
  20. /**
  21. * Load user account.
  22. *
  23. * Always creates user object. To check if user exists, use $this->exists().
  24. *
  25. * @param string $username
  26. * @return User
  27. */
  28. public static function load($username)
  29. {
  30. $locator = self::getGrav()['locator'];
  31. $blueprints = new Blueprints('blueprints://');
  32. $blueprint = $blueprints->get('user/account');
  33. $file_path = $locator->findResource('account://' . $username . YAML_EXT);
  34. $file = CompiledYamlFile::instance($file_path);
  35. $content = $file->content();
  36. if (!isset($content['username'])) {
  37. $content['username'] = $username;
  38. }
  39. $user = new User($content, $blueprint);
  40. $user->file($file);
  41. return $user;
  42. }
  43. /**
  44. * Remove user account.
  45. *
  46. * @param string $username
  47. * @return bool True is the action was performed
  48. */
  49. public static function remove($username)
  50. {
  51. $file_path = self::getGrav()['locator']->findResource('account://' . $username . YAML_EXT);
  52. if (file_exists($file_path) && unlink($file_path)) {
  53. return true;
  54. }
  55. return false;
  56. }
  57. /**
  58. * Authenticate user.
  59. *
  60. * If user password needs to be updated, new information will be saved.
  61. *
  62. * @param string $password Plaintext password.
  63. * @return bool
  64. */
  65. public function authenticate($password)
  66. {
  67. $save = false;
  68. // Plain-text is still stored
  69. if ($this->password) {
  70. if ($password !== $this->password) {
  71. // Plain-text passwords do not match, we know we should fail but execute
  72. // verify to protect us from timing attacks and return false regardless of
  73. // the result
  74. Authentication::verify($password, self::getGrav()['config']->get('system.security.default_hash'));
  75. return false;
  76. } else {
  77. // Plain-text does match, we can update the hash and proceed
  78. $save = true;
  79. $this->hashed_password = Authentication::create($this->password);
  80. unset($this->password);
  81. }
  82. }
  83. $result = Authentication::verify($password, $this->hashed_password);
  84. // Password needs to be updated, save the file.
  85. if ($result == 2) {
  86. $save = true;
  87. $this->hashed_password = Authentication::create($password);
  88. }
  89. if ($save) {
  90. $this->save();
  91. }
  92. return (bool) $result;
  93. }
  94. /**
  95. * Save user without the username
  96. */
  97. public function save()
  98. {
  99. $file = $this->file();
  100. if ($file) {
  101. // if plain text password, hash it and remove plain text
  102. if ($this->password) {
  103. $this->hashed_password = Authentication::create($this->password);
  104. unset($this->password);
  105. }
  106. $username = $this->get('username');
  107. unset($this->username);
  108. $file->save($this->items);
  109. $this->set('username', $username);
  110. }
  111. }
  112. /**
  113. * Checks user authorization to the action.
  114. *
  115. * @param string $action
  116. * @return bool
  117. */
  118. public function authorize($action)
  119. {
  120. if (empty($this->items)) {
  121. return false;
  122. }
  123. return Utils::isPositive($this->get("access.{$action}"));
  124. }
  125. /**
  126. * Checks user authorization to the action.
  127. * Ensures backwards compatibility
  128. *
  129. * @param string $action
  130. * @deprecated use authorize()
  131. * @return bool
  132. */
  133. public function authorise($action)
  134. {
  135. return $this->authorize($action);
  136. }
  137. }