Skip to content

Commit 7937e05

Browse files
committed
AC-1271: Add rate limiting for payment information endpoint and mutation
1 parent 8630e12 commit 7937e05

File tree

6 files changed

+143
-157
lines changed

6 files changed

+143
-157
lines changed

app/code/Magento/Quote/Model/Backpressure/OrderLimitConfigManager.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,16 @@ public function readLimit(ContextInterface $context): LimitConfig
7979
public function isEnforcementEnabled(): bool
8080
{
8181
$loggerType = $this->deploymentConfig->get(RequestLoggerInterface::CONFIG_PATH_BACKPRESSURE_LOGGER);
82+
if (!$loggerType) {
83+
return false;
84+
}
85+
8286
$enabled = $this->config->isSetFlag('sales/backpressure/enabled', ScopeInterface::SCOPE_STORE);
83-
if ($loggerType && $enabled) {
84-
return true;
87+
if (!$enabled) {
88+
return false;
8589
}
8690

87-
return false;
91+
return true;
8892
}
8993

9094
/**
@@ -117,6 +121,6 @@ private function fetchGuestLimit(): int
117121
*/
118122
private function fetchPeriod(): int
119123
{
120-
return (int)$this->config->getValue('sales/backpressure/period', ScopeInterface::SCOPE_STORE);
124+
return (int)$this->config->getValue('sales/backpressure/period', ScopeInterface::SCOPE_STORE);
121125
}
122126
}

app/code/Magento/Quote/Test/Unit/Model/Backpressure/OrderLimitConfigManagerTest.php

Lines changed: 50 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88

99
namespace Magento\Quote\Test\Unit\Model\Backpressure;
1010

11+
use Magento\Framework\App\DeploymentConfig;
12+
use Magento\Framework\Exception\FileSystemException;
13+
use Magento\Framework\Exception\RuntimeException;
1114
use Magento\Quote\Model\Backpressure\OrderLimitConfigManager;
1215
use Magento\Framework\App\Backpressure\ContextInterface;
1316
use Magento\Framework\App\Config\ScopeConfigInterface;
@@ -19,12 +22,17 @@ class OrderLimitConfigManagerTest extends TestCase
1922
/**
2023
* @var ScopeConfigInterface|MockObject
2124
*/
22-
private $config;
25+
private $scopeConfigMock;
26+
27+
/**
28+
* @var DeploymentConfig|MockObject
29+
*/
30+
private $deploymentConfigMock;
2331

2432
/**
2533
* @var OrderLimitConfigManager
2634
*/
27-
private $model;
35+
private OrderLimitConfigManager $model;
2836

2937
/**
3038
* @inheritDoc
@@ -33,9 +41,13 @@ protected function setUp(): void
3341
{
3442
parent::setUp();
3543

36-
$this->config = $this->createMock(ScopeConfigInterface::class);
44+
$this->scopeConfigMock = $this->createMock(ScopeConfigInterface::class);
45+
$this->deploymentConfigMock = $this->createMock(DeploymentConfig::class);
3746

38-
$this->model = new OrderLimitConfigManager($this->config);
47+
$this->model = new OrderLimitConfigManager(
48+
$this->scopeConfigMock,
49+
$this->deploymentConfigMock
50+
);
3951
}
4052

4153
/**
@@ -62,6 +74,7 @@ public function getConfigCases(): array
6274
* @param int $expectedPeriod
6375
* @return void
6476
* @dataProvider getConfigCases
77+
* @throws RuntimeException
6578
*/
6679
public function testReadLimit(
6780
int $identityType,
@@ -71,102 +84,61 @@ public function testReadLimit(
7184
int $expectedLimit,
7285
int $expectedPeriod
7386
): void {
74-
$this->initConfig($guestLimit, $authLimit, $period, true);
75-
$context = $this->createContext($identityType);
87+
$context = $this->createMock(ContextInterface::class);
88+
$context->method('getIdentityType')->willReturn($identityType);
89+
90+
$this->scopeConfigMock->method('getValue')
91+
->willReturnMap(
92+
[
93+
['sales/backpressure/limit', 'store', null, $authLimit],
94+
['sales/backpressure/guest_limit', 'store', null, $guestLimit],
95+
['sales/backpressure/period', 'store', null, $period],
96+
]
97+
);
7698

7799
$limit = $this->model->readLimit($context);
78100
$this->assertEquals($expectedLimit, $limit->getLimit());
79101
$this->assertEquals($expectedPeriod, $limit->getPeriod());
80102
}
81103

82104
/**
83-
* Config variations for enabled check.
84-
*
85-
* @return array
86-
*/
87-
public function getEnabledCases(): array
88-
{
89-
return [
90-
'disabled' => [100, 100, 60, false, false],
91-
'guest-misconfigured-1' => [0, 100, 60, true, false],
92-
'auth-misconfigured-1' => [10, -1, 60, true, false],
93-
'period-misconfigured-1' => [10, 111, 0, true, false],
94-
'enabled' => [10, 111, 60, true, true]
95-
];
96-
}
97-
98-
/**
99-
* Verify logic behind enabled check.
105+
* Verify logic behind enabled check
100106
*
101-
* @param int $guestLimit
102-
* @param int $authLimit
103-
* @param int $period
104107
* @param bool $enabled
105108
* @param bool $expected
109+
* @param string|null $requestLoggerType
106110
* @return void
111+
* @throws RuntimeException
112+
* @throws FileSystemException
107113
* @dataProvider getEnabledCases
108114
*/
109115
public function testIsEnforcementEnabled(
110-
int $guestLimit,
111-
int $authLimit,
112-
int $period,
113-
bool $enabled,
114-
bool $expected
116+
bool $enabled,
117+
bool $expected,
118+
?string $requestLoggerType
115119
): void {
116-
$this->initConfig($guestLimit, $authLimit, $period, $enabled);
120+
$this->deploymentConfigMock->method('get')
121+
->with('backpressure/logger/type')
122+
->willReturn($requestLoggerType);
123+
$this->scopeConfigMock->method('isSetFlag')
124+
->with('sales/backpressure/enabled')
125+
->willReturn($enabled);
117126

118127
$this->assertEquals($expected, $this->model->isEnforcementEnabled());
119128
}
120129

121130
/**
122-
* Initialize config mock.
123-
*
124-
* @param int $guest
125-
* @param int $auth
126-
* @param int $period
127-
* @param bool $enabled
128-
* @return void
129-
*/
130-
private function initConfig(int $guest, int $auth, int $period, bool $enabled): void
131-
{
132-
$this->config->method('getValue')
133-
->willReturnCallback(
134-
function (string $path) use ($auth, $guest, $period): ?string {
135-
switch ($path) {
136-
case 'sales/backpressure/limit':
137-
return (string) $auth;
138-
case 'sales/backpressure/guest_limit':
139-
return (string) $guest;
140-
case 'sales/backpressure/period':
141-
return (string) $period;
142-
}
143-
144-
return null;
145-
}
146-
);
147-
$this->config->method('isSetFlag')
148-
->willReturnCallback(
149-
function (string $path) use ($enabled): bool {
150-
if ($path === 'sales/backpressure/enabled') {
151-
return $enabled;
152-
}
153-
154-
return false;
155-
}
156-
);
157-
}
158-
159-
/**
160-
* Create backpressure context.
131+
* Config variations for enabled check.
161132
*
162-
* @param int $identityType
163-
* @return ContextInterface
133+
* @return array
164134
*/
165-
private function createContext(int $identityType): ContextInterface
135+
public function getEnabledCases(): array
166136
{
167-
$context = $this->createMock(ContextInterface::class);
168-
$context->method('getIdentityType')->willReturn($identityType);
169-
170-
return $context;
137+
return [
138+
'disabled' => [false, false, null],
139+
'disabled-request-logger-type-exists' => [false, false, 'requestLoggerType'],
140+
'enabled-request-logger-type-not-exist' => [true, false, null],
141+
'enabled' => [true, true, 'requestLoggerType'],
142+
];
171143
}
172144
}

lib/internal/Magento/Framework/App/Backpressure/SlidingWindow/RedisRequestLogger.php

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@ class RedisRequestLogger implements RequestLoggerInterface
3939
public const CONFIG_PATH_BACKPRESSURE_LOGGER_REDIS_DB = 'backpressure/logger/options/db';
4040
public const CONFIG_PATH_BACKPRESSURE_LOGGER_REDIS_PASSWORD = 'backpressure/logger/options/password';
4141
public const CONFIG_PATH_BACKPRESSURE_LOGGER_REDIS_USER = 'backpressure/logger/options/user';
42-
public const CONFIG_PATH_BACKPRESSURE_LOGGER_REDIS_COMPRESS_DATA = 'backpressure/logger/options/compress-data';
43-
public const CONFIG_PATH_BACKPRESSURE_LOGGER_REDIS_COMPRESSION_LIB = 'backpressure/logger/options/compression-lib';
4442
public const CONFIG_PATH_BACKPRESSURE_LOGGER_ID_PREFIX = 'backpressure/logger/id-prefix';
4543

4644
/**
@@ -59,8 +57,6 @@ class RedisRequestLogger implements RequestLoggerInterface
5957
self::CONFIG_PATH_BACKPRESSURE_LOGGER_REDIS_DB => 3,
6058
self::CONFIG_PATH_BACKPRESSURE_LOGGER_REDIS_PASSWORD => null,
6159
self::CONFIG_PATH_BACKPRESSURE_LOGGER_REDIS_USER => null,
62-
self::CONFIG_PATH_BACKPRESSURE_LOGGER_REDIS_COMPRESS_DATA => 0,
63-
self::CONFIG_PATH_BACKPRESSURE_LOGGER_REDIS_COMPRESSION_LIB => null,
6460
];
6561

6662
/**
@@ -76,11 +72,6 @@ class RedisRequestLogger implements RequestLoggerInterface
7672
self::KEY_USER => self::CONFIG_PATH_BACKPRESSURE_LOGGER_REDIS_USER,
7773
];
7874

79-
/**
80-
* Valid compression libs
81-
*/
82-
public const VALID_COMPRESSION_LIBS = ['gzip', 'lzf', 'lz4', 'snappy'];
83-
8475
/**
8576
* @var Credis_Client
8677
*/

lib/internal/Magento/Framework/App/Backpressure/SlidingWindow/RequestLoggerFactory.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ public function __construct(ObjectManagerInterface $objectManager, array $types)
3636
}
3737

3838
/**
39+
* @inheritDoc
40+
*
3941
* @param string $type
4042
* @return RequestLoggerInterface
4143
* @throws RuntimeException

0 commit comments

Comments
 (0)