PageRenderTime 40ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/magento/module-encryption-key/Model/ResourceModel/Key/Change.php

https://gitlab.com/yousafsyed/easternglamor
PHP | 204 lines | 106 code | 19 blank | 79 comment | 4 complexity | 16fe8a6ea8805717a001b47c8280087f MD5 | raw file
  1. <?php
  2. /**
  3. * Copyright © 2016 Magento. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\EncryptionKey\Model\ResourceModel\Key;
  7. use Magento\Framework\App\Filesystem\DirectoryList;
  8. use Magento\Framework\Config\ConfigOptionsListConstants;
  9. use Magento\Framework\Config\Data\ConfigData;
  10. use Magento\Framework\Config\File\ConfigFilePool;
  11. use Magento\Framework\App\ObjectManager;
  12. /**
  13. * Encryption key changer resource model
  14. * The operation must be done in one transaction
  15. */
  16. class Change extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
  17. {
  18. /**
  19. * Encryptor interface
  20. *
  21. * @var \Magento\Framework\Encryption\EncryptorInterface
  22. */
  23. protected $encryptor;
  24. /**
  25. * Filesystem directory write interface
  26. *
  27. * @var \Magento\Framework\Filesystem\Directory\WriteInterface
  28. */
  29. protected $directory;
  30. /**
  31. * System configuration structure
  32. *
  33. * @var \Magento\Config\Model\Config\Structure
  34. */
  35. protected $structure;
  36. /**
  37. * Configuration writer
  38. *
  39. * @var \Magento\Framework\App\DeploymentConfig\Writer
  40. */
  41. protected $writer;
  42. /**
  43. * Random
  44. *
  45. * @var \Magento\Framework\Math\Random
  46. */
  47. protected $random;
  48. /**
  49. * @param \Magento\Framework\Model\ResourceModel\Db\Context $context
  50. * @param \Magento\Framework\Filesystem $filesystem
  51. * @param \Magento\Config\Model\Config\Structure $structure
  52. * @param \Magento\Framework\Encryption\EncryptorInterface $encryptor
  53. * @param \Magento\Framework\App\DeploymentConfig\Writer $writer
  54. * @param string $connectionName
  55. */
  56. public function __construct(
  57. \Magento\Framework\Model\ResourceModel\Db\Context $context,
  58. \Magento\Framework\Filesystem $filesystem,
  59. \Magento\Config\Model\Config\Structure $structure,
  60. \Magento\Framework\Encryption\EncryptorInterface $encryptor,
  61. \Magento\Framework\App\DeploymentConfig\Writer $writer,
  62. $connectionName = null
  63. ) {
  64. $this->encryptor = clone $encryptor;
  65. parent::__construct($context, $connectionName);
  66. $this->directory = $filesystem->getDirectoryWrite(DirectoryList::CONFIG);
  67. $this->structure = $structure;
  68. $this->writer = $writer;
  69. }
  70. /**
  71. * Initialize
  72. *
  73. * @return void
  74. */
  75. protected function _construct()
  76. {
  77. $this->_init('core_config_data', 'config_id');
  78. }
  79. /**
  80. * Change encryption key
  81. *
  82. * @param string|null $key
  83. * @return null|string
  84. * @throws \Exception
  85. */
  86. public function changeEncryptionKey($key = null)
  87. {
  88. // prepare new key, encryptor and new configuration segment
  89. if (!$this->writer->checkIfWritable()) {
  90. throw new \Exception(__('Deployment configuration file is not writable.'));
  91. }
  92. if (null === $key) {
  93. $key = md5($this->getRandom()->getRandomString(ConfigOptionsListConstants::STORE_KEY_RANDOM_STRING_SIZE));
  94. }
  95. $this->encryptor->setNewKey($key);
  96. $encryptSegment = new ConfigData(ConfigFilePool::APP_ENV);
  97. $encryptSegment->set(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY, $this->encryptor->exportKeys());
  98. $configData = [$encryptSegment->getFileKey() => $encryptSegment->getData()];
  99. // update database and config.php
  100. $this->beginTransaction();
  101. try {
  102. $this->_reEncryptSystemConfigurationValues();
  103. $this->_reEncryptCreditCardNumbers();
  104. $this->writer->saveConfig($configData);
  105. $this->commit();
  106. return $key;
  107. } catch (\Exception $e) {
  108. $this->rollBack();
  109. throw $e;
  110. }
  111. }
  112. /**
  113. * Get Math Random
  114. *
  115. * @return \Magento\Framework\Math\Random
  116. */
  117. public function getRandom()
  118. {
  119. if (!$this->random) {
  120. $this->random = ObjectManager::getInstance()->get('\Magento\Framework\Math\Random');
  121. }
  122. return $this->random;
  123. }
  124. /**
  125. * Set Random
  126. *
  127. * @param \Magento\Framework\Math\Random $random
  128. */
  129. public function setRandom(\Magento\Framework\Math\Random $random)
  130. {
  131. $this->random = $random;
  132. }
  133. /**
  134. * Gather all encrypted system config values and re-encrypt them
  135. *
  136. * @return void
  137. */
  138. protected function _reEncryptSystemConfigurationValues()
  139. {
  140. // look for encrypted node entries in all system.xml files
  141. /** @var \Magento\Config\Model\Config\Structure $configStructure */
  142. $configStructure = $this->structure;
  143. $paths = $configStructure->getFieldPathsByAttribute(
  144. 'backend_model',
  145. 'Magento\Config\Model\Config\Backend\Encrypted'
  146. );
  147. // walk through found data and re-encrypt it
  148. if ($paths) {
  149. $table = $this->getTable('core_config_data');
  150. $values = $this->getConnection()->fetchPairs(
  151. $this->getConnection()
  152. ->select()
  153. ->from($table, ['config_id', 'value'])
  154. ->where('path IN (?)', $paths)
  155. ->where('value NOT LIKE ?', '')
  156. );
  157. foreach ($values as $configId => $value) {
  158. $this->getConnection()->update(
  159. $table,
  160. ['value' => $this->encryptor->encrypt($this->encryptor->decrypt($value))],
  161. ['config_id = ?' => (int)$configId]
  162. );
  163. }
  164. }
  165. }
  166. /**
  167. * Gather saved credit card numbers from sales order payments and re-encrypt them
  168. *
  169. * @return void
  170. */
  171. protected function _reEncryptCreditCardNumbers()
  172. {
  173. $table = $this->getTable('sales_order_payment');
  174. $select = $this->getConnection()->select()->from($table, ['entity_id', 'cc_number_enc']);
  175. $attributeValues = $this->getConnection()->fetchPairs($select);
  176. // save new values
  177. foreach ($attributeValues as $valueId => $value) {
  178. $this->getConnection()->update(
  179. $table,
  180. ['cc_number_enc' => $this->encryptor->encrypt($this->encryptor->decrypt($value))],
  181. ['entity_id = ?' => (int)$valueId]
  182. );
  183. }
  184. }
  185. }