SecurityManager.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Security\Model;
  7. use Magento\Framework\Exception\SecurityViolationException;
  8. use Magento\Framework\HTTP\PhpEnvironment\RemoteAddress;
  9. use Magento\Security\Model\SecurityChecker\SecurityCheckerInterface;
  10. /**
  11. * Manager for password reset actions
  12. *
  13. * @api
  14. *
  15. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  16. * @since 100.1.0
  17. */
  18. class SecurityManager
  19. {
  20. /**
  21. * Security control records time life
  22. */
  23. const SECURITY_CONTROL_RECORDS_LIFE_TIME = 86400;
  24. /**
  25. * @var ConfigInterface
  26. * @since 100.1.0
  27. */
  28. protected $securityConfig;
  29. /**
  30. * @var \Magento\Security\Model\PasswordResetRequestEventFactory
  31. * @since 100.1.0
  32. */
  33. protected $passwordResetRequestEventFactory;
  34. /**
  35. * @var ResourceModel\PasswordResetRequestEvent\CollectionFactory
  36. * @since 100.1.0
  37. */
  38. protected $passwordResetRequestEventCollectionFactory;
  39. /**
  40. * @var SecurityCheckerInterface[]
  41. * @since 100.1.0
  42. */
  43. protected $securityCheckers;
  44. /**
  45. * @var \Magento\Framework\Event\ManagerInterface
  46. */
  47. private $eventManager;
  48. /**
  49. * @var \Magento\Framework\Stdlib\DateTime\DateTime
  50. */
  51. private $dateTime;
  52. /**
  53. * @var RemoteAddress
  54. */
  55. private $remoteAddress;
  56. /**
  57. * SecurityManager constructor.
  58. *
  59. * @param ConfigInterface $securityConfig
  60. * @param \Magento\Security\Model\PasswordResetRequestEventFactory $passwordResetRequestEventFactory
  61. * @param ResourceModel\PasswordResetRequestEvent\CollectionFactory $passwordResetRequestEventCollectionFactory
  62. * @param \Magento\Framework\Event\ManagerInterface $eventManager
  63. * @param \Magento\Framework\Stdlib\DateTime\DateTime $dateTime
  64. * @param RemoteAddress $remoteAddress
  65. * @param array $securityCheckers
  66. * @throws \Magento\Framework\Exception\LocalizedException
  67. */
  68. public function __construct(
  69. ConfigInterface $securityConfig,
  70. \Magento\Security\Model\PasswordResetRequestEventFactory $passwordResetRequestEventFactory,
  71. ResourceModel\PasswordResetRequestEvent\CollectionFactory $passwordResetRequestEventCollectionFactory,
  72. \Magento\Framework\Event\ManagerInterface $eventManager,
  73. \Magento\Framework\Stdlib\DateTime\DateTime $dateTime,
  74. RemoteAddress $remoteAddress,
  75. $securityCheckers = []
  76. ) {
  77. $this->securityConfig = $securityConfig;
  78. $this->passwordResetRequestEventFactory = $passwordResetRequestEventFactory;
  79. $this->passwordResetRequestEventCollectionFactory = $passwordResetRequestEventCollectionFactory;
  80. $this->securityCheckers = $securityCheckers;
  81. $this->eventManager = $eventManager;
  82. $this->dateTime = $dateTime;
  83. $this->remoteAddress = $remoteAddress;
  84. foreach ($this->securityCheckers as $checker) {
  85. if (!($checker instanceof SecurityCheckerInterface)) {
  86. throw new \Magento\Framework\Exception\LocalizedException(
  87. __('Incorrect Security Checker class. It has to implement SecurityCheckerInterface')
  88. );
  89. }
  90. }
  91. }
  92. /**
  93. * Perform security check
  94. *
  95. * @param int $requestType
  96. * @param string|null $accountReference
  97. * @param int|null $longIp
  98. * @return $this
  99. * @throws SecurityViolationException
  100. * @since 100.1.0
  101. */
  102. public function performSecurityCheck($requestType, $accountReference = null, $longIp = null)
  103. {
  104. if (null === $longIp) {
  105. $longIp = $this->remoteAddress->getRemoteAddress();
  106. }
  107. foreach ($this->securityCheckers as $checker) {
  108. $checker->check($requestType, $accountReference, $longIp);
  109. }
  110. $this->createNewPasswordResetRequestEventRecord($requestType, $accountReference, $longIp);
  111. return $this;
  112. }
  113. /**
  114. * Clean expired Admin Sessions
  115. *
  116. * @return $this
  117. * @since 100.1.0
  118. */
  119. public function cleanExpiredRecords()
  120. {
  121. $this->passwordResetRequestEventCollectionFactory->create()->deleteRecordsOlderThen(
  122. $this->dateTime->gmtTimestamp() - self::SECURITY_CONTROL_RECORDS_LIFE_TIME
  123. );
  124. return $this;
  125. }
  126. /**
  127. * Create new password reset request record
  128. *
  129. * @param int $requestType
  130. * @param string|null $accountReference
  131. * @param int $longIp
  132. * @return PasswordResetRequestEvent
  133. * @since 100.1.0
  134. */
  135. protected function createNewPasswordResetRequestEventRecord($requestType, $accountReference, $longIp)
  136. {
  137. /** @var \Magento\Security\Model\PasswordResetRequestEventFactory $passwordResetRequestEvent */
  138. $passwordResetRequestEvent = $this->passwordResetRequestEventFactory->create();
  139. $passwordResetRequestEvent->setRequestType($requestType)
  140. ->setAccountReference($accountReference)
  141. ->setIp($longIp)
  142. ->save();
  143. return $passwordResetRequestEvent;
  144. }
  145. }