pandorafms/pandora_console/godmode/wizards/ManageExtensions.class.php

1178 lines
38 KiB
PHP

<?php
/**
* Manage Extensions wizard for Pandora FMS Discovery
*
* @category Wizard
* @package Pandora FMS
* @subpackage ManageExtensions
* @version 1.0.0
* @license See below
*
* ______ ___ _______ _______ ________
* | __ \.-----.--.--.--| |.-----.----.-----. | ___| | | __|
* | __/| _ | | _ || _ | _| _ | | ___| |__ |
* |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______|
*
* ============================================================================
* Copyright (c) 2007-2021 Artica Soluciones Tecnologicas, http://www.artica.es
* This code is NOT free software. This code is NOT licenced under GPL2 licence
* You cannnot redistribute it without written permission of copyright holder.
* ============================================================================
*/
use PandoraFMS\Tools\Files;
require_once $config['homedir'].'/include/class/ExtensionsDiscovery.class.php';
/**
* Manage interface for upload new extensions in discovery.
*/
class ManageExtensions extends HTML
{
/**
* Allowed methods to be called using AJAX request.
*
* @var array
*/
public $AJAXMethods = [
'getExtensionsInstalled',
'validateIniName',
'loadMigrateModal',
'migrateApp',
];
/**
* Url of controller.
*
* @var string
*/
public $ajaxController;
/**
* Icon of section
*
* @var string
*/
public $icon = '/images/wizard/Configurar_app@svg.svg';
/**
* Name of section
*
* @var string
*/
public $label = 'Manage disco packages';
/**
* Url of section
*
* @var string
*/
public $url;
/**
* Path of the installation extension.
*
* @var string
*/
public $path = 'attachment/discovery';
/**
* Ini file from extension.
*
* @var array
*/
public $iniFile;
/**
* Default logo
*
* @var string
*/
public $defaultLogo = '/images/wizard/app_generico.svg';
/**
* Constructor
*/
public function __construct()
{
global $config;
$this->ajaxController = $config['homedir'].'/include/ajax/manage_extensions.ajax';
$this->url = ui_get_full_url(
'index.php?sec=gservers&sec2=godmode/servers/discovery&wiz=magextensions'
);
}
/**
* Checks if target method is available to be called using AJAX.
*
* @param string $method Target method.
*
* @return boolean True allowed, false not.
*/
public function ajaxMethod($method)
{
// Check access.
check_login();
return in_array($method, $this->AJAXMethods);
}
/**
* Implements load method.
*
* @return mixed Skeleton for button.
*/
public function load()
{
return [
'icon' => $this->icon,
'label' => __($this->label),
'url' => $this->url,
];
}
/**
* Generates a JSON error.
*
* @param string $msg Error message.
*
* @return void
*/
public function errorAjax(string $msg)
{
echo json_encode(
['error' => $msg]
);
}
/**
* Implements run method.
*
* @return void
*/
public function run()
{
global $config;
if (! check_acl($config['id_user'], 0, 'AR')) {
db_pandora_audit(
AUDIT_LOG_ACL_VIOLATION,
'Trying to access Manage disco packages'
);
include 'general/noaccess.php';
return;
}
// Load styles.
parent::run();
$uploadDisco = get_parameter('upload_disco', '');
$action = get_parameter('action', '');
$shortName = get_parameter('short_name', '');
if (empty($uploadDisco) === false) {
if ($_FILES['file']['error'] == 0) {
$result = $this->uploadExtension($_FILES['file']);
if ($result === true) {
ui_print_success_message(
__('Uploaded extension')
);
} else {
if (is_string($result)) {
echo $this->error($result);
} else {
echo $this->error(__('Failed to upload extension'));
}
}
} else {
echo $this->error(__('Failed to upload extension'));
}
}
if (empty($action) === false && empty($shortName) === false) {
switch ($action) {
case 'delete':
$result = $this->uninstallExtension($shortName);
if ($result === true) {
ui_print_success_message(
__('Deleted extension')
);
} else {
echo $this->error(__('Fail delete extension'));
}
case 'sync_server':
$syncAction = get_parameter('sync_action', '');
if ($syncAction === 'refresh') {
$installationFolder = $config['homedir'].'/'.$this->path.'/'.$shortName;
$result = $this->copyExtensionToServer($installationFolder, $shortName);
if ($result === true) {
ui_print_success_message(
__('Extension folder created successfully')
);
} else {
echo $this->error(__('Fail created extension folder'));
}
}
break;
default:
// Nothing.
break;
}
}
// Check config migrated apps and create it if neccesary.
$migratedAppsJson = db_get_value('value', 'tconfig', 'token', 'migrated_discovery_apps');
if ($migratedAppsJson === false || empty($migratedAppsJson) === true) {
// If does't exists it means is not migrated yet, insert it.
$migratedApps = [
'pandorafms.vmware' => 0,
'pandorafms.mysql' => 0,
'pandorafms.mssql' => 0,
'pandorafms.oracle' => 0,
'pandorafms.db2' => 0,
'pandorafms.sap.deset' => 0,
'pandorafms.gcp.ce' => 0,
'pandorafms.aws.ec2' => 0,
'pandorafms.aws.s3' => 0,
'pandorafms.aws.rds' => 0,
'pandorafms.azure.mc' => 0,
];
$migratedAppsJson = json_encode($migratedApps);
if (json_last_error() === JSON_ERROR_NONE) {
config_create_value(
'migrated_discovery_apps',
io_safe_input($migratedAppsJson)
);
}
}
$this->prepareBreadcrum(
[
[
'link' => ui_get_full_url(
'index.php?sec=gservers&sec2=godmode/servers/discovery'
),
'label' => __('Discovery'),
],
[
'link' => '',
'label' => _('Manage disco packages'),
'selected' => 1,
],
]
);
// Header.
ui_print_page_header(
__('Manage disco packages'),
'',
false,
'',
true,
'',
false,
'',
GENERIC_SIZE_TEXT,
'',
$this->printHeader(true)
);
if ((bool) check_acl($config['id_user'], 0, 'AW') === true) {
$table = new stdClass();
$table->width = '100%';
$table->class = 'databox filters';
$table->size = [];
$table->size[0] = '80%';
$table->align[3] = 'right';
$table->data = [];
$table->data[0][0] = html_print_label_input_block(
__('Load DISCO'),
html_print_div(
[
'id' => 'upload_file',
'content' => html_print_input_file(
'file',
true,
['style' => 'width:100%']
),
'class' => 'mrgn_top_15px',
],
true
)
);
$table->data[0][3] = html_print_submit_button(
__('Upload DISCO'),
'upload_button',
false,
[
'class' => 'sub ok float-right',
'icon' => 'next',
],
true
);
echo '<form id="uploadExtension" enctype="multipart/form-data" action="index.php?sec=gservers&sec2=godmode/servers/discovery&wiz=magextensions" method="POST">';
html_print_input_hidden('upload_disco', 1);
html_print_table($table);
// Auxiliar div ant string for migrate modal.
$modal = '<div id="migrate_modal" class="invisible"></div>';
$modal .= '<div class="invisible" id="msg"></div>';
echo $modal;
echo '<div class="action-buttons w700px">';
echo '</div>';
echo '</form>';
}
echo '<script type="text/javascript">
var page = "'.$this->ajaxController.'";
var textsToTranslate = {
"Warning": "'.__('Warning').'",
"Confirm": "'.__('Confirm').'",
"Cancel": "'.__('Cancel').'",
"Error": "'.__('Error').'",
"Ok": "'.__('Ok').'",
"Failed to upload extension": "'.__('Failed to upload extension').'",
"Migrate": "'.__('Migrate').'",
"migrationSuccess": "'.__('Migration Suceeded').'",
};
var url = "'.ui_get_full_url('ajax.php', false, false, false).'";
</script>';
ui_require_javascript_file('manage_extensions');
try {
$columns = [
'name',
'short_name',
'section',
'description',
'version',
[
'text' => 'actions',
'class' => 'flex flex-items-center',
],
];
$columnNames = [
__('Name'),
__('Short name'),
__('Section'),
__('Description'),
__('Version'),
__('Actions'),
];
// Load datatables user interface.
ui_print_datatable(
[
'id' => 'list_extensions',
'class' => 'info_table discovery-list-extensions',
'style' => 'width: 99%',
'dom_elements' => 'plfti',
'filter_main_class' => 'box-flat white_table_graph fixed_filter_bar',
'columns' => $columns,
'column_names' => $columnNames,
'ajax_url' => $this->ajaxController,
'ajax_data' => ['method' => 'getExtensionsInstalled'],
'no_sortable_columns' => [-1],
'order' => [
'field' => 'name',
'direction' => 'asc',
],
'search_button_class' => 'sub filter float-right',
]
);
} catch (Exception $e) {
echo $e->getMessage();
}
}
/**
* Upload extension to server.
*
* @param array $disco File disco tu upload.
*
* @return boolean $result Of operation, true if is ok.
*/
private function uploadExtension($disco)
{
global $config;
if (substr($disco['name'], -6) !== '.disco') {
return false;
}
$nameFile = str_replace('.disco', '.zip', $disco['name']);
$nameTempDir = $config['attachment_store'].'/downloads/';
if (file_exists($nameTempDir) === false) {
mkdir($nameTempDir);
}
$tmpPath = Files::tempdirnam(
$nameTempDir,
'extensions_uploaded_'
);
$result = move_uploaded_file($disco['tmp_name'], $tmpPath.'/'.$nameFile);
if ($result === true) {
$unzip = $this->unZip($tmpPath.'/'.$nameFile, $tmpPath);
if ($unzip === true) {
unlink($tmpPath.'/'.$nameFile);
db_process_sql_begin();
$this->iniFile = parse_ini_file($tmpPath.'/discovery_definition.ini', true, INI_SCANNER_TYPED);
if ($this->iniFile === false) {
db_process_sql_rollback();
Files::rmrf($tmpPath);
return __('Failed to upload extension: Error while parsing dicovery_definition.ini');
}
$error = ExtensionsDiscovery::validateIni($this->iniFile);
if ($error !== false) {
db_process_sql_rollback();
Files::rmrf($tmpPath);
return $error;
}
$id = $this->installExtension();
if ($id === false) {
db_process_sql_rollback();
Files::rmrf($tmpPath);
return false;
}
$result = $this->autoLoadConfigExec($id);
if ($result === false) {
db_process_sql_rollback();
Files::rmrf($tmpPath);
return false;
}
$result = $this->autoUpdateDefaultMacros($id);
if ($result === false) {
db_process_sql_rollback();
Files::rmrf($tmpPath);
return false;
}
$nameFolder = $this->iniFile['discovery_extension_definition']['short_name'];
$installationFolder = $config['homedir'].'/'.$this->path.'/'.$nameFolder;
if (file_exists($installationFolder) === false) {
mkdir($installationFolder, 0777, true);
} else {
Files::rmrf($installationFolder, true);
}
$result = Files::move($tmpPath, $installationFolder, true);
if ($result === false) {
db_process_sql_rollback();
Files::rmrf($tmpPath);
return false;
}
$this->setPermissionfiles($installationFolder, $this->iniFile['discovery_extension_definition']['execution_file']);
$this->setPermissionfiles(
$installationFolder,
[
$this->iniFile['discovery_extension_definition']['passencrypt_script'],
$this->iniFile['discovery_extension_definition']['passdecrypt_script'],
]
);
$result = $this->copyExtensionToServer($installationFolder, $nameFolder);
if ($result === false) {
db_process_sql_rollback();
Files::rmrf($tmpPath);
return false;
}
Files::rmrf($tmpPath);
db_process_sql_commit();
return true;
}
} else {
Files::rmrf($tmpPath);
return false;
}
}
/**
* Copy the extension folder into remote path server.
*
* @param string $path Path extension folder.
* @param string $nameFolder Name of extension folder.
*
* @return boolean Result of operation.
*/
public function copyExtensionToServer($path, $nameFolder)
{
global $config;
$filesToExclude = [
'discovery_definition.ini',
'logo.png',
];
$serverPath = $config['remote_config'].'/discovery/'.$nameFolder;
if (file_exists($serverPath) === false) {
mkdir($serverPath, 0777, true);
} else {
Files::rmrf($serverPath, true);
}
$result = $this->copyFolder($path, $serverPath, $filesToExclude);
$this->setPermissionfiles($serverPath, $this->iniFile['discovery_extension_definition']['execution_file']);
return $result;
}
/**
* Copy from $source path to $destination
*
* @param string $source Initial folder path.
* @param string $destination Destination folder path.
* @param array $exclude Files to exlcude in copy.
*
* @return boolean Result of operation.
*/
public function copyFolder($source, $destination, $exclude=[])
{
if (file_exists($destination) === false) {
mkdir($destination, 0777, true);
}
$files = scandir($source);
foreach ($files as $file) {
if ($file !== '.' && $file !== '..') {
if (is_dir($source.'/'.$file)) {
$result = $this->copyFolder($source.'/'.$file, $destination.'/'.$file);
if ($result === false) {
return false;
}
} else {
if (in_array($file, $exclude) === false) {
$result = copy($source.'/'.$file, $destination.'/'.$file);
if ($result === false) {
return false;
}
}
}
}
}
return true;
}
/**
* Delete extension from database and delete folder
*
* @param integer $shortName Short name app for delete.
*
* @return boolean Result of operation.
*/
private function uninstallExtension($shortName)
{
global $config;
$result = db_process_sql_delete(
'tdiscovery_apps',
['short_name' => $shortName]
);
if ($result !== false) {
Files::rmrf($config['homedir'].'/'.$this->path.'/'.$shortName);
Files::rmrf($config['remote_config'].'/discovery/'.$shortName);
return true;
} else {
return false;
}
}
/**
* Load the basic information of the app into database.
*
* @return boolean Result of query.
*/
private function installExtension()
{
$exist = db_get_row_filter(
'tdiscovery_apps',
[
'short_name' => $this->iniFile['discovery_extension_definition']['short_name'],
]
);
$version = $this->iniFile['discovery_extension_definition']['version'];
if ($version === null) {
$version = '';
}
$description = $this->iniFile['discovery_extension_definition']['description'];
if ($description === null) {
$description = '';
}
if ($exist === false) {
return db_process_sql_insert(
'tdiscovery_apps',
[
'short_name' => $this->iniFile['discovery_extension_definition']['short_name'],
'name' => io_safe_input($this->iniFile['discovery_extension_definition']['name']),
'description' => io_safe_input($description),
'section' => $this->iniFile['discovery_extension_definition']['section'],
'version' => $version,
]
);
} else {
$result = db_process_sql_update(
'tdiscovery_apps',
[
'name' => io_safe_input($this->iniFile['discovery_extension_definition']['name']),
'description' => io_safe_input($description),
'section' => $this->iniFile['discovery_extension_definition']['section'],
'version' => $version,
],
[
'short_name' => $this->iniFile['discovery_extension_definition']['short_name'],
]
);
if ($result !== false) {
return $exist['id_app'];
}
}
}
/**
* Return all extension installed by ajax.
*
* @return void
*/
public function getExtensionsInstalled()
{
global $config;
$data = [];
$start = get_parameter('start', 0);
$length = get_parameter('length', $config['block_size']);
$orderDatatable = get_datatable_order(true);
$pagination = '';
$order = '';
try {
ob_start();
if (isset($orderDatatable)) {
$order = sprintf(
' ORDER BY %s %s',
$orderDatatable['field'],
$orderDatatable['direction']
);
}
if (isset($length) && $length > 0
&& isset($start) && $start >= 0
) {
$pagination = sprintf(
' LIMIT %d OFFSET %d ',
$length,
$start
);
}
$sql = sprintf(
'SELECT short_name, name, section, description, version
FROM tdiscovery_apps
%s %s',
$order,
$pagination
);
$data = db_get_all_rows_sql($sql);
$sqlCount = sprintf(
'SELECT short_name, name, section, description, version
FROM tdiscovery_apps
%s',
$order,
);
$appsMetadata = self::loadDiscoveryAppsMetadata();
$flattenMetadata = array_merge(...array_values($appsMetadata));
$count = db_get_num_rows($sqlCount);
foreach ($data as $key => $row) {
$logo = $this->path.'/'.$row['short_name'].'/logo.png';
if (file_exists($logo) === false) {
$logo = $this->defaultLogo;
}
$metadataImage = $flattenMetadata[$row['short_name']]['image'];
if (isset($metadataImage) === true
&& file_exists($config['homedir'].'/images/discovery/'.$metadataImage) === true
&& file_exists($this->path.'/'.$row['short_name'].'/logo.png') === false
) {
$logo = '/images/discovery/'.$metadataImage;
}
$logo = html_print_image($logo, true, ['style' => 'max-width: 30px; margin-right: 15px;']);
$data[$key]['name'] = $logo.io_safe_output($row['name']);
$data[$key]['short_name'] = $row['short_name'];
$data[$key]['description'] = io_safe_output($row['description']);
$data[$key]['version'] = $row['version'];
$data[$key]['actions'] = '';
if ((bool) check_acl($config['id_user'], 0, 'AW') === true) {
$data[$key]['actions'] .= '<form name="grupo" method="post" class="rowPair table_action_buttons" action="'.$this->url.'&action=delete">';
$data[$key]['actions'] .= html_print_input_image(
'button_delete',
'images/delete.svg',
'',
'',
true,
[
'onclick' => 'if (!confirm(\''.__('Deleting this application will also delete all the discovery tasks using it. Do you want to delete it?').'\')) return false;',
'class' => 'main_menu_icon invert_filter action_button_hidden',
'title' => 'Delete',
]
);
$data[$key]['actions'] .= html_print_input_hidden('short_name', $row['short_name'], true);
$data[$key]['actions'] .= '</form>';
}
if ($this->checkFolderConsole($row['short_name']) === true) {
if ((bool) check_acl($config['id_user'], 0, 'AW') === true) {
$data[$key]['actions'] .= '<form name="grupo" method="post" class="rowPair table_action_buttons" action="'.$this->url.'&action=sync_server">';
$data[$key]['actions'] .= html_print_input_image(
'button_refresh',
'images/refresh@svg.svg',
'',
'',
true,
[
'onclick' => 'if (!confirm(\''.__('Are you sure you want to reapply?').'\')) return false;',
'class' => 'main_menu_icon invert_filter action_button_hidden',
'title' => 'Refresh',
]
);
$data[$key]['actions'] .= html_print_input_hidden('sync_action', 'refresh', true);
$data[$key]['actions'] .= html_print_input_hidden('short_name', $row['short_name'], true);
$data[$key]['actions'] .= '</form>';
}
} else {
$data[$key]['actions'] .= html_print_image(
'images/error_red.png',
true,
[
'title' => __('The extension directory or .ini does not exist in console.'),
'alt' => __('The extension directory or .ini does not exist in console.'),
'class' => 'main_menu_icon invert_filter',
],
);
}
}
if (empty($data) === true) {
$total = 0;
$data = [];
} else {
$total = $count;
}
echo json_encode(
[
'data' => $data,
'recordsTotal' => $total,
'recordsFiltered' => $total,
]
);
// Capture output.
$response = ob_get_clean();
} catch (Exception $e) {
echo json_encode(['error' => $e->getMessage()]);
exit;
}
json_decode($response);
if (json_last_error() === JSON_ERROR_NONE) {
echo $response;
} else {
echo json_encode(
[
'success' => false,
'error' => $response,
]
);
}
exit;
}
/**
* Insert new the default values for extension.
*
* @param integer $id Id of extension.
*
* @return boolean Result of query.
*/
private function autoUpdateDefaultMacros($id)
{
$defaultValues = $this->iniFile['discovery_extension_definition']['default_value'];
foreach ($defaultValues as $macro => $value) {
$sql = 'INSERT IGNORE INTO `tdiscovery_apps_tasks_macros`
(`id_task`, `macro`, `type`, `value`, `temp_conf`)
SELECT `id_rt`, "'.$macro.'", "custom", "'.(string) io_safe_input($value).'", "0"
FROM `trecon_task`
WHERE `id_app` = "'.$id.'";';
$result = db_process_sql($sql);
if ($result === false) {
return false;
}
}
$tempFiles = $this->iniFile['tempfile_confs']['file'];
foreach ($tempFiles as $macro => $value) {
$sql = 'UPDATE `tdiscovery_apps_tasks_macros`
SET `value` = "'.(string) io_safe_input($value).'" WHERE `id_task`
IN (SELECT `id_rt` FROM `trecon_task` WHERE `id_app` = "'.$id.'") AND `macro` = "'.$macro.'"';
$result = db_process_sql($sql);
if ($result === false) {
return false;
}
$sql = 'INSERT IGNORE INTO `tdiscovery_apps_tasks_macros`
(`id_task`, `macro`, `type`, `value`, `temp_conf`)
SELECT `id_rt`, "'.$macro.'", "custom", "'.(string) io_safe_input($value).'", "1"
FROM `trecon_task`
WHERE `id_app` = "'.$id.'";';
$result = db_process_sql($sql);
if ($result === false) {
return false;
}
}
return true;
}
/**
* Load the exec files in database
*
* @param integer $id Id of extension.
*
* @return boolean Result of query.
*/
private function autoLoadConfigExec($id)
{
$executionFiles = $this->iniFile['discovery_extension_definition']['execution_file'];
foreach ($executionFiles as $key => $value) {
$exist = db_get_row_filter(
'tdiscovery_apps_scripts',
[
'id_app' => $id,
'macro' => $key,
]
);
if ($exist === false) {
$result = db_process_sql_insert(
'tdiscovery_apps_scripts',
[
'id_app' => $id,
'macro' => $key,
'value' => io_safe_input($value),
]
);
if ($result === false) {
return false;
}
} else {
$result = db_process_sql_update(
'tdiscovery_apps_scripts',
['value' => io_safe_input($value)],
[
'id_app' => $id,
'macro' => $key,
]
);
if ($result === false) {
return false;
}
}
}
$execCommands = $this->iniFile['discovery_extension_definition']['exec'];
$result = db_process_sql_delete(
'tdiscovery_apps_executions',
['id_app' => $id]
);
if ($result === false) {
return false;
}
foreach ($execCommands as $key => $value) {
$result = db_process_sql_insert(
'tdiscovery_apps_executions',
[
'id_app' => $id,
'execution' => io_safe_input($value),
]
);
if ($result === false) {
return false;
}
}
return true;
}
/**
* Check if exist folder extension in console.
*
* @param string $shortName Name of folder.
*
* @return boolean Return true if exist folder
*/
private function checkFolderConsole($shortName)
{
global $config;
$folderPath = $config['homedir'].'/'.$this->path.'/'.$shortName;
$iniPath = $config['homedir'].'/'.$this->path.'/'.$shortName.'/discovery_definition.ini';
if (file_exists($folderPath) === false || file_exists($iniPath) === false) {
return false;
} else {
return true;
}
}
/**
* Validate the ini name by ajax.
*
* @return void
*/
public function validateIniName()
{
global $config;
$uploadDisco = get_parameter('upload_disco', '');
if (empty($uploadDisco) === false) {
if ($_FILES['file']['error'] == 0) {
$disco = $_FILES['file'];
} else {
echo json_encode(['success' => false, 'message' => 'Failed to upload extension']);
return;
}
}
if (substr($disco['name'], -6) !== '.disco') {
echo json_encode(['success' => false, 'message' => 'Failed to upload extension']);
return;
}
$nameFile = str_replace('.disco', '.zip', $disco['name']);
$nameTempDir = $config['attachment_store'].'/downloads/';
if (file_exists($nameTempDir) === false) {
mkdir($nameTempDir);
}
$tmpPath = Files::tempdirnam(
$nameTempDir,
'extensions_uploaded_'
);
$result = move_uploaded_file($disco['tmp_name'], $tmpPath.'/'.$nameFile);
if ($result === true) {
$unzip = $this->unZip($tmpPath.'/'.$nameFile, $tmpPath, 'discovery_definition.ini');
if ($unzip === true) {
unlink($tmpPath.'/'.$nameFile);
$this->iniFile = parse_ini_file($tmpPath.'/discovery_definition.ini', true, INI_SCANNER_TYPED);
if ($this->iniFile === false) {
Files::rmrf($tmpPath);
echo json_encode(['success' => false, 'message' => __('Failed to upload extension: Error while parsing dicovery_definition.ini')]);
return;
}
$message = false;
$shortName = $this->iniFile['discovery_extension_definition']['short_name'];
if (strpos($shortName, 'pandorafms.') === 0) {
$message = __('The \'short_name\' starting with \'pandorafms.\' is reserved for Pandora FMS applications. If this is not an official Pandora FMS application, consider changing the \'short_name\'. Do you want to continue?');
}
$exist = db_get_row_filter(
'tdiscovery_apps',
['short_name' => $shortName]
);
if ($exist !== false) {
$message = __('There is another application with the same \'short_name\': \'%s\'. Do you want to overwrite the application and all of its contents?', $shortName);
}
if ($message !== false) {
echo json_encode(
[
'success' => true,
'warning' => true,
'message' => $message,
]
);
} else {
echo json_encode(['success' => true]);
}
Files::rmrf($tmpPath);
return;
}
} else {
Files::rmrf($tmpPath);
echo json_encode(['success' => false, 'message' => __('Failed to upload extension')]);
return;
}
}
/**
* Return all extensions from section.
*
* @param string $section Section to filter.
*
* @return array List of sections.
*/
static public function getExtensionBySection($section)
{
return db_get_all_rows_filter(
'tdiscovery_apps',
['section' => $section]
);
}
/**
* Set execution permission in folder items and subfolders.
*
* @param string $path Array of files to apply permissions.
* @param array $filter Array of files for apply permission only.
*
* @return void
*/
private function setPermissionfiles($path, $filter=false)
{
global $config;
if ($filter !== false && is_array($filter) === true) {
foreach ($filter as $key => $file) {
if (substr($file, 0, 1) !== '/') {
$file = $path.'/'.$file;
}
chmod($file, 0777);
}
} else {
chmod($path, 0777);
if (is_dir($path)) {
$items = scandir($path);
foreach ($items as $item) {
if ($item != '.' && $item != '..') {
$itemPath = $path.'/'.$item;
$this->setPermissionfiles($itemPath);
}
}
}
}
}
/**
* Unzip folder or only file.
*
* @param string $zipFile File to unzip.
* @param string $target_path Target path into unzip.
* @param string $file If only need unzip one file.
*
* @return boolean $result True if the file has been successfully decompressed.
*/
public function unZip($zipFile, $target_path, $file=null)
{
$zip = new \ZipArchive;
if ($zip->open($zipFile) === true) {
$zip->extractTo($target_path, $file);
$zip->close();
return true;
} else {
return false;
}
}
/**
* Read metadata CSV from system and store data structure in memory.
*
* @return array Data structure.
*/
private static function loadDiscoveryAppsMetadata()
{
global $config;
// Open the CSV file for reading.
$fileHandle = fopen($config['homedir'].'/extras/discovery/DiscoveryApps.csv', 'r');
// Check if the file was opened successfully.
if ($fileHandle !== false) {
$csvData = [];
// Loop through each line in the CSV file.
while (($data = fgetcsv($fileHandle)) !== false) {
$csvData[] = explode(';', $data[0]);
}
// Close the file handle.
fclose($fileHandle);
}
$groupedArray = [];
foreach ($csvData as $item) {
$key = $item[2];
if (isset($groupedArray[$key]) === false) {
$groupedArray[$key] = [];
}
$itemShortName = $item[0];
unset($item[0]);
unset($item[2]);
$itemIns = [
'name' => $item[1],
'enterprise' => $item[3],
'image' => $item[4],
'url' => $item[5],
];
$groupedArray[$key][$itemShortName] = $itemIns;
}
return $groupedArray;
}
}