Frequency.php 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Security\Model\SecurityChecker;
  7. use Magento\Framework\Exception\SecurityViolationException;
  8. use Magento\Framework\HTTP\PhpEnvironment\RemoteAddress;
  9. use Magento\Security\Model\Config\Source\ResetMethod;
  10. use Magento\Security\Model\ConfigInterface;
  11. use Magento\Security\Model\ResourceModel\PasswordResetRequestEvent\CollectionFactory;
  12. /**
  13. * Checker by frequency requests
  14. */
  15. class Frequency implements SecurityCheckerInterface
  16. {
  17. /**
  18. * @var \Magento\Framework\Stdlib\DateTime\DateTime
  19. */
  20. private $dateTime;
  21. /**
  22. * @var \Magento\Security\Model\ResourceModel\PasswordResetRequestEvent\CollectionFactory
  23. */
  24. private $collectionFactory;
  25. /**
  26. * @var ConfigInterface
  27. */
  28. private $securityConfig;
  29. /**
  30. * @var RemoteAddress
  31. */
  32. private $remoteAddress;
  33. /**
  34. * @param ConfigInterface $securityConfig
  35. * @param CollectionFactory $collectionFactory
  36. * @param \Magento\Framework\Stdlib\DateTime\DateTime $dateTime
  37. * @param RemoteAddress $remoteAddress
  38. */
  39. public function __construct(
  40. ConfigInterface $securityConfig,
  41. CollectionFactory $collectionFactory,
  42. \Magento\Framework\Stdlib\DateTime\DateTime $dateTime,
  43. RemoteAddress $remoteAddress
  44. ) {
  45. $this->securityConfig = $securityConfig;
  46. $this->collectionFactory = $collectionFactory;
  47. $this->dateTime = $dateTime;
  48. $this->remoteAddress = $remoteAddress;
  49. }
  50. /**
  51. * {@inheritdoc}
  52. */
  53. public function check($securityEventType, $accountReference = null, $longIp = null)
  54. {
  55. $isEnabled = $this->securityConfig->getPasswordResetProtectionType() != ResetMethod::OPTION_NONE;
  56. $limitTimeBetweenRequests = $this->securityConfig->getMinTimeBetweenPasswordResetRequests();
  57. if ($isEnabled && $limitTimeBetweenRequests) {
  58. if (null === $longIp) {
  59. $longIp = $this->remoteAddress->getRemoteAddress();
  60. }
  61. $lastRecordCreationTimestamp = $this->loadLastRecordCreationTimestamp(
  62. $securityEventType,
  63. $accountReference,
  64. $longIp
  65. );
  66. if ($lastRecordCreationTimestamp && (
  67. $limitTimeBetweenRequests >
  68. ($this->dateTime->gmtTimestamp() - $lastRecordCreationTimestamp)
  69. )) {
  70. throw new SecurityViolationException(
  71. __(
  72. 'We received too many requests for password resets. '
  73. . 'Please wait and try again later or contact %1.',
  74. $this->securityConfig->getCustomerServiceEmail()
  75. )
  76. );
  77. }
  78. }
  79. }
  80. /**
  81. * Load last record creation timestamp
  82. *
  83. * @param int $securityEventType
  84. * @param string $accountReference
  85. * @param int $longIp
  86. * @return int
  87. */
  88. private function loadLastRecordCreationTimestamp($securityEventType, $accountReference, $longIp)
  89. {
  90. $collection = $this->collectionFactory->create($securityEventType, $accountReference, $longIp);
  91. /** @var \Magento\Security\Model\PasswordResetRequestEvent $record */
  92. $record = $collection->filterLastItem()->getFirstItem();
  93. return (int) strtotime($record->getCreatedAt());
  94. }
  95. }