Skip to content

Commit e1b264c

Browse files
committed
AC-12767: Implement extensible data re-encryption mechanism.
1 parent da656b1 commit e1b264c

File tree

4 files changed

+59
-49
lines changed
  • app/code/Magento
  • dev/tests/integration/testsuite/Magento/Config/Model/Data/ReEncryptorList/CoreConfigDataReEncryptor

4 files changed

+59
-49
lines changed

app/code/Magento/Config/Model/Data/ReEncryptorList/CoreConfigDataReEncryptor/Handler.php

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Magento\Framework\Encryption\EncryptorInterface;
1212
use Magento\EncryptionKey\Model\Data\ReEncryptorList\ReEncryptor\HandlerInterface;
1313
use Magento\EncryptionKey\Model\Data\ReEncryptorList\ReEncryptor\Handler\ErrorFactory;
14+
use Magento\Framework\DB\Query\Generator;
1415

1516
/**
1617
* Handler for core configuration re-encryption.
@@ -30,7 +31,12 @@ class Handler implements HandlerInterface
3031
/**
3132
* @var int
3233
*/
33-
private const QUERY_SIZE = 1000;
34+
private const BATCH_SIZE = 1000;
35+
36+
/**
37+
* @var string
38+
*/
39+
private const IDENTIFIER = "config_id";
3440

3541
/**
3642
* @var EncryptorInterface
@@ -47,19 +53,27 @@ class Handler implements HandlerInterface
4753
*/
4854
private ErrorFactory $errorFactory;
4955

56+
/**
57+
* @var Generator
58+
*/
59+
private Generator $queryGenerator;
60+
5061
/**
5162
* @param EncryptorInterface $encryptor
5263
* @param ResourceConnection $resourceConnection
5364
* @param ErrorFactory $errorFactory
65+
* @param Generator $queryGenerator
5466
*/
5567
public function __construct(
5668
EncryptorInterface $encryptor,
5769
ResourceConnection $resourceConnection,
58-
ErrorFactory $errorFactory
70+
ErrorFactory $errorFactory,
71+
Generator $queryGenerator
5972
) {
6073
$this->encryptor = $encryptor;
6174
$this->resourceConnection = $resourceConnection;
6275
$this->errorFactory = $errorFactory;
76+
$this->queryGenerator = $queryGenerator;
6377
}
6478

6579
/**
@@ -77,24 +91,31 @@ public function reEncrypt(): array
7791
->from($tableName, ['config_id', 'value'])
7892
->where('value != ?', '')
7993
->where('value IS NOT NULL')
80-
->where('value REGEXP ?', self::PATTERN)
81-
->limit(self::QUERY_SIZE);
82-
83-
foreach ($connection->fetchPairs($select) as $configId => $value) {
84-
try {
85-
$connection->update(
86-
$tableName,
87-
['value' => $this->encryptor->encrypt($this->encryptor->decrypt($value))],
88-
['config_id = ?' => (int)$configId]
89-
);
90-
} catch (\Throwable $e) {
91-
$errors[] = $this->errorFactory->create(
92-
"config_id",
93-
$configId,
94-
$e->getMessage()
95-
);
96-
97-
continue;
94+
->where('value REGEXP ?', self::PATTERN);
95+
96+
$iterator = $this->queryGenerator->generate(
97+
self::IDENTIFIER,
98+
$select,
99+
self::BATCH_SIZE
100+
);
101+
102+
foreach ($iterator as $batch) {
103+
foreach ($connection->fetchAll($batch) as $row) {
104+
try {
105+
$connection->update(
106+
$tableName,
107+
['value' => $this->encryptor->encrypt($this->encryptor->decrypt($row['value']))],
108+
['config_id = ?' => $row['config_id']]
109+
);
110+
} catch (\Throwable $e) {
111+
$errors[] = $this->errorFactory->create(
112+
self::IDENTIFIER,
113+
$row['config_id'],
114+
$e->getMessage()
115+
);
116+
117+
continue;
118+
}
98119
}
99120
}
100121

app/code/Magento/EncryptionKey/Model/Data/ReEncryptorList/ReEncryptor/Handler/Error.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ class Error
2222
/**
2323
* Value of the identifier field of a DB row an error relates to.
2424
*
25-
* @var int
25+
* @var int|string
2626
*/
27-
private int $rowIdValue;
27+
private int|string $rowIdValue;
2828

2929
/**
3030
* Error message.
@@ -35,12 +35,12 @@ class Error
3535

3636
/**
3737
* @param string $rowIdField
38-
* @param int $rowIdValue
38+
* @param int|string $rowIdValue
3939
* @param string $message
4040
*/
4141
public function __construct(
4242
string $rowIdField,
43-
int $rowIdValue,
43+
int|string $rowIdValue,
4444
string $message
4545
) {
4646
$this->rowIdField = $rowIdField;
@@ -61,9 +61,9 @@ public function getRowIdField(): string
6161
/**
6262
* Returns row ID field value.
6363
*
64-
* @return int
64+
* @return int|string
6565
*/
66-
public function getRowIdValue(): int
66+
public function getRowIdValue(): int|string
6767
{
6868
return $this->rowIdValue;
6969
}

app/code/Magento/EncryptionKey/Model/Data/ReEncryptorList/ReEncryptor/Handler/ErrorFactory.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ public function __construct(
3232
* Creates an error object.
3333
*
3434
* @param string $rowIdField
35-
* @param int $rowIdValue
35+
* @param int|string $rowIdValue
3636
* @param string $message
3737
*
3838
* @return Error
3939
*/
40-
public function create(string $rowIdField, int $rowIdValue, string $message): Error
40+
public function create(string $rowIdField, int|string $rowIdValue, string $message): Error
4141
{
4242
return $this->objectManager->create(
4343
Error::class,

dev/tests/integration/testsuite/Magento/Config/Model/Data/ReEncryptorList/CoreConfigDataReEncryptor/HandlerTest.php

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ class HandlerTest extends TestCase
3535
*/
3636
private ?EncryptorInterface $encryptor;
3737

38+
/**
39+
* Initialize dependencies
40+
*
41+
* @return void
42+
*/
3843
protected function setUp(): void
3944
{
4045
$this->config = Bootstrap::getObjectManager()->get(
@@ -51,30 +56,17 @@ protected function setUp(): void
5156
}
5257

5358
/**
59+
* Test ReEncryption for core config data
60+
*
5461
* @magentoDbIsolation enabled
62+
* @return void
5563
*/
56-
public function testReEncrypt()
64+
public function testReEncrypt():void
5765
{
5866
$testConfigPath1 = "test/correct_enc_value";
5967
$testConfigPath2 = "test/incorrect_enc_value";
6068
$testConfigPath3 = "test/empty_enc_value";
6169

62-
$initialMock = $this->createMock(Initial::class);
63-
64-
$initialMock->expects($this->any())
65-
->method('getMetadata')
66-
->willReturn([
67-
$testConfigPath1 => [
68-
"backendModel" => Encrypted::class
69-
],
70-
$testConfigPath2 => [
71-
"backendModel" => Encrypted::class
72-
],
73-
$testConfigPath3 => [
74-
"backendModel" => Encrypted::class
75-
]
76-
]);
77-
7870
$this->configResource->saveConfig(
7971
$testConfigPath1,
8072
$this->encryptor->encrypt("Encrypted Config Value")
@@ -97,10 +89,7 @@ public function testReEncrypt()
9789

9890
/** @var Handler $coreConfigDataReEncryptionHandler */
9991
$coreConfigDataReEncryptionHandler = Bootstrap::getObjectManager()->create(
100-
Handler::class,
101-
[
102-
"config" => $initialMock
103-
]
92+
Handler::class
10493
);
10594

10695
try {

0 commit comments

Comments
 (0)