UpgradeSchema.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. <?php
  2. /**
  3. * MageSpecialist
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to info@magespecialist.it so we can send you a copy immediately.
  14. *
  15. * @category MSP
  16. * @package MSP_TwoFactorAuth
  17. * @copyright Copyright (c) 2017 Skeeller srl (http://www.magespecialist.it)
  18. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  19. */
  20. namespace MSP\TwoFactorAuth\Setup;
  21. use Magento\Framework\DB\Adapter\AdapterInterface;
  22. use Magento\Framework\Json\DecoderInterface;
  23. use Magento\Framework\Json\EncoderInterface;
  24. use Magento\Framework\Setup\ModuleContextInterface;
  25. use Magento\Framework\Setup\SchemaSetupInterface;
  26. use Magento\Framework\DB\Ddl\Table;
  27. use Magento\Framework\Setup\UpgradeSchemaInterface;
  28. class UpgradeSchema implements UpgradeSchemaInterface
  29. {
  30. /**
  31. * @var EncoderInterface
  32. */
  33. private $encoder;
  34. /**
  35. * @var DecoderInterface
  36. */
  37. private $decoder;
  38. public function __construct(
  39. EncoderInterface $encoder,
  40. DecoderInterface $decoder
  41. ) {
  42. $this->encoder = $encoder;
  43. $this->decoder = $decoder;
  44. }
  45. private function upgradeTo010100(SchemaSetupInterface $setup)
  46. {
  47. $tableName = $setup->getTable('msp_tfa_trusted');
  48. $table = $setup->getConnection()
  49. ->newTable($tableName)
  50. ->addColumn(
  51. 'msp_tfa_trusted_id',
  52. Table::TYPE_INTEGER,
  53. null,
  54. ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
  55. 'Trusted device ID'
  56. )
  57. ->addColumn(
  58. 'date_time',
  59. Table::TYPE_DATETIME,
  60. null,
  61. ['nullable' => false],
  62. 'Date and time'
  63. )
  64. ->addColumn(
  65. 'user_id',
  66. Table::TYPE_INTEGER,
  67. null,
  68. ['nullable' => false, 'unsigned' => true],
  69. 'User ID'
  70. )
  71. ->addColumn(
  72. 'device_name',
  73. Table::TYPE_TEXT,
  74. null,
  75. ['nullable' => false],
  76. 'Device name'
  77. )
  78. ->addColumn(
  79. 'token',
  80. Table::TYPE_TEXT,
  81. null,
  82. ['nullable' => false],
  83. 'Token'
  84. )
  85. ->addColumn(
  86. 'last_ip',
  87. Table::TYPE_TEXT,
  88. null,
  89. ['nullable' => false],
  90. 'Last IP'
  91. )
  92. ->addForeignKey(
  93. $setup->getFkName(
  94. $setup->getTable('msp_tfa_trusted'),
  95. 'user_id',
  96. $setup->getTable('admin_user'),
  97. 'user_id'
  98. ),
  99. 'user_id',
  100. $setup->getTable('admin_user'),
  101. 'user_id',
  102. Table::ACTION_CASCADE
  103. );
  104. $setup->getConnection()->createTable($table);
  105. }
  106. private function upgradeTo010200(SchemaSetupInterface $setup)
  107. {
  108. $connection = $setup->getConnection();
  109. $adminUserTable = $setup->getTable('admin_user');
  110. $connection->changeColumn($adminUserTable, 'msp_tfa_enabled', 'msp_tfa_provider', [
  111. 'type' => Table::TYPE_TEXT,
  112. 'nullable' => true,
  113. 'comment' => 'Two Factor Authentication Provider',
  114. ]);
  115. $connection->changeColumn($adminUserTable, 'msp_tfa_secret', 'msp_tfa_config', [
  116. 'type' => Table::TYPE_TEXT,
  117. 'nullable' => true,
  118. 'comment' => 'Two Factor Authentication Config',
  119. ]);
  120. // Migrate information
  121. $connection->update($adminUserTable, [
  122. 'msp_tfa_provider' => 'none',
  123. ], 'msp_tfa_provider=0');
  124. $connection->update($adminUserTable, [
  125. 'msp_tfa_provider' => 'google'
  126. ], 'msp_tfa_provider=1');
  127. // @codingStandardsIgnoreStart
  128. $users = $connection->fetchAll($connection->select()->from($adminUserTable));
  129. foreach ($users as $user) {
  130. $tfaSecret = $user['msp_tfa_config'];
  131. if ($tfaSecret) {
  132. $connection->update($adminUserTable, ['msp_tfa_config' => $this->encoder->encode([
  133. 'google' => [
  134. 'secret' => $tfaSecret,
  135. ]
  136. ])], 'user_id=' . ((int) $user['user_id']));
  137. }
  138. }
  139. // @codingStandardsIgnoreEnd
  140. }
  141. private function upgradeTo020000(SchemaSetupInterface $setup)
  142. {
  143. $connection = $setup->getConnection();
  144. $tfaAdminUserTable = $setup->getTable('msp_tfa_user_config');
  145. $adminUserTable = $setup->getTable('admin_user');
  146. $table = $setup->getConnection()
  147. ->newTable($tfaAdminUserTable)
  148. ->addColumn(
  149. 'msp_tfa_user_config_id',
  150. Table::TYPE_INTEGER,
  151. null,
  152. ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
  153. 'TFA admin user ID'
  154. )
  155. ->addColumn(
  156. 'user_id',
  157. Table::TYPE_INTEGER,
  158. null,
  159. ['nullable' => false, 'unsigned' => true],
  160. 'User ID'
  161. )
  162. ->addColumn(
  163. 'encoded_providers',
  164. Table::TYPE_TEXT,
  165. null,
  166. ['nullable' => true],
  167. 'Encoded providers list'
  168. )
  169. ->addColumn(
  170. 'encoded_config',
  171. Table::TYPE_TEXT,
  172. null,
  173. ['nullable' => true],
  174. 'Encoded providers configuration'
  175. )
  176. ->addColumn(
  177. 'default_provider',
  178. Table::TYPE_TEXT,
  179. null,
  180. ['nullable' => true],
  181. 'Default provider'
  182. )
  183. ->addForeignKey(
  184. $setup->getFkName(
  185. $setup->getTable('msp_tfa_user_config'),
  186. 'user_id',
  187. $setup->getTable('admin_user'),
  188. 'user_id'
  189. ),
  190. 'user_id',
  191. $setup->getTable('admin_user'),
  192. 'user_id',
  193. Table::ACTION_CASCADE
  194. );
  195. $connection->createTable($table);
  196. // Migrate data from old configuration
  197. // @codingStandardsIgnoreStart
  198. $users = $connection->fetchAll($connection->select()->from($adminUserTable));
  199. foreach ($users as $user) {
  200. try {
  201. $providerConfig = $this->decoder->decode($user['msp_tfa_config']);
  202. if (isset($providerConfig[$user['msp_tfa_provider']])) {
  203. $providerConfig[$user['msp_tfa_provider']]['active'] = $user['msp_tfa_activated'];
  204. }
  205. } catch (\Exception $e) {
  206. $providerConfig = [];
  207. }
  208. $providerCode = $user['msp_tfa_provider'];
  209. if ($providerCode == 'none') {
  210. $providerCode = '';
  211. }
  212. $connection->insert($tfaAdminUserTable, [
  213. 'user_id' => $user['user_id'],
  214. 'encoded_config' => $this->encoder->encode($providerConfig),
  215. 'encoded_providers' => $this->encoder->encode([$providerCode]),
  216. ]);
  217. }
  218. // @codingStandardsIgnoreEnd
  219. $connection->dropColumn($adminUserTable, 'msp_tfa_provider');
  220. $connection->dropColumn($adminUserTable, 'msp_tfa_config');
  221. $connection->dropColumn($adminUserTable, 'msp_tfa_activated');
  222. }
  223. private function upgradeTo020001(SchemaSetupInterface $setup)
  224. {
  225. $connection = $setup->getConnection();
  226. $tableName = $setup->getTable('msp_tfa_country_codes');
  227. $table = $setup->getConnection()
  228. ->newTable($tableName)
  229. ->addColumn(
  230. 'msp_tfa_country_codes_id',
  231. Table::TYPE_INTEGER,
  232. null,
  233. ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
  234. 'TFA admin user ID'
  235. )
  236. ->addColumn(
  237. 'code',
  238. Table::TYPE_TEXT,
  239. null,
  240. ['nullable' => false],
  241. 'Country code'
  242. )
  243. ->addColumn(
  244. 'name',
  245. Table::TYPE_TEXT,
  246. null,
  247. ['nullable' => false],
  248. 'Country name'
  249. )
  250. ->addColumn(
  251. 'dial_code',
  252. Table::TYPE_TEXT,
  253. null,
  254. ['nullable' => false],
  255. 'Prefix'
  256. )
  257. ->addIndex(
  258. $setup->getIdxName(
  259. $tableName,
  260. ['code'],
  261. AdapterInterface::INDEX_TYPE_INDEX
  262. ),
  263. [['name' => 'code', 'size' => 128]],
  264. ['type' => AdapterInterface::INDEX_TYPE_INDEX]
  265. );
  266. $connection->createTable($table);
  267. }
  268. /**
  269. * Upgrades DB schema for a module
  270. *
  271. * @param SchemaSetupInterface $setup
  272. * @param ModuleContextInterface $context
  273. * @return void
  274. */
  275. public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
  276. {
  277. $setup->startSetup();
  278. if (version_compare($context->getVersion(), '1.1.0') < 0) {
  279. $this->upgradeTo010100($setup);
  280. }
  281. if (version_compare($context->getVersion(), '1.2.0') < 0) {
  282. $this->upgradeTo010200($setup);
  283. }
  284. if (version_compare($context->getVersion(), '2.0.0') < 0) {
  285. $this->upgradeTo020000($setup);
  286. }
  287. if (version_compare($context->getVersion(), '2.0.1') < 0) {
  288. $this->upgradeTo020001($setup);
  289. }
  290. $setup->endSetup();
  291. }
  292. }