8
8
namespace Magento \EncryptionKey \Setup \Patch \Data ;
9
9
10
10
use Magento \Framework \Setup \Patch \DataPatchInterface ;
11
+ use Magento \Framework \App \ObjectManager ;
11
12
12
13
/**
13
14
* Migrate encrypted configuration values to the latest cipher
14
15
*/
15
16
class SodiumChachaPatch implements DataPatchInterface
16
17
{
18
+ /**
19
+ * @var \Magento\Framework\Config\ScopeInterface
20
+ */
21
+ private $ scope ;
22
+
17
23
/**
18
24
* @var \Magento\Framework\Setup\ModuleDataSetupInterface
19
25
*/
@@ -35,25 +41,29 @@ class SodiumChachaPatch implements DataPatchInterface
35
41
private $ state ;
36
42
37
43
/**
44
+ * SodiumChachaPatch constructor.
38
45
* @param \Magento\Framework\Setup\ModuleDataSetupInterface $moduleDataSetup
39
46
* @param \Magento\Config\Model\Config\Structure\Proxy $structure
40
47
* @param \Magento\Framework\Encryption\EncryptorInterface $encryptor
41
48
* @param \Magento\Framework\App\State $state
49
+ * @param \Magento\Framework\Config\ScopeInterface|null $scope
42
50
*/
43
51
public function __construct (
44
52
\Magento \Framework \Setup \ModuleDataSetupInterface $ moduleDataSetup ,
45
53
\Magento \Config \Model \Config \Structure \Proxy $ structure ,
46
54
\Magento \Framework \Encryption \EncryptorInterface $ encryptor ,
47
- \Magento \Framework \App \State $ state
55
+ \Magento \Framework \App \State $ state ,
56
+ \Magento \Framework \Config \ScopeInterface $ scope = null
48
57
) {
49
58
$ this ->moduleDataSetup = $ moduleDataSetup ;
50
59
$ this ->structure = $ structure ;
51
60
$ this ->encryptor = $ encryptor ;
52
61
$ this ->state = $ state ;
62
+ $ this ->scope = $ scope ?? ObjectManager::getInstance ()->get (\Magento \Framework \Config \ScopeInterface::class);
53
63
}
54
64
55
65
/**
56
- * { @inheritdoc}
66
+ * @inheritdoc
57
67
*/
58
68
public function apply ()
59
69
{
@@ -65,49 +75,75 @@ public function apply()
65
75
}
66
76
67
77
/**
68
- * { @inheritdoc}
78
+ * @inheritdoc
69
79
*/
70
80
public static function getDependencies ()
71
81
{
72
82
return [];
73
83
}
74
84
75
85
/**
76
- * { @inheritdoc}
86
+ * @inheritdoc
77
87
*/
78
88
public function getAliases ()
79
89
{
80
90
return [];
81
91
}
82
92
93
+ /**
94
+ * Re encrypt sensitive data in the system configuration
95
+ */
83
96
private function reEncryptSystemConfigurationValues ()
84
97
{
85
- $ structure = $ this ->structure ;
86
- $ paths = $ this ->state ->emulateAreaCode (
87
- \Magento \Framework \App \Area::AREA_ADMINHTML ,
88
- function () use ($ structure ) {
89
- return $ structure ->getFieldPathsByAttribute (
90
- 'backend_model ' ,
91
- \Magento \Config \Model \Config \Backend \Encrypted::class
92
- );
93
- }
98
+ $ table = $ this ->moduleDataSetup ->getTable ('core_config_data ' );
99
+ $ hasEncryptedData = $ this ->moduleDataSetup ->getConnection ()->fetchOne (
100
+ $ this ->moduleDataSetup ->getConnection ()
101
+ ->select ()
102
+ ->from ($ table , [new \Zend_Db_Expr ('count(value) ' )])
103
+ ->where ('value LIKE ? ' , '0:2% ' )
94
104
);
95
- // walk through found data and re-encrypt it
96
- if ($ paths ) {
97
- $ table = $ this ->moduleDataSetup ->getTable ('core_config_data ' );
98
- $ values = $ this ->moduleDataSetup ->getConnection ()->fetchPairs (
99
- $ this ->moduleDataSetup ->getConnection ()
100
- ->select ()
101
- ->from ($ table , ['config_id ' , 'value ' ])
102
- ->where ('path IN (?) ' , $ paths )
103
- ->where ('value NOT LIKE ? ' , '' )
105
+ if ($ hasEncryptedData !== '0 ' ) {
106
+ $ currentScope = $ this ->scope ->getCurrentScope ();
107
+ $ structure = $ this ->structure ;
108
+ $ paths = $ this ->state ->emulateAreaCode (
109
+ \Magento \Framework \App \Area::AREA_ADMINHTML ,
110
+ function () use ($ structure ) {
111
+ $ this ->scope ->setCurrentScope (\Magento \Framework \App \Area::AREA_ADMINHTML );
112
+ /** Returns list of structure paths to be re encrypted */
113
+ $ paths = $ structure ->getFieldPathsByAttribute (
114
+ 'backend_model ' ,
115
+ \Magento \Config \Model \Config \Backend \Encrypted::class
116
+ );
117
+ /** Returns list of mapping between configPath => [structurePaths] */
118
+ $ mappedPaths = $ structure ->getFieldPaths ();
119
+ foreach ($ mappedPaths as $ mappedPath => $ data ) {
120
+ foreach ($ data as $ structurePath ) {
121
+ if ($ structurePath !== $ mappedPath && $ key = array_search ($ structurePath , $ paths )) {
122
+ $ paths [$ key ] = $ mappedPath ;
123
+ }
124
+ }
125
+ }
126
+
127
+ return array_unique ($ paths );
128
+ }
104
129
);
105
- foreach ($ values as $ configId => $ value ) {
106
- $ this ->moduleDataSetup ->getConnection ()->update (
107
- $ table ,
108
- ['value ' => $ this ->encryptor ->encrypt ($ this ->encryptor ->decrypt ($ value ))],
109
- ['config_id = ? ' => (int )$ configId ]
130
+ $ this ->scope ->setCurrentScope ($ currentScope );
131
+ // walk through found data and re-encrypt it
132
+ if ($ paths ) {
133
+ $ values = $ this ->moduleDataSetup ->getConnection ()->fetchPairs (
134
+ $ this ->moduleDataSetup ->getConnection ()
135
+ ->select ()
136
+ ->from ($ table , ['config_id ' , 'value ' ])
137
+ ->where ('path IN (?) ' , $ paths )
138
+ ->where ('value NOT LIKE ? ' , '' )
110
139
);
140
+ foreach ($ values as $ configId => $ value ) {
141
+ $ this ->moduleDataSetup ->getConnection ()->update (
142
+ $ table ,
143
+ ['value ' => $ this ->encryptor ->encrypt ($ this ->encryptor ->decrypt ($ value ))],
144
+ ['config_id = ? ' => (int )$ configId ]
145
+ );
146
+ }
111
147
}
112
148
}
113
149
}
0 commit comments