UserLoginEvent.php 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. <?php
  2. /**
  3. * @package Grav\Plugin\Login
  4. *
  5. * @copyright Copyright (C) 2014 - 2017 RocketTheme, LLC. All rights reserved.
  6. * @license MIT License; see LICENSE file for details.
  7. */
  8. namespace Grav\Plugin\Login\Events;
  9. use Grav\Common\Grav;
  10. use Grav\Common\Session;
  11. use Grav\Common\User\Interfaces\UserCollectionInterface;
  12. use Grav\Common\User\Interfaces\UserInterface;
  13. use RocketTheme\Toolbox\Event\Event;
  14. /**
  15. * Class UserLoginEvent
  16. * @package Grav\Common\User\Events
  17. *
  18. * @property int $status
  19. * @property array $credentials
  20. * @property string|string[] $authorize
  21. * @property array $options
  22. * @property Session $session
  23. * @property UserInterface $user
  24. * @property string $message
  25. *
  26. */
  27. class UserLoginEvent extends Event
  28. {
  29. /**
  30. * Undefined event state.
  31. */
  32. const AUTHENTICATION_UNDEFINED = 0;
  33. /**
  34. * onUserAuthenticate success.
  35. */
  36. const AUTHENTICATION_SUCCESS = 1;
  37. /**
  38. * onUserAuthenticate fails on bad username/password.
  39. */
  40. const AUTHENTICATION_FAILURE = 2;
  41. /**
  42. * onUserAuthenticate fails on auth cancellation.
  43. */
  44. const AUTHENTICATION_CANCELLED = 4;
  45. /**
  46. * onUserAuthorizeLogin fails on expired account.
  47. */
  48. const AUTHORIZATION_EXPIRED = 8;
  49. /**
  50. * onUserAuthorizeLogin is delayed until user has performed extra action(s).
  51. */
  52. const AUTHORIZATION_DELAYED = 16;
  53. /**
  54. * onUserAuthorizeLogin fails for other reasons.
  55. */
  56. const AUTHORIZATION_DENIED = 32;
  57. /**
  58. * UserLoginEvent constructor.
  59. * @param array $items
  60. */
  61. public function __construct(array $items = [])
  62. {
  63. $items += [
  64. 'credentials' => [],
  65. 'options' => [],
  66. 'authorize' => 'site.login',
  67. 'status' => static::AUTHENTICATION_UNDEFINED,
  68. 'session' => null,
  69. 'user' => null,
  70. 'message' => null,
  71. 'redirect' => null,
  72. 'redirect_code' => 303
  73. ];
  74. $items['credentials'] += ['username' => '', 'password' => ''];
  75. parent::__construct($items);
  76. if (!$this->offsetExists('session') && isset(Grav::instance()['session'])) {
  77. $this->offsetSet('session', Grav::instance()['session']);
  78. }
  79. if (!$this->offsetExists('user')) {
  80. /** @var UserCollectionInterface $users */
  81. $users = Grav::instance()['accounts'];
  82. $this->offsetSet('user', $users->load($this['credentials']['username']));
  83. }
  84. }
  85. public function isSuccess()
  86. {
  87. $status = $this->offsetGet('status');
  88. $failure = static::AUTHENTICATION_FAILURE | static::AUTHENTICATION_CANCELLED | static::AUTHORIZATION_EXPIRED
  89. | static::AUTHORIZATION_DENIED;
  90. return ($status & static::AUTHENTICATION_SUCCESS) && !($status & $failure);
  91. }
  92. public function isDelayed()
  93. {
  94. return $this->isSuccess() && ($this->offsetGet('status') & static::AUTHORIZATION_DELAYED);
  95. }
  96. /**
  97. * @return int
  98. */
  99. public function getStatus()
  100. {
  101. return (int)$this->offsetGet('status');
  102. }
  103. /**
  104. * @param int $status
  105. * @return $this
  106. */
  107. public function setStatus($status)
  108. {
  109. $this->offsetSet('status', $this->offsetGet('status') | (int)$status);
  110. return $this;
  111. }
  112. /**
  113. * @return array
  114. */
  115. public function getCredentials()
  116. {
  117. return $this->offsetGet('credentials') + ['username' => '', 'password' => ''];
  118. }
  119. /**
  120. * @param string $name
  121. * @return mixed
  122. */
  123. public function getCredential($name)
  124. {
  125. return $this->items['credentials'][$name] ?? null;
  126. }
  127. /**
  128. * @param string $name
  129. * @param mixed $value
  130. * @return $this
  131. */
  132. public function setCredential($name, $value)
  133. {
  134. $this->items['credentials'][$name] = $value;
  135. return $this;
  136. }
  137. /**
  138. * @return array
  139. */
  140. public function getOptions()
  141. {
  142. return $this->offsetGet('options');
  143. }
  144. /**
  145. * @param string $name
  146. * @return mixed
  147. */
  148. public function getOption($name)
  149. {
  150. return $this->items['options'][$name] ?? null;
  151. }
  152. /**
  153. * @param string $name
  154. * @param mixed $value
  155. * @return $this
  156. */
  157. public function setOption($name, $value)
  158. {
  159. $this->items['options'][$name] = $value;
  160. return $this;
  161. }
  162. /**
  163. * @return Session|null
  164. */
  165. public function getSession()
  166. {
  167. return $this->offsetGet('session');
  168. }
  169. /**
  170. * @return UserInterface
  171. */
  172. public function getUser()
  173. {
  174. return $this->offsetGet('user');
  175. }
  176. /**
  177. * @param UserInterface $user
  178. * @return $this
  179. */
  180. public function setUser(UserInterface $user)
  181. {
  182. $this->offsetSet('user', $user);
  183. return $this;
  184. }
  185. /**
  186. * @return array
  187. */
  188. public function getAuthorize()
  189. {
  190. return (array)$this->offsetGet('authorize');
  191. }
  192. /**
  193. * @return string|null
  194. */
  195. public function getMessage()
  196. {
  197. return !empty($this->items['message'][0]) ? (string)$this->items['message'][0] : null;
  198. }
  199. /**
  200. * @return string|null
  201. */
  202. public function getMessageType()
  203. {
  204. return !empty($this->items['message'][1]) ? (string)$this->items['message'][1] : 'info';
  205. }
  206. /**
  207. * @param string $message
  208. * @param string|null $type
  209. * @return $this
  210. */
  211. public function setMessage($message, $type = null)
  212. {
  213. $this->items['message'] = $message ? [$message, $type] : null;
  214. return $this;
  215. }
  216. /**
  217. * @param string $message
  218. * @param string|null $type
  219. * @return $this
  220. */
  221. public function defMessage($message, $type = null)
  222. {
  223. if ($message && !isset($this->items['message'])) {
  224. $this->setMessage($message, $type);
  225. }
  226. return $this;
  227. }
  228. /**
  229. * @return string|null
  230. */
  231. public function getRedirect()
  232. {
  233. return $this->items['redirect'] ?? null;
  234. }
  235. /**
  236. * @return int
  237. */
  238. public function getRedirectCode()
  239. {
  240. return $this->items['redirect_code'] ?? 303;
  241. }
  242. /**
  243. * @param string $path
  244. * @param int $code
  245. * @return $this
  246. */
  247. public function setRedirect($path, $code = 303)
  248. {
  249. $this->items['redirect'] = $path ?: null;
  250. $this->items['redirect_code'] = (int)$code;
  251. return $this;
  252. }
  253. /**
  254. * @param string $path
  255. * @param int $code
  256. * @return $this
  257. */
  258. public function defRedirect($path, $code = 303)
  259. {
  260. if ($path && !isset($this->items['redirect'])) {
  261. $this->setRedirect($path, $code);
  262. }
  263. return $this;
  264. }
  265. /**
  266. * Magic setter method
  267. *
  268. * @param mixed $offset Asset name value
  269. * @param mixed $value Asset value
  270. */
  271. public function __set($offset, $value)
  272. {
  273. $this->offsetSet($offset, $value);
  274. }
  275. /**
  276. * Magic getter method
  277. *
  278. * @param mixed $offset Asset name value
  279. * @return mixed Asset value
  280. */
  281. public function __get($offset)
  282. {
  283. return $this->offsetGet($offset);
  284. }
  285. /**
  286. * Magic method to determine if the attribute is set
  287. *
  288. * @param mixed $offset Asset name value
  289. * @return boolean True if the value is set
  290. */
  291. public function __isset($offset)
  292. {
  293. return $this->offsetExists($offset);
  294. }
  295. /**
  296. * Magic method to unset the attribute
  297. *
  298. * @param mixed $offset The name value to unset
  299. */
  300. public function __unset($offset)
  301. {
  302. $this->offsetUnset($offset);
  303. }
  304. }