Extra validatons on Schema Check

This commit is contained in:
Félix Suárez 2024-04-12 15:43:08 -06:00
parent 32755235e9
commit 8556401387
1 changed files with 252 additions and 28 deletions

View File

@ -50,10 +50,14 @@ function extension_db_status()
}
ui_print_info_message(
__('This extension checks the DB is correct. Because sometimes the old DB from a migration has not some fields in the tables or the data is changed.')
);
ui_print_info_message(
__('At the moment the checks is for MySQL/MariaDB.')
" - " .
__('This extension checks the DB is correct. Because sometimes the old DB from a migration has not some fields in the tables or the data is changed.') .
"<br>" .
" - " .
__('At the moment the checks is for MySQL/MariaDB.') .
"<br>" .
" - " .
__('User must have Select, Drop, Create and References privileges.')
);
echo "<form method='post' class='max_floating_element_size'>";
@ -164,6 +168,16 @@ function extension_db_status_execute_checks($db_user, $db_password, $db_host, $d
$db_name = explode(' ', $db_name);
$db_name = $db_name[0];
if (!$db_host) {
ui_print_error_message(__('A host must be provided'));
return;
}
if (!$db_name) {
ui_print_error_message(__('A DB name must be provided'));
return;
}
try {
if ($config['mysqli']) {
$connection_test = mysqli_connect($db_host, $db_user, $db_password);
@ -196,6 +210,10 @@ function extension_db_status_execute_checks($db_user, $db_password, $db_host, $d
return;
}
if (check_drop_privileges($connection_test) == 0) {
return;
}
try {
if ($config['mysqli']) {
$create_db = mysqli_query($connection_test, "CREATE DATABASE `$db_name`");
@ -211,10 +229,28 @@ function extension_db_status_execute_checks($db_user, $db_password, $db_host, $d
return;
}
if ($config['mysqli'] === true) {
mysqli_select_db($connection_test, $db_name);
} else {
mysql_select_db($db_name, $connection_test);
if (check_ref_privileges($connection_test) == 0) {
drop_database($connection_test, $db_name);
ui_print_error_message(__("Unable to <b>create references</b> with the provided user please check its privileges"));
return;
}
if (check_explain_privileges($connection_test) == 0) {
drop_database($connection_test, $db_name);
ui_print_error_message(__("Unable to <b>explain</b> with the provided user please check its privileges"));
return;
}
try {
if ($config['mysqli'] === true) {
mysqli_select_db($connection_test, $db_name);
} else {
mysql_select_db($db_name, $connection_test);
}
} catch (Exception $e) {
drop_database($connection_test, $db_name);
ui_print_error_message(__('There was an error selecting the DB'));
return;
}
$install_tables = extension_db_status_execute_sql_file(
@ -234,14 +270,7 @@ function extension_db_status_execute_checks($db_user, $db_password, $db_host, $d
$config['dbname']
);
if ($config['mysqli'] === true) {
mysqli_select_db($connection_test, $db_name);
mysqli_query($connection_test, "DROP DATABASE IF EXISTS `$db_name`");
} else {
mysql_select_db($db_name, $connection_test);
mysql_query("DROP DATABASE IF EXISTS `$db_name`", $connection_test);
}
drop_database($connection_test, $db_name);
}
@ -512,19 +541,15 @@ function extension_db_status_execute_sql_file($url, $connection)
$query .= $sql_line;
if (preg_match("/;[\040]*\$/", $sql_line)) {
if ($config['mysqli'] === true) {
if (!$result = mysqli_query($connection, $query)) {
echo mysqli_error();
// Uncomment for debug
echo "<i><br>$query<br></i>";
return 0;
}
$result = mysqli_query($connection, $query);
} else {
if (!$result = mysql_query($query, $connection)) {
echo mysql_error();
// Uncomment for debug
echo "<i><br>$query<br></i>";
return 0;
}
$result = mysql_query($query, $connection);
}
if (!$result) {
echo mysqli_error($connection);
// Uncomment for debug
echo "<i><br>$query<br></i>";
return 0;
}
$query = '';
@ -539,5 +564,204 @@ function extension_db_status_execute_sql_file($url, $connection)
}
function check_explain_privileges($connection)
{
global $config;
$has_privileges = 1;
$explain_check= "EXPLAIN tb1";
$create_tb1= "CREATE TABLE tb1 (
id INT AUTO_INCREMENT PRIMARY KEY
)";
drop_database($connection, 'pandora_tmp_privilege_check');
try {
if ($config['mysqli']) {
mysqli_query($connection, "CREATE DATABASE `pandora_tmp_privilege_check`");
} else {
mysql_query("CREATE DATABASE `pandora_tmp_privilege_check`", $connection);
}
} catch (Exception $e) {
ui_print_error_message(__('There was an error creating the DB during reference check'));
return 0;
}
try {
if ($config['mysqli'] === true) {
mysqli_select_db($connection, "pandora_tmp_privilege_check");
} else {
mysql_select_db("reference_check", $connection);
}
} catch (Exception $e) {
ui_print_error_message(__('There was an error selecting the DB during reference check'));
return 0;
}
try {
if ($config['mysqli'] === true) {
$result = mysqli_query($connection, $create_tb1);
} else {
$result = mysql_query($create_tb1, $connection);
}
if(!$result){
throw new Exception("Error on explain check: " . $connection->error);
}
if ($config['mysqli'] === true) {
$result = mysqli_query($connection, $explain_check);
} else {
$result = mysql_query($explain_check, $connection);
}
if(!$result){
throw new Exception("Error on explain check: " . $connection->error);
}
} catch (Exception $e) {
$has_privileges = 0;
} finally {
drop_database($connection, 'pandora_tmp_privilege_check');
return $has_privileges;
}
}
function check_drop_privileges($connection)
{
global $config;
$has_privileges = 1;
try {
if ($config['mysqli']) {
$create_db = mysqli_query($connection, "CREATE DATABASE IF NOT EXISTS`pandora_tmp_privilege_check`");
} else {
$create_db = mysql_query("CREATE DATABASE IF NOT EXISTS `pandora_tmp_privilege_check`", $connection);
}
} catch (Exception $e) {
$error_message = $e->getMessage();
}
if (!$create_db) {
if (stripos($error_message, "access denied for user") !== false) {
preg_match("/'.+?'\@'.+?'/", $error_message, $error_user);
$error_user = $error_user[0];
ui_print_error_message(__("Unable to <b>create databases</b> with the provided user please check its privileges"));
return 0;
}
ui_print_error_message(__('There was an error creating the DB during drop check'));
return 0;
}
try {
if ($config['mysqli'] === true) {
mysqli_select_db($connection, "pandora_tmp_privilege_check");
} else {
mysql_select_db("reference_check", $connection);
}
} catch (Exception $e) {
ui_print_error_message(__('There was an error selecting the DB during drop check'));
return 0;
}
try {
drop_database($connection, 'pandora_tmp_privilege_check');
} catch (Exception $e) {
$has_privileges = 0;
ui_print_error_message(
__("Unable to <b>drop databases</b> with the provided user please check its privileges.") .
"<br>" .
__("Test databases may have been left over due to lack of drop privileges.")
);
} finally {
return $has_privileges;
}
}
function check_ref_privileges($connection)
{
global $config;
$has_privileges = 1;
drop_database($connection, 'pandora_tmp_privilege_check');
$create_tb1= "CREATE TABLE tb1 (
id INT AUTO_INCREMENT PRIMARY KEY
)";
$create_tb2 = "CREATE TABLE tb2 (
id INT AUTO_INCREMENT PRIMARY KEY,
id_tb1 INT,
FOREIGN KEY (id_tb1) REFERENCES tb2(id)
)";
try {
if ($config['mysqli']) {
mysqli_query($connection, "CREATE DATABASE `pandora_tmp_privilege_check`");
} else {
mysql_query("CREATE DATABASE `pandora_tmp_privilege_check`", $connection);
}
} catch (Exception $e) {
ui_print_error_message(__('There was an error creating the DB during reference check'));
return 0;
}
try {
if ($config['mysqli'] === true) {
mysqli_select_db($connection, "pandora_tmp_privilege_check");
} else {
mysql_select_db("reference_check", $connection);
}
} catch (Exception $e) {
ui_print_error_message(__('There was an error selecting the DB during reference check'));
return 0;
}
try {
if ($config['mysqli'] === true) {
$result = mysqli_query($connection, $create_tb1);
} else {
$result = mysql_query($create_tb1, $connection);
}
if(!$result){
throw new Exception("Error on reference check: " . $connection->error);
}
if ($config['mysqli'] === true) {
$result = mysqli_query($connection, $create_tb2);
} else {
$result = mysql_query($create_tb2, $connection);
}
if(!$result){
throw new Exception("Error on reference check: " . $connection->error);
}
} catch (Exception $e) {
$has_privileges = 0;
} finally {
drop_database($connection, 'pandora_tmp_privilege_check');
return $has_privileges;
}
}
function drop_database($connection, $database)
{
global $config;
if ($config['mysqli'] === true) {
mysqli_query($connection, "DROP DATABASE IF EXISTS `$database`");
} else {
mysql_query("DROP DATABASE IF EXISTS `$database`", $connection);
}
}
extensions_add_godmode_function('extension_db_status');
extensions_add_godmode_menu_option(__('DB Schema check'), 'DM', 'gextensions', null, 'v1r1', 'gdbman');