mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
Merge remote-tracking branch 'origin/support/2.6' into support/2.7
# Conflicts: # application/utils.inc.php # conf/web.config # datamodels/2.x/itop-backup/ajax.backup.php # datamodels/2.x/itop-backup/status.php
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -16,6 +16,11 @@
|
||||
vendor/*
|
||||
test/vendor/*
|
||||
|
||||
# all conf but listing prevention
|
||||
/conf/**
|
||||
!/conf/.htaccess
|
||||
!/conf/web.config
|
||||
|
||||
# all datas but listing prevention
|
||||
/data/**
|
||||
!/data/.htaccess
|
||||
|
||||
@@ -2194,7 +2194,7 @@ class utils
|
||||
* * not contained in base path
|
||||
* Otherwise return the real path (see realpath())
|
||||
*
|
||||
* @since 2.7.0 N°2538
|
||||
* @since 2.6.5 2.7.0 N°2538
|
||||
*/
|
||||
final public static function RealPath($sPath, $sBasePath)
|
||||
{
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<system.web>
|
||||
<authorization>
|
||||
<deny users="*" /> <!-- Denies all users -->
|
||||
</authorization>
|
||||
</system.web>
|
||||
<system.webServer>
|
||||
<security>
|
||||
<requestFiltering>
|
||||
<fileExtensions applyToWebDAV="false" allowUnlisted="false"></fileExtensions>
|
||||
</requestFiltering>
|
||||
<authorization>
|
||||
<deny users="*" /> <!-- Denies all users -->
|
||||
</authorization>
|
||||
</security>
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
@@ -1,8 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<system.web>
|
||||
<authorization>
|
||||
<deny users="*" /> <!-- Denies all users -->
|
||||
</authorization>
|
||||
</system.web>
|
||||
<system.webServer>
|
||||
<security>
|
||||
<requestFiltering>
|
||||
<fileExtensions applyToWebDAV="false" allowUnlisted="false"></fileExtensions>
|
||||
</requestFiltering>
|
||||
<authorization>
|
||||
<deny users="*" /> <!-- Denies all users -->
|
||||
</authorization>
|
||||
</security>
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2019 Combodo SARL
|
||||
* Copyright (C) 2010-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
@@ -25,77 +25,140 @@ require_once(APPROOT.'/application/ajaxwebpage.class.inc.php');
|
||||
|
||||
require_once(APPROOT.'core/mutex.class.inc.php');
|
||||
|
||||
|
||||
/**
|
||||
* @param WebPage $oPage
|
||||
* @param string $sHtmlErrorMessage the whole HTML error, cinluding div/p/...
|
||||
* @param int|string $exitCode
|
||||
*
|
||||
* @uses \die() https://www.php.net/manual/fr/function.die.php
|
||||
*
|
||||
* @since 2.6.5 2.7.1 N°2989
|
||||
*/
|
||||
function DisplayErrorAndDie($oPage, $sHtmlErrorMessage, $exitCode = null)
|
||||
{
|
||||
$oPage->add($sHtmlErrorMessage);
|
||||
$oPage->output();
|
||||
|
||||
die($exitCode);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
$sOperation = utils::ReadParam('operation', '');
|
||||
|
||||
$oPage = new ajax_page('');
|
||||
$oPage->no_cache();
|
||||
$oPage->SetContentType('text/html');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Check security
|
||||
*/
|
||||
switch ($sOperation)
|
||||
{
|
||||
/**
|
||||
* Can't use normal check methods (DoLogin for ex) as the datamodel can't be loaded here
|
||||
* So we're only using a token generated in the restore_token operation
|
||||
*/
|
||||
case 'restore_exec':
|
||||
IssueLog::Enable(APPROOT.'log/error.log');
|
||||
if (utils::GetConfig()->Get('demo_mode'))
|
||||
{
|
||||
DisplayErrorAndDie($oPage, '<div data-error-stimulus="Error">Sorry, '.ITOP_APPLICATION_SHORT.' is in <b>demonstration mode</b>: the feature is disabled.</div>');
|
||||
}
|
||||
|
||||
$sToken = utils::ReadParam('token', '', false, 'raw_data');
|
||||
$sBasePath = APPROOT.'/data/';
|
||||
$sTokenFile = $sBasePath.'restore.'.$sToken.'.tok';
|
||||
$tokenRealPath = utils::RealPath($sTokenFile, $sBasePath);
|
||||
if (($tokenRealPath === false) || (!is_file($tokenRealPath)))
|
||||
{
|
||||
IssueLog::Error("ajax.backup.php operation=$sOperation ERROR = inexisting token $sToken");
|
||||
$sEscapedToken = utils::HtmlEntities($sToken);
|
||||
DisplayErrorAndDie($oPage, "<p>Error: missing token file: '$sEscapedToken'</p>");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
require_once(APPROOT.'/application/startup.inc.php');
|
||||
require_once(APPROOT.'/application/loginwebpage.class.inc.php');
|
||||
|
||||
LoginWebPage::DoLogin();
|
||||
|
||||
$sTransactionId = utils::ReadParam('transaction_id', '', true, 'transaction_id');
|
||||
// the consumer page is not reloaded after download, we need to keep the transaction_id
|
||||
$bRemoveTransactionId = ($sOperation !== 'download');
|
||||
if (!utils::IsTransactionValid($sTransactionId, $bRemoveTransactionId))
|
||||
{
|
||||
$sEscapedOperation = utils::HtmlEntities($sOperation);
|
||||
DisplayErrorAndDie($oPage, "<div data-error-stimulus=\"Error\">Error: invalid Transaction ID. The operation '$sEscapedOperation' was NOT performed!</div>");
|
||||
}
|
||||
|
||||
ApplicationMenu::CheckMenuIdEnabled('BackupStatus');
|
||||
|
||||
if (utils::GetConfig()->Get('demo_mode'))
|
||||
{
|
||||
DisplayErrorAndDie($oPage, '<div data-error-stimulus="Error">Sorry, '.ITOP_APPLICATION_SHORT.' is in <b>demonstration mode</b>: the feature is disabled.</div>');
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Backup from an interactive session
|
||||
*/
|
||||
try
|
||||
{
|
||||
$sOperation = utils::ReadParam('operation', '');
|
||||
|
||||
switch ($sOperation)
|
||||
{
|
||||
case 'backup':
|
||||
require_once(APPROOT.'/application/startup.inc.php');
|
||||
require_once(APPROOT.'/application/loginwebpage.class.inc.php');
|
||||
LoginWebPage::DoLogin(); // Check user rights and prompt if needed
|
||||
ApplicationMenu::CheckMenuIdEnabled('BackupStatus');
|
||||
$oPage = new ajax_page("");
|
||||
$oPage->no_cache();
|
||||
$oPage->SetContentType('text/html');
|
||||
try
|
||||
{
|
||||
set_time_limit(0);
|
||||
$oBB = new BackupExec(APPROOT.'data/backups/manual/', 0 /*iRetentionCount*/);
|
||||
$sRes = $oBB->Process(time() + 36000); // 10 hours to complete should be sufficient!
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
$oPage->p('Error: '.$e->getMessage());
|
||||
IssueLog::Error($sOperation.' - '.$e->getMessage());
|
||||
}
|
||||
|
||||
if (utils::GetConfig()->Get('demo_mode'))
|
||||
{
|
||||
$oPage->add("<div data-error-stimulus=\"Error\">Sorry, iTop is in <b>demonstration mode</b>: the feature is disabled.</div>");
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
set_time_limit(0);
|
||||
$oBB = new BackupExec(APPROOT.'data/backups/manual/', 0 /*iRetentionCount*/);
|
||||
$sRes = $oBB->Process(time() + 36000); // 10 hours to complete should be sufficient!
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
$oPage->p('Error: '.$e->getMessage());
|
||||
IssueLog::Error($sOperation.' - '.$e->getMessage());
|
||||
}
|
||||
}
|
||||
$oPage->output();
|
||||
break;
|
||||
|
||||
/*
|
||||
* Fix a token :
|
||||
* Fix a specific token :
|
||||
* We can't load the MetaModel because in DBRestore, after restore is done we're launching a compile !
|
||||
* So as \LoginWebPage::DoLogin needs a loaded DataModel, we can't use it
|
||||
* So as LoginWebPage::DoLogin needs a loaded DataModel, we can't use it
|
||||
* Also, we can't use \utils::IsTransactionValid as it uses \MetaModel::GetConfig
|
||||
* As a result we're setting a token file to make sure the restore is called by an authenticated user with the correct rights !
|
||||
*/
|
||||
case 'restore_get_token':
|
||||
require_once(APPROOT.'/application/startup.inc.php');
|
||||
require_once(APPROOT.'/application/loginwebpage.class.inc.php');
|
||||
LoginWebPage::DoLogin(); // Check user rights and prompt if needed
|
||||
ApplicationMenu::CheckMenuIdEnabled('BackupStatus');
|
||||
|
||||
$oPage = new ajax_page("");
|
||||
$oPage->no_cache();
|
||||
$oPage->SetContentType('text/html');
|
||||
|
||||
$sEnvironment = utils::ReadParam('environment', 'production', false, 'raw_data');
|
||||
$oRestoreMutex = new iTopMutex('restore.'.$sEnvironment);
|
||||
if (!$oRestoreMutex->IsLocked())
|
||||
if ($oRestoreMutex->IsLocked())
|
||||
{
|
||||
$sFile = utils::ReadParam('file', '', false, 'raw_data');
|
||||
$sToken = str_replace(' ', '', (string)microtime());
|
||||
$sTokenFile = APPROOT.'/data/restore.'.$sToken.'.tok';
|
||||
file_put_contents($sTokenFile, $sFile);
|
||||
DisplayErrorAndDie($oPage, '<p>'.Dict::S('bkp-restore-running').'</p>');
|
||||
}
|
||||
|
||||
$sFile = utils::ReadParam('file', '', false, 'raw_data');
|
||||
$sToken = str_replace(' ', '', (string)microtime()).$sTransactionId;
|
||||
$sTokenFile = APPROOT.'/data/restore.'.$sToken.'.tok';
|
||||
file_put_contents($sTokenFile, $sFile);
|
||||
|
||||
$oPage->add_ready_script(
|
||||
<<<JS
|
||||
$("#restore_token").val('$sToken');
|
||||
JS
|
||||
);
|
||||
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
$("#restore_token").val('$sToken');
|
||||
EOF
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oPage->p(Dict::S('bkp-restore-running'));
|
||||
}
|
||||
$oPage->output();
|
||||
break;
|
||||
|
||||
@@ -109,72 +172,47 @@ EOF
|
||||
require_once(APPROOT.'/setup/backup.class.inc.php');
|
||||
require_once(dirname(__FILE__).'/dbrestore.class.inc.php');
|
||||
|
||||
IssueLog::Enable(APPROOT.'log/error.log');
|
||||
|
||||
$oPage = new ajax_page("");
|
||||
$oPage->no_cache();
|
||||
$oPage->SetContentType('text/html');
|
||||
|
||||
if (utils::GetConfig()->Get('demo_mode'))
|
||||
$sEnvironment = utils::ReadParam('environment', 'production', false, 'raw_data');
|
||||
$oRestoreMutex = new iTopMutex('restore.'.$sEnvironment);
|
||||
IssueLog::Info("Backup Restore - Acquiring the LOCK 'restore.$sEnvironment'");
|
||||
$oRestoreMutex->Lock();
|
||||
IssueLog::Info('Backup Restore - LOCK acquired, executing...');
|
||||
try
|
||||
{
|
||||
$oPage->add("<div data-error-stimulus=\"Error\">Sorry, iTop is in <b>demonstration mode</b>: the feature is disabled.</div>");
|
||||
set_time_limit(0);
|
||||
|
||||
// Get the file and destroy the token (single usage)
|
||||
$sFile = file_get_contents($tokenRealPath);
|
||||
|
||||
// Loading config file : we don't have the MetaModel but we have the current env !
|
||||
$sConfigFilePath = utils::GetConfigFilePath($sEnvironment);
|
||||
$oItopConfig = new Config($sConfigFilePath, true);
|
||||
$sMySQLBinDir = $oItopConfig->GetModuleSetting('itop-backup', 'mysql_bindir', '');
|
||||
|
||||
$oDBRS = new DBRestore($oItopConfig);
|
||||
$oDBRS->SetMySQLBinDir($sMySQLBinDir);
|
||||
|
||||
$sBackupDir = APPROOT.'data/backups/';
|
||||
$sBackupFile = $sBackupDir.$sFile;
|
||||
$sRes = $oDBRS->RestoreFromCompressedBackup($sBackupFile, $sEnvironment);
|
||||
|
||||
IssueLog::Info('Backup Restore - Done, releasing the LOCK');
|
||||
}
|
||||
else
|
||||
catch (Exception $e)
|
||||
{
|
||||
$sEnvironment = utils::ReadParam('environment', 'production', false, 'raw_data');
|
||||
$oRestoreMutex = new iTopMutex('restore.'.$sEnvironment);
|
||||
IssueLog::Info("Backup Restore - Acquiring the LOCK 'restore.$sEnvironment'");
|
||||
$oRestoreMutex->Lock();
|
||||
IssueLog::Info('Backup Restore - LOCK acquired, executing...');
|
||||
try
|
||||
{
|
||||
set_time_limit(0);
|
||||
|
||||
// Get the file and destroy the token (single usage)
|
||||
$sToken = utils::ReadParam('token', '', false, 'raw_data');
|
||||
$sTokenFile = APPROOT.'/data/restore.'.$sToken.'.tok';
|
||||
if (!is_file($sTokenFile))
|
||||
{
|
||||
throw new Exception("Error: missing token file: '$sTokenFile'");
|
||||
}
|
||||
$sFile = file_get_contents($sTokenFile);
|
||||
unlink($sTokenFile);
|
||||
|
||||
// Loading config file : we don't have the MetaModel but we have the current env !
|
||||
$sConfigFilePath = utils::GetConfigFilePath($sEnvironment);
|
||||
$oItopConfig = new Config($sConfigFilePath, true);
|
||||
$sMySQLBinDir = $oItopConfig->GetModuleSetting('itop-backup', 'mysql_bindir', '');
|
||||
|
||||
$oDBRS = new DBRestore($oItopConfig);
|
||||
$oDBRS->SetMySQLBinDir($sMySQLBinDir);
|
||||
|
||||
$sBackupDir = APPROOT.'data/backups/';
|
||||
$sBackupFile = $sBackupDir.$sFile;
|
||||
$sRes = $oDBRS->RestoreFromCompressedBackup($sBackupFile, $sEnvironment);
|
||||
|
||||
IssueLog::Info('Backup Restore - Done, releasing the LOCK');
|
||||
$oRestoreMutex->Unlock();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
$oRestoreMutex->Unlock();
|
||||
$oPage->p('Error: '.$e->getMessage());
|
||||
IssueLog::Error($sOperation.' - '.$e->getMessage());
|
||||
}
|
||||
$oPage->p('Error: '.$e->getMessage());
|
||||
IssueLog::Error($sOperation.' - '.$e->getMessage());
|
||||
}
|
||||
finally
|
||||
{
|
||||
unlink($tokenRealPath);
|
||||
$oRestoreMutex->Unlock();
|
||||
}
|
||||
|
||||
$oPage->output();
|
||||
break;
|
||||
|
||||
case 'download':
|
||||
require_once(APPROOT.'/application/startup.inc.php');
|
||||
require_once(APPROOT.'/application/loginwebpage.class.inc.php');
|
||||
LoginWebPage::DoLogin(); // Check user rights and prompt if needed
|
||||
ApplicationMenu::CheckMenuIdEnabled('BackupStatus');
|
||||
|
||||
if (utils::GetConfig()->Get('demo_mode'))
|
||||
{
|
||||
throw new Exception('iTop is in demonstration mode: the feature is disabled');
|
||||
}
|
||||
$sFile = utils::ReadParam('file', '', false, 'raw_data');
|
||||
$oBackup = new DBBackupScheduled();
|
||||
$sBackupDir = APPROOT.'data/backups/';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2019 Combodo SARL
|
||||
* Copyright (C) 2010-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
@@ -33,13 +33,9 @@ require_once(APPROOT.'application/loginwebpage.class.inc.php');
|
||||
LoginWebPage::DoLogin(); // Check user rights and prompt if needed
|
||||
ApplicationMenu::CheckMenuIdEnabled('BackupStatus');
|
||||
|
||||
//$sOperation = utils::ReadParam('operation', 'menu');
|
||||
//$oAppContext = new ApplicationContext();
|
||||
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
$sTransactionId = utils::GetNewTransactionId();
|
||||
$oP = new iTopWebPage(Dict::S('bkp-status-title'));
|
||||
$oP->set_base(utils::GetAbsoluteUrlAppRoot().'pages/');
|
||||
|
||||
@@ -186,7 +182,13 @@ try
|
||||
}
|
||||
else
|
||||
{
|
||||
$sAjax = utils::GetAbsoluteUrlModulePage('itop-backup', 'ajax.backup.php', array('operation' => 'download', 'file' => $sFilePath));
|
||||
$sAjax = utils::GetAbsoluteUrlModulePage('itop-backup', 'ajax.backup.php',
|
||||
array(
|
||||
'operation' => 'download',
|
||||
'file' => $sFilePath,
|
||||
'transaction_id' => $sTransactionId,
|
||||
)
|
||||
);
|
||||
$sName = "<a href=\"$sAjax\">".$sFileName.'</a>';
|
||||
}
|
||||
$sSize = SetupUtils::HumanReadableSize(filesize($sBackupFile));
|
||||
@@ -234,7 +236,13 @@ try
|
||||
}
|
||||
else
|
||||
{
|
||||
$sAjax = utils::GetAbsoluteUrlModulePage('itop-backup', 'ajax.backup.php', array('operation' => 'download', 'file' => $sFilePath));
|
||||
$sAjax = utils::GetAbsoluteUrlModulePage('itop-backup', 'ajax.backup.php',
|
||||
array(
|
||||
'operation' => 'download',
|
||||
'file' => $sFilePath,
|
||||
'transaction_id' => $sTransactionId,
|
||||
)
|
||||
);
|
||||
$sName = "<a href=\"$sAjax\">".$sFileName.'</a>';
|
||||
}
|
||||
$sSize = SetupUtils::HumanReadableSize(filesize($sBackupFile));
|
||||
@@ -298,9 +306,9 @@ try
|
||||
$sDBSubName = addslashes(MetaModel::GetConfig()->Get('db_subname'));
|
||||
|
||||
$sEnvironment = addslashes(utils::GetCurrentEnvironment());
|
||||
|
||||
|
||||
$oP->add_script(
|
||||
<<<EOF
|
||||
<<<JS
|
||||
function LaunchBackupNow()
|
||||
{
|
||||
$('#backup_success').hide();
|
||||
@@ -312,6 +320,7 @@ function LaunchBackupNow()
|
||||
|
||||
var oParams = {};
|
||||
oParams.operation = 'backup';
|
||||
oParams.transaction_id = "$sTransactionId";
|
||||
$.post(GetAbsoluteUrlModulePage('itop-backup', 'ajax.backup.php'), oParams, function(data){
|
||||
if (data.search(/error|exceptio|notice|warning/i) != -1)
|
||||
{
|
||||
@@ -337,7 +346,8 @@ function LaunchRestoreNow(sBackupFile, sConfirmationMessage)
|
||||
|
||||
var oParams = {};
|
||||
oParams.operation = 'restore_get_token';
|
||||
oParams.file = sBackupFile;
|
||||
oParams.file = sBackupFile;
|
||||
oParams.transaction_id = "$sTransactionId";
|
||||
$.post(GetAbsoluteUrlModulePage('itop-backup', 'ajax.backup.php'), oParams, function(data){
|
||||
|
||||
// Get the value of restore_token
|
||||
@@ -347,6 +357,7 @@ function LaunchRestoreNow(sBackupFile, sConfirmationMessage)
|
||||
oParams.operation = 'restore_exec';
|
||||
oParams.token = $("#restore_token").val(); // token to check auth + rights without loading MetaModel
|
||||
oParams.environment = '$sEnvironment'; // needed to load the config
|
||||
oParams.transaction_id = "$sTransactionId";
|
||||
if (oParams.token.length > 0)
|
||||
{
|
||||
$.post(GetAbsoluteUrlModulePage('itop-backup', 'ajax.backup.php'), oParams, function(data){
|
||||
@@ -373,7 +384,7 @@ function LaunchRestoreNow(sBackupFile, sConfirmationMessage)
|
||||
});
|
||||
}
|
||||
}
|
||||
EOF
|
||||
JS
|
||||
);
|
||||
|
||||
if (MetaModel::GetConfig()->Get('demo_mode'))
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<system.web>
|
||||
<authorization>
|
||||
<deny users="*" /> <!-- Denies all users -->
|
||||
</authorization>
|
||||
</system.web>
|
||||
<system.webServer>
|
||||
<security>
|
||||
<requestFiltering>
|
||||
<fileExtensions applyToWebDAV="false" allowUnlisted="false"></fileExtensions>
|
||||
</requestFiltering>
|
||||
<authorization>
|
||||
<deny users="*" /> <!-- Denies all users -->
|
||||
</authorization>
|
||||
</security>
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
@@ -282,6 +282,7 @@ try
|
||||
{
|
||||
try
|
||||
{
|
||||
$iCount = 0;
|
||||
$oDefinitionFilter = DBObjectSearch::FromOQL($oAuditCategory->Get('definition_set'));
|
||||
$oDefinitionFilter->UpdateContextFromUser();
|
||||
FilterByContext($oDefinitionFilter, $oAppContext);
|
||||
@@ -348,7 +349,7 @@ try
|
||||
$aRow['nb_errors'] = "n/a";
|
||||
$aRow['percent_ok'] = '';
|
||||
$aRow['class'] = 'red';
|
||||
$sMessage = Dict::Format('UI:Audit:ErrorIn_Category_Reason', $oAuditCategory->GetHyperlink(), $e->getMessage());
|
||||
$sMessage = Dict::Format('UI:Audit:ErrorIn_Category_Reason', $oAuditCategory->GetHyperlink(), utils::HtmlEntities($e->getMessage()));
|
||||
$oP->p("<img style=\"vertical-align:middle\" src=\"../images/stop-mid.png\"/> ".$sMessage);
|
||||
$aResults[] = $aRow;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user