123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- declare(strict_types=1);
- namespace Magento\EncryptionKey\Setup\Patch\Data;
- use Magento\Framework\Setup\Patch\DataPatchInterface;
- use Magento\Framework\App\ObjectManager;
- /**
- * Migrate encrypted configuration values to the latest cipher
- */
- class SodiumChachaPatch implements DataPatchInterface
- {
- /**
- * @var \Magento\Framework\Config\ScopeInterface
- */
- private $scope;
- /**
- * @var \Magento\Framework\Setup\ModuleDataSetupInterface
- */
- private $moduleDataSetup;
- /**
- * @var \Magento\Config\Model\Config\Structure
- */
- private $structure;
- /**
- * @var \Magento\Framework\Encryption\EncryptorInterface
- */
- private $encryptor;
- /**
- * @var \Magento\Framework\App\State
- */
- private $state;
- /**
- * SodiumChachaPatch constructor.
- * @param \Magento\Framework\Setup\ModuleDataSetupInterface $moduleDataSetup
- * @param \Magento\Config\Model\Config\Structure\Proxy $structure
- * @param \Magento\Framework\Encryption\EncryptorInterface $encryptor
- * @param \Magento\Framework\App\State $state
- * @param \Magento\Framework\Config\ScopeInterface|null $scope
- */
- public function __construct(
- \Magento\Framework\Setup\ModuleDataSetupInterface $moduleDataSetup,
- \Magento\Config\Model\Config\Structure\Proxy $structure,
- \Magento\Framework\Encryption\EncryptorInterface $encryptor,
- \Magento\Framework\App\State $state,
- \Magento\Framework\Config\ScopeInterface $scope = null
- ) {
- $this->moduleDataSetup = $moduleDataSetup;
- $this->structure = $structure;
- $this->encryptor = $encryptor;
- $this->state = $state;
- $this->scope = $scope ?? ObjectManager::getInstance()->get(\Magento\Framework\Config\ScopeInterface::class);
- }
- /**
- * @inheritdoc
- */
- public function apply()
- {
- $this->moduleDataSetup->startSetup();
- $this->reEncryptSystemConfigurationValues();
- $this->moduleDataSetup->endSetup();
- }
- /**
- * @inheritdoc
- */
- public static function getDependencies()
- {
- return [];
- }
- /**
- * @inheritdoc
- */
- public function getAliases()
- {
- return [];
- }
- /**
- * Re encrypt sensitive data in the system configuration
- */
- private function reEncryptSystemConfigurationValues()
- {
- $table = $this->moduleDataSetup->getTable('core_config_data');
- $hasEncryptedData = $this->moduleDataSetup->getConnection()->fetchOne(
- $this->moduleDataSetup->getConnection()
- ->select()
- ->from($table, [new \Zend_Db_Expr('count(value)')])
- ->where('value LIKE ?', '0:2%')
- );
- if ($hasEncryptedData !== '0') {
- $currentScope = $this->scope->getCurrentScope();
- $structure = $this->structure;
- $paths = $this->state->emulateAreaCode(
- \Magento\Framework\App\Area::AREA_ADMINHTML,
- function () use ($structure) {
- $this->scope->setCurrentScope(\Magento\Framework\App\Area::AREA_ADMINHTML);
- /** Returns list of structure paths to be re encrypted */
- $paths = $structure->getFieldPathsByAttribute(
- 'backend_model',
- \Magento\Config\Model\Config\Backend\Encrypted::class
- );
- /** Returns list of mapping between configPath => [structurePaths] */
- $mappedPaths = $structure->getFieldPaths();
- foreach ($mappedPaths as $mappedPath => $data) {
- foreach ($data as $structurePath) {
- if ($structurePath !== $mappedPath && $key = array_search($structurePath, $paths)) {
- $paths[$key] = $mappedPath;
- }
- }
- }
- return array_unique($paths);
- }
- );
- $this->scope->setCurrentScope($currentScope);
- // walk through found data and re-encrypt it
- if ($paths) {
- $values = $this->moduleDataSetup->getConnection()->fetchPairs(
- $this->moduleDataSetup->getConnection()
- ->select()
- ->from($table, ['config_id', 'value'])
- ->where('path IN (?)', $paths)
- ->where('value NOT LIKE ?', '')
- );
- foreach ($values as $configId => $value) {
- $this->moduleDataSetup->getConnection()->update(
- $table,
- ['value' => $this->encryptor->encrypt($this->encryptor->decrypt($value))],
- ['config_id = ?' => (int)$configId]
- );
- }
- }
- }
- }
- }
|