Files
opensourcepos/app/Database/Migrations/20220127000000_convert_to_ci4.php
objecttothis 8a1e4b2083 Convert encryption to CI4
- automatic upgrade of encryption key.
- automatic decryption of CI3 data, then re-encryption in CI4 and update of table.
- Fixing save function in app_config model
2023-04-27 21:54:11 -04:00

132 lines
2.8 KiB
PHP

<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Forge;
use CodeIgniter\Database\Migration;
use CodeIgniter\Router\Exceptions\RedirectException;
use Config\Encryption;
use Config\Services;
class Convert_to_ci4 extends Migration
{
public function __construct(?Forge $forge = null)
{
parent::__construct($forge);
helper('security');
}
public function up(): void
{
error_log('Migrating database to CodeIgniter4 formats');
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.4.0_ci4_conversion.sql');
if(!empty(config('Encryption')->key))
{
$this->convert_ci3_encrypted_data();
}
else
{
check_encryption();
}
error_log('Migrating to CodeIgniter4 formats completed');
}
public function down(): void
{
}
private function convert_ci3_encrypted_data()
{
$appconfig = model('Appconfig');
$ci3_encrypted_data = [
'clcdesq_api_key' => '',
'clcdesq_api_url' => '',
'mailchimp_api_key' => '',
'mailchimp_list_id' => '',
'smtp_pass' => ''
];
foreach($ci3_encrypted_data as $key => $value)
{
$ci3_encrypted_data[$key] = $appconfig->get_value($key);
}
$decrypted_data = $this->decrypt_ci3_data($ci3_encrypted_data);
check_encryption();
try
{
$ci4_encrypted_data = $this->encrypt_data($decrypted_data);
$success = empty(array_diff_assoc($decrypted_data, $this->decrypt_data($ci4_encrypted_data)));
if(!$success)
{
abort_encryption_conversion();
throw new RedirectException('login');
}
$appconfig->batch_save($ci4_encrypted_data);
} catch(RedirectException $e)
{
return redirect()->to('login'); //TODO: Need to figure out how to pass the error to the Login controller so that it gets displayed.
}
}
/**
* @return void
*/
private function decrypt_ci3_data(array $encrypted_data): array
{
$config = new Encryption();
$config->driver = 'OpenSSL';
$config->key = config('Encryption')->key;
$config->cipher = 'AES-128-CBC';
$config->rawData = false;
$config->encryptKeyInfo = 'encryption';
$config->authKeyInfo = 'authentication';
$encrypter = Services::encrypter($config);
$decrypted_data = [];
foreach($encrypted_data as $key => $value)
{
$decrypted_data[$key] = !empty($value) ? $encrypter->decrypt($value): '';
}
return $decrypted_data;
}
private function encrypt_data(array $plain_data): array
{
$encrypter = Services::encrypter();
$encrypted_data = [];
foreach($plain_data as $key => $value)
{
$encrypted_data[$key] = !empty($value) ? $encrypter->encrypt($value) : '';
}
return $encrypted_data;
}
private function decrypt_data(array $encrypted_data): array
{
$encrypter = Services::encrypter();
$decrypted_data = [];
foreach($encrypted_data as $key => $value)
{
$decrypted_data[$key] = !empty($value) ? $encrypter->decrypt($value) : '';
}
return $decrypted_data;
}
}