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