PageRenderTime 58ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/symfony/symfony/src/Symfony/Component/Security/Http/RememberMe/AbstractRememberMeServices.php

https://gitlab.com/Marwamimo/Crowdrise_Web
PHP | 312 lines | 154 code | 41 blank | 117 comment | 23 complexity | b46a86eb9e712923fdcfa5653b22fd10 MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Security\Http\RememberMe;
  11. use Symfony\Component\Security\Core\Exception\AuthenticationException;
  12. use Symfony\Component\Security\Core\User\UserInterface;
  13. use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken;
  14. use Symfony\Component\Security\Http\Logout\LogoutHandlerInterface;
  15. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  16. use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
  17. use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
  18. use Symfony\Component\Security\Core\Exception\CookieTheftException;
  19. use Symfony\Component\HttpFoundation\Response;
  20. use Symfony\Component\HttpFoundation\Request;
  21. use Symfony\Component\HttpFoundation\Cookie;
  22. use Psr\Log\LoggerInterface;
  23. /**
  24. * Base class implementing the RememberMeServicesInterface
  25. *
  26. * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  27. */
  28. abstract class AbstractRememberMeServices implements RememberMeServicesInterface, LogoutHandlerInterface
  29. {
  30. const COOKIE_DELIMITER = ':';
  31. protected $logger;
  32. protected $options;
  33. private $providerKey;
  34. private $key;
  35. private $userProviders;
  36. /**
  37. * Constructor.
  38. *
  39. * @param array $userProviders
  40. * @param string $key
  41. * @param string $providerKey
  42. * @param array $options
  43. * @param LoggerInterface $logger
  44. *
  45. * @throws \InvalidArgumentException
  46. */
  47. public function __construct(array $userProviders, $key, $providerKey, array $options = array(), LoggerInterface $logger = null)
  48. {
  49. if (empty($key)) {
  50. throw new \InvalidArgumentException('$key must not be empty.');
  51. }
  52. if (empty($providerKey)) {
  53. throw new \InvalidArgumentException('$providerKey must not be empty.');
  54. }
  55. if (0 === count($userProviders)) {
  56. throw new \InvalidArgumentException('You must provide at least one user provider.');
  57. }
  58. $this->userProviders = $userProviders;
  59. $this->key = $key;
  60. $this->providerKey = $providerKey;
  61. $this->options = $options;
  62. $this->logger = $logger;
  63. }
  64. /**
  65. * Returns the parameter that is used for checking whether remember-me
  66. * services have been requested.
  67. *
  68. * @return string
  69. */
  70. public function getRememberMeParameter()
  71. {
  72. return $this->options['remember_me_parameter'];
  73. }
  74. /**
  75. * @return string
  76. */
  77. public function getKey()
  78. {
  79. return $this->key;
  80. }
  81. /**
  82. * Implementation of RememberMeServicesInterface. Detects whether a remember-me
  83. * cookie was set, decodes it, and hands it to subclasses for further processing.
  84. *
  85. * @param Request $request
  86. *
  87. * @return TokenInterface|null
  88. *
  89. * @throws CookieTheftException
  90. * @throws \RuntimeException
  91. */
  92. final public function autoLogin(Request $request)
  93. {
  94. if (null === $cookie = $request->cookies->get($this->options['name'])) {
  95. return;
  96. }
  97. if (null !== $this->logger) {
  98. $this->logger->debug('Remember-me cookie detected.');
  99. }
  100. $cookieParts = $this->decodeCookie($cookie);
  101. try {
  102. $user = $this->processAutoLoginCookie($cookieParts, $request);
  103. if (!$user instanceof UserInterface) {
  104. throw new \RuntimeException('processAutoLoginCookie() must return a UserInterface implementation.');
  105. }
  106. if (null !== $this->logger) {
  107. $this->logger->info('Remember-me cookie accepted.');
  108. }
  109. return new RememberMeToken($user, $this->providerKey, $this->key);
  110. } catch (CookieTheftException $theft) {
  111. $this->cancelCookie($request);
  112. throw $theft;
  113. } catch (UsernameNotFoundException $notFound) {
  114. if (null !== $this->logger) {
  115. $this->logger->info('User for remember-me cookie not found.');
  116. }
  117. } catch (UnsupportedUserException $unSupported) {
  118. if (null !== $this->logger) {
  119. $this->logger->warning('User class for remember-me cookie not supported.');
  120. }
  121. } catch (AuthenticationException $invalid) {
  122. if (null !== $this->logger) {
  123. $this->logger->debug('Remember-Me authentication failed: '.$invalid->getMessage());
  124. }
  125. }
  126. $this->cancelCookie($request);
  127. }
  128. /**
  129. * Implementation for LogoutHandlerInterface. Deletes the cookie.
  130. *
  131. * @param Request $request
  132. * @param Response $response
  133. * @param TokenInterface $token
  134. */
  135. public function logout(Request $request, Response $response, TokenInterface $token)
  136. {
  137. $this->cancelCookie($request);
  138. }
  139. /**
  140. * Implementation for RememberMeServicesInterface. Deletes the cookie when
  141. * an attempted authentication fails.
  142. *
  143. * @param Request $request
  144. */
  145. final public function loginFail(Request $request)
  146. {
  147. $this->cancelCookie($request);
  148. $this->onLoginFail($request);
  149. }
  150. /**
  151. * Implementation for RememberMeServicesInterface. This is called when an
  152. * authentication is successful.
  153. *
  154. * @param Request $request
  155. * @param Response $response
  156. * @param TokenInterface $token The token that resulted in a successful authentication
  157. */
  158. final public function loginSuccess(Request $request, Response $response, TokenInterface $token)
  159. {
  160. // Make sure any old remember-me cookies are cancelled
  161. $this->cancelCookie($request);
  162. if (!$token->getUser() instanceof UserInterface) {
  163. if (null !== $this->logger) {
  164. $this->logger->debug('Remember-me ignores token since it does not contain a UserInterface implementation.');
  165. }
  166. return;
  167. }
  168. if (!$this->isRememberMeRequested($request)) {
  169. if (null !== $this->logger) {
  170. $this->logger->debug('Remember-me was not requested.');
  171. }
  172. return;
  173. }
  174. if (null !== $this->logger) {
  175. $this->logger->debug('Remember-me was requested; setting cookie.');
  176. }
  177. // Remove attribute from request that sets a NULL cookie.
  178. // It was set by $this->cancelCookie()
  179. // (cancelCookie does other things too for some RememberMeServices
  180. // so we should still call it at the start of this method)
  181. $request->attributes->remove(self::COOKIE_ATTR_NAME);
  182. $this->onLoginSuccess($request, $response, $token);
  183. }
  184. /**
  185. * Subclasses should validate the cookie and do any additional processing
  186. * that is required. This is called from autoLogin().
  187. *
  188. * @param array $cookieParts
  189. * @param Request $request
  190. *
  191. * @return TokenInterface
  192. */
  193. abstract protected function processAutoLoginCookie(array $cookieParts, Request $request);
  194. /**
  195. * @param Request $request
  196. */
  197. protected function onLoginFail(Request $request)
  198. {
  199. }
  200. /**
  201. * This is called after a user has been logged in successfully, and has
  202. * requested remember-me capabilities. The implementation usually sets a
  203. * cookie and possibly stores a persistent record of it.
  204. *
  205. * @param Request $request
  206. * @param Response $response
  207. * @param TokenInterface $token
  208. */
  209. abstract protected function onLoginSuccess(Request $request, Response $response, TokenInterface $token);
  210. final protected function getUserProvider($class)
  211. {
  212. foreach ($this->userProviders as $provider) {
  213. if ($provider->supportsClass($class)) {
  214. return $provider;
  215. }
  216. }
  217. throw new UnsupportedUserException(sprintf('There is no user provider that supports class "%s".', $class));
  218. }
  219. /**
  220. * Decodes the raw cookie value
  221. *
  222. * @param string $rawCookie
  223. *
  224. * @return array
  225. */
  226. protected function decodeCookie($rawCookie)
  227. {
  228. return explode(self::COOKIE_DELIMITER, base64_decode($rawCookie));
  229. }
  230. /**
  231. * Encodes the cookie parts
  232. *
  233. * @param array $cookieParts
  234. *
  235. * @return string
  236. */
  237. protected function encodeCookie(array $cookieParts)
  238. {
  239. return base64_encode(implode(self::COOKIE_DELIMITER, $cookieParts));
  240. }
  241. /**
  242. * Deletes the remember-me cookie
  243. *
  244. * @param Request $request
  245. */
  246. protected function cancelCookie(Request $request)
  247. {
  248. if (null !== $this->logger) {
  249. $this->logger->debug(sprintf('Clearing remember-me cookie "%s"', $this->options['name']));
  250. }
  251. $request->attributes->set(self::COOKIE_ATTR_NAME, new Cookie($this->options['name'], null, 1, $this->options['path'], $this->options['domain']));
  252. }
  253. /**
  254. * Checks whether remember-me capabilities were requested
  255. *
  256. * @param Request $request
  257. *
  258. * @return bool
  259. */
  260. protected function isRememberMeRequested(Request $request)
  261. {
  262. if (true === $this->options['always_remember_me']) {
  263. return true;
  264. }
  265. $parameter = $request->get($this->options['remember_me_parameter'], null, true);
  266. if (null === $parameter && null !== $this->logger) {
  267. $this->logger->debug(sprintf('Did not send remember-me cookie (remember-me parameter "%s" was not sent).', $this->options['remember_me_parameter']));
  268. }
  269. return $parameter === 'true' || $parameter === 'on' || $parameter === '1' || $parameter === 'yes';
  270. }
  271. }