PageRenderTime 26ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/app/code/Magento/Customer/Model/Authentication.php

https://gitlab.com/svillegas/magento2
PHP | 168 lines | 91 code | 19 blank | 58 comment | 9 complexity | 813b886a10f4e747d5c69f116fd18cf6 MD5 | raw file
  1. <?php
  2. /**
  3. * Copyright © 2016 Magento. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Customer\Model;
  7. use Magento\Customer\Api\CustomerRepositoryInterface;
  8. use Magento\Backend\App\ConfigInterface;
  9. use Magento\Framework\Encryption\EncryptorInterface as Encryptor;
  10. use Magento\Framework\Exception\InvalidEmailOrPasswordException;
  11. use Magento\Framework\Exception\State\UserLockedException;
  12. class Authentication implements AuthenticationInterface
  13. {
  14. /**
  15. * Configuration path to customer lockout threshold
  16. */
  17. const LOCKOUT_THRESHOLD_PATH = 'customer/password/lockout_threshold';
  18. /**
  19. * Configuration path to customer max login failures number
  20. */
  21. const MAX_FAILURES_PATH = 'customer/password/lockout_failures';
  22. /**
  23. * @var CustomerRegistry
  24. */
  25. protected $customerRegistry;
  26. /**
  27. * Backend configuration interface
  28. *
  29. * @var \Magento\Backend\App\ConfigInterface
  30. */
  31. protected $backendConfig;
  32. /**
  33. * @var \Magento\Framework\Stdlib\DateTime
  34. */
  35. protected $dateTime;
  36. /**
  37. * @var Encryptor
  38. */
  39. protected $encryptor;
  40. /**
  41. * @var CustomerRepositoryInterface
  42. */
  43. protected $customerRepository;
  44. /**
  45. * @param CustomerRepositoryInterface $customerRepository
  46. * @param CustomerRegistry $customerRegistry
  47. * @param ConfigInterface $backendConfig
  48. * @param \Magento\Framework\Stdlib\DateTime $dateTime
  49. * @param Encryptor $encryptor
  50. */
  51. public function __construct(
  52. CustomerRepositoryInterface $customerRepository,
  53. CustomerRegistry $customerRegistry,
  54. ConfigInterface $backendConfig,
  55. \Magento\Framework\Stdlib\DateTime $dateTime,
  56. Encryptor $encryptor
  57. ) {
  58. $this->customerRepository = $customerRepository;
  59. $this->customerRegistry = $customerRegistry;
  60. $this->backendConfig = $backendConfig;
  61. $this->dateTime = $dateTime;
  62. $this->encryptor = $encryptor;
  63. }
  64. /**
  65. * {@inheritdoc}
  66. */
  67. public function processAuthenticationFailure($customerId)
  68. {
  69. $now = new \DateTime();
  70. $lockThreshold = $this->getLockThreshold();
  71. $maxFailures = $this->getMaxFailures();
  72. $customerSecure = $this->customerRegistry->retrieveSecureData($customerId);
  73. if (!($lockThreshold && $maxFailures)) {
  74. return;
  75. }
  76. $failuresNum = (int)$customerSecure->getFailuresNum() + 1;
  77. $firstFailureDate = $customerSecure->getFirstFailure();
  78. if ($firstFailureDate) {
  79. $firstFailureDate = new \DateTime($firstFailureDate);
  80. }
  81. $lockThreshInterval = new \DateInterval('PT' . $lockThreshold . 'S');
  82. $lockExpires = $customerSecure->getLockExpires();
  83. $lockExpired = ($lockExpires !== null) && ($now > new \DateTime($lockExpires));
  84. // set first failure date when this is the first failure or the lock is expired
  85. if (1 === $failuresNum || !$firstFailureDate || $lockExpired) {
  86. $customerSecure->setFirstFailure($this->dateTime->formatDate($now));
  87. $failuresNum = 1;
  88. $customerSecure->setLockExpires(null);
  89. // otherwise lock customer
  90. } elseif ($failuresNum >= $maxFailures) {
  91. $customerSecure->setLockExpires($this->dateTime->formatDate($now->add($lockThreshInterval)));
  92. }
  93. $customerSecure->setFailuresNum($failuresNum);
  94. $this->customerRepository->save($this->customerRepository->getById($customerId));
  95. }
  96. /**
  97. * {@inheritdoc}
  98. */
  99. public function unlock($customerId)
  100. {
  101. $customerSecure = $this->customerRegistry->retrieveSecureData($customerId);
  102. $customerSecure->setFailuresNum(0);
  103. $customerSecure->setFirstFailure(null);
  104. $customerSecure->setLockExpires(null);
  105. $this->customerRepository->save($this->customerRepository->getById($customerId));
  106. }
  107. /**
  108. * Get lock threshold
  109. *
  110. * @return int
  111. */
  112. protected function getLockThreshold()
  113. {
  114. return $this->backendConfig->getValue(self::LOCKOUT_THRESHOLD_PATH) * 60;
  115. }
  116. /**
  117. * Get max failures
  118. *
  119. * @return int
  120. */
  121. protected function getMaxFailures()
  122. {
  123. return $this->backendConfig->getValue(self::MAX_FAILURES_PATH);
  124. }
  125. /**
  126. * {@inheritdoc}
  127. */
  128. public function isLocked($customerId)
  129. {
  130. $currentCustomer = $this->customerRegistry->retrieve($customerId);
  131. return $currentCustomer->isCustomerLocked();
  132. }
  133. /**
  134. * {@inheritdoc}
  135. */
  136. public function authenticate($customerId, $password)
  137. {
  138. $customerSecure = $this->customerRegistry->retrieveSecureData($customerId);
  139. $hash = $customerSecure->getPasswordHash();
  140. if (!$this->encryptor->validateHash($password, $hash)) {
  141. $this->processAuthenticationFailure($customerId);
  142. if ($this->isLocked($customerId)) {
  143. throw new UserLockedException(__('The account is locked.'));
  144. }
  145. throw new InvalidEmailOrPasswordException(__('Invalid login or password.'));
  146. }
  147. return true;
  148. }
  149. }