Merge branch 'support/2.5'

# Conflicts:
#	datamodels/2.x/itop-hub-connector/zh_cn.dict.itop-hub-connector.php
#	lib/tcpdf/CHANGELOG.TXT
#	lib/tcpdf/composer.json
#	lib/tcpdf/include/tcpdf_fonts.php
#	lib/tcpdf/include/tcpdf_images.php
#	lib/tcpdf/include/tcpdf_static.php
#	lib/tcpdf/tcpdf.php
This commit is contained in:
Pierre Goiffon
2019-01-28 16:04:19 +01:00
18 changed files with 281 additions and 315 deletions

View File

@@ -184,7 +184,7 @@ EOF
$sFile = utils::ReadParam('file', '', false, 'raw_data');
$oBackup = new DBBackupScheduled();
$sBackupDir = APPROOT.'data/backups/';
$sPathNoDotDotPattern = '/^((?!\/\.\.\/).)*$/';
$sPathNoDotDotPattern = "/^((?![\/\\\\]\.\.[\/\\\\]).)*$/";
if(preg_match($sPathNoDotDotPattern, $sBackupDir.$sFile) == 1)
{
$oBackup->DownloadBackup($sBackupDir.$sFile);

View File

@@ -256,7 +256,11 @@ try
case 'compile':
SetupPage::log_info('Deployment starts...');
$sAuthent = utils::ReadParam('authent', '', false, 'raw_data');
if (!file_exists(APPROOT.'data/hub/compile_authent') || $sAuthent !== file_get_contents(APPROOT.'data/hub/compile_authent'))
{
throw new SecurityException(Dict::S('iTopHub:FailAuthent'));
}
// First step: prepare the datamodel, if it fails, roll-back
$aSelectedExtensionCodes = utils::ReadParam('extension_codes', array());
$aSelectedExtensionDirs = utils::ReadParam('extension_dirs', array());
@@ -295,7 +299,13 @@ try
try
{
SetupPage::log_info('Move to production starts...');
// Load the "production" config file to clone & update it
$sAuthent = utils::ReadParam('authent', '', false, 'raw_data');
if (!file_exists(APPROOT.'data/hub/compile_authent') || $sAuthent !== file_get_contents(APPROOT.'data/hub/compile_authent'))
{
throw new SecurityException(Dict::S('iTopHub:FailAuthent'));
}
unlink(APPROOT.'data/hub/compile_authent');
// Load the "production" config file to clone & update it
$oConfig = new Config(APPCONF.'production/'.ITOP_CONFIG_FILE);
$oRuntimeEnv->InitDataModel($oConfig, true /* model only */);
@@ -357,6 +367,10 @@ try
}
catch (Exception $e)
{
if(file_exists(APPROOT.'data/hub/compile_authent'))
{
unlink(APPROOT.'data/hub/compile_authent');
}
// Note: at this point, the dictionnary is not necessarily loaded
SetupPage::log_error(get_class($e).': '.Dict::S('iTopHub:ConfigurationSafelyReverted')."\n".$e->getMessage());
SetupPage::log_error('Debug trace: '.$e->getTraceAsString());

View File

@@ -48,7 +48,9 @@ Dict::Add('EN US', 'English', 'English', array(
'iTopHub:Landing:Install' => 'Deploying extensions...',
'iTopHub:CompiledOK' => 'Compilation successful.',
'iTopHub:ConfigurationSafelyReverted' => 'Error detected during deployment!<br/>iTop configuration has NOT been modified.',
'iTopHub:FailAuthent' => 'Authentication failed for this action.',
'iTopHub:InstalledExtensions' => 'Extensions deployed on this instance',
'iTopHub:ExtensionCategory:Manual' => 'Extensions deployed manually',
'iTopHub:ExtensionCategory:Manual+' => 'The following extensions have been deployed by copying them manually in the %1$s directory of iTop:',

View File

@@ -32,6 +32,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
'iTopHub:Landing:Install' => 'Déploiement des extensions...',
'iTopHub:CompiledOK' => 'Compilation réussie.',
'iTopHub:ConfigurationSafelyReverted' => 'Une erreur a été détectée durant le déploiement!<br/>La configuration d\'iTop n\'a PAS été modifiée.',
'iTopHub:FailAuthent' => 'Échec d\'authentification pour cette action',
'iTopHub:InstalledExtensions' => 'Extensions déployées sur cette instance',
'iTopHub:ExtensionCategory:Manual' => 'Extensions déployées manuellement',

View File

@@ -18,7 +18,8 @@ $(function()
extensions_installation: 'Installation of the extensions...',
installation_successful: 'Installation successful!',
rollback: 'iTop configuration has NOT been modified.'
}
},
authent : ''
},
// the constructor
@@ -106,7 +107,7 @@ $(function()
var aExtensionCodes = [];
var aExtensionDirs = [];
$('.choice :input:checked').each(function() { aExtensionCodes.push($(this).attr('data-extension-code')); aExtensionDirs.push($(this).attr('data-extension-dir')); });
$.post(this.options.self_url, {operation: 'compile', extension_codes: aExtensionCodes, extension_dirs: aExtensionDirs}, function(data) { me._on_compile(data) }, 'json');
$.post(this.options.self_url, {operation: 'compile', extension_codes: aExtensionCodes, extension_dirs: aExtensionDirs, authent: this.options.authent}, function(data) { me._on_compile(data) }, 'json');
},
_on_compile: function(data)
{
@@ -125,7 +126,7 @@ $(function()
{
$('#hub-installation-progress-text').html('<i class="fa fa-cogs"></i> '+this.options.labels.extensions_installation);
var me = this;
$.post(this.options.self_url, {operation: 'move_to_production'}, function(data) { me._on_move_to_prod(data) }, 'json');
$.post(this.options.self_url, {operation: 'move_to_production', authent: this.options.authent}, function(data) { me._on_move_to_prod(data) }, 'json');
},
_on_move_to_prod: function(data)
{

View File

@@ -107,7 +107,7 @@ function DoLanding(WebPage $oPage)
$sPath = APPROOT.'data/downloaded-extensions/';
if (!is_dir($sPath))
{
if (!mkdir($sPath)) throw new Exception("ERROR: Unable to create the directory '$sPath'. Cannot download any extension. Check the access rights on '".dirname($sPath)."'");
if (!mkdir($sPath)) throw new Exception("ERROR: Unable to create the directory '$sPath'. Cannot download any extension. Check the access rights on '".dirname('data/downloaded-extensions/')."'");
}
else
{
@@ -126,7 +126,7 @@ function DoLanding(WebPage $oPage)
$oZip = new ZipArchive();
if (!$oZip->open($sZipArchiveFile))
{
throw new Exception('Unable to open "'.$sZipArchiveFile.'" for extraction. Make sure that the directory "'.$sPath.'" is writable for the web server.');
throw new Exception('Unable to open "'.$sZipArchiveFile.'" for extraction. Make sure that the directory "'.'data/downloaded-extensions/'.'" is writable for the web server.');
}
for($idx = 0; $idx < $oZip->numFiles; $idx++)
{
@@ -146,6 +146,9 @@ function DoLanding(WebPage $oPage)
function DoInstall(WebPage $oPage)
{
$sUID = hash('sha256', rand());
file_put_contents(APPROOT.'data/hub/compile_authent', $sUID);
$oPage->add_linked_stylesheet(utils::GetAbsoluteUrlModulesRoot().'itop-hub-connector/css/hub.css');
$oPage->add('<table class="module-selection-banner"><tr>');
$sBannerUrl = utils::GetAbsoluteUrlModulesRoot().'/itop-hub-connector/images/landing-extension.png';
@@ -259,6 +262,7 @@ function DoInstall(WebPage $oPage)
'installation_successful' => Dict::S('iTopHub:InstallationProgress:InstallationSuccessful'),
'rollback' => Dict::S('iTopHub:ConfigurationSafelyReverted'),
),
'authent' => $sUID,
);
$sWidgetParams = json_encode($aWidgetParams);
@@ -301,6 +305,10 @@ try
break;
case 'install':
if (!file_exists(APPROOT.'data/hub'))
{
mkdir(APPROOT.'data/hub');
}
DoInstall($oPage);
break;

View File

@@ -48,7 +48,8 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'iTopHub:Landing:Install' => '扩展安装进行中...',
'iTopHub:CompiledOK' => '编译成功.',
'iTopHub:ConfigurationSafelyReverted' => '安装时发生错误!<br/>iTop 配置将不会改变.',
'iTopHub:FailAuthent' => 'Authentication failed for this action.~~',
'iTopHub:InstalledExtensions' => '本机已安装的扩展',
'iTopHub:ExtensionCategory:Manual' => '手动安装的扩展',
'iTopHub:ExtensionCategory:Manual+' => '下列已安装的扩展是手动将文件放置到 %1$s 目录的:',