mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-21 11:24:19 +01:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2fd9523c16 | ||
|
|
a4f6f6e877 | ||
|
|
94c604a6af | ||
|
|
6995a3c641 | ||
|
|
9865bf0779 | ||
|
|
d5449cca42 | ||
|
|
5d38d22c50 | ||
|
|
99d69493d1 | ||
|
|
c9bb628c30 | ||
|
|
08e8d15d78 |
@@ -42,7 +42,7 @@ class ajax_page extends WebPage implements iTabbedPage
|
||||
$this->m_sReadyScript = "";
|
||||
//$this->add_header("Content-type: text/html; charset=utf-8");
|
||||
$this->no_cache();
|
||||
$this->add_xframe_options();
|
||||
$this->add_http_headers();
|
||||
$this->m_oTabs = new TabManager();
|
||||
$this->sContentType = 'text/html';
|
||||
$this->sContentDisposition = 'inline';
|
||||
@@ -51,6 +51,16 @@ class ajax_page extends WebPage implements iTabbedPage
|
||||
utils::InitArchiveMode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Disabling sending the header so that resource won't be blocked by CORB. See parent method documentation.
|
||||
* @return void
|
||||
* @since 2.7.10 3.0.4 3.1.2 3.2.0 N°4368 method creation
|
||||
*/
|
||||
public function add_xcontent_type_options()
|
||||
{
|
||||
// Nothing to do !
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @throws \Exception
|
||||
|
||||
@@ -33,7 +33,7 @@ class CSVPage extends WebPage
|
||||
parent::__construct($s_title);
|
||||
$this->add_header("Content-type: text/plain; charset=".self::PAGES_CHARSET);
|
||||
$this->no_cache();
|
||||
$this->add_xframe_options();
|
||||
$this->add_http_headers();
|
||||
//$this->add_header("Content-Transfer-Encoding: binary");
|
||||
}
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
|
||||
$this->SetRootUrl(utils::GetAbsoluteUrlAppRoot());
|
||||
$this->add_header("Content-type: text/html; charset=".self::PAGES_CHARSET);
|
||||
$this->no_cache();
|
||||
$this->add_xframe_options();
|
||||
$this->add_http_headers();
|
||||
$this->add_linked_stylesheet("../css/jquery.treeview.css");
|
||||
$this->add_linked_stylesheet("../css/jquery.autocomplete.css");
|
||||
$this->add_linked_stylesheet("../css/jquery-ui-timepicker-addon.css");
|
||||
|
||||
@@ -85,7 +85,7 @@ class LoginWebPage extends NiceWebPage
|
||||
parent::__construct($sTitle);
|
||||
$this->SetStyleSheet();
|
||||
$this->no_cache();
|
||||
$this->add_xframe_options();
|
||||
$this->add_http_headers();
|
||||
}
|
||||
|
||||
public function SetStyleSheet()
|
||||
|
||||
@@ -483,12 +483,24 @@ class WebPage implements Page
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $sHeaderValue for example `SAMESITE`. If null will set the header using the config parameter value.
|
||||
* @param string|null $sXFrameOptionsHeaderValue passed to {@see add_xframe_options}
|
||||
*
|
||||
* @return void
|
||||
* @since 2.7.10 3.0.4 3.1.2 3.2.0 N°4368 method creation, replace {@see add_xframe_options} consumers call
|
||||
*/
|
||||
public function add_http_headers($sXFrameOptionsHeaderValue = null)
|
||||
{
|
||||
$this->add_xframe_options($sXFrameOptionsHeaderValue);
|
||||
$this->add_xcontent_type_options();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $sHeaderValue for example `SAMESITE`. If null will set the header using the `security_header_xframe` config parameter value.
|
||||
*
|
||||
* @since 2.7.3 3.0.0 N°3416
|
||||
* @uses security_header_xframe config parameter
|
||||
* @uses \utils::GetConfig()
|
||||
* @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
|
||||
*
|
||||
* @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options HTTP header MDN documentation
|
||||
*/
|
||||
public function add_xframe_options($sHeaderValue = null)
|
||||
{
|
||||
@@ -499,6 +511,38 @@ class WebPage implements Page
|
||||
$this->add_header('X-Frame-Options: '.$sHeaderValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Warning : this header will trigger the Cross-Origin Read Blocking (CORB) protection for some mime types (HTML, XML except SVG, JSON, text/plain)
|
||||
* In consequence some children pages will override this method.
|
||||
*
|
||||
* Sending header can be disabled globally using the `security.enable_header_xcontent_type_options` optional config parameter.
|
||||
*
|
||||
* @return void
|
||||
* @since 2.7.10 3.0.4 3.1.2 3.2.0 N°4368 method creation
|
||||
*
|
||||
* @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options HTTP header MDN documentation
|
||||
* @link https://chromium.googlesource.com/chromium/src/+/master/services/network/cross_origin_read_blocking_explainer.md#determining-whether-a-response-is-corb_protected "Determining whether a response is CORB-protected"
|
||||
*/
|
||||
public function add_xcontent_type_options()
|
||||
{
|
||||
try {
|
||||
$oConfig = utils::GetConfig();
|
||||
} catch (ConfigException|CoreException $e) {
|
||||
$oConfig = null;
|
||||
}
|
||||
if (is_null($oConfig)) {
|
||||
$bSendXContentTypeOptionsHttpHeader = true;
|
||||
} else {
|
||||
$bSendXContentTypeOptionsHttpHeader = $oConfig->Get('security.enable_header_xcontent_type_options');
|
||||
}
|
||||
|
||||
if ($bSendXContentTypeOptionsHttpHeader === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->add_header('X-Content-Type-Options: nosniff');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add needed headers to the page so that it will no be cached
|
||||
*/
|
||||
|
||||
@@ -44,10 +44,20 @@ class XMLPage extends WebPage
|
||||
$this->m_bHeaderSent = false;
|
||||
$this->add_header("Content-type: text/xml; charset=".self::PAGES_CHARSET);
|
||||
$this->no_cache();
|
||||
$this->add_xframe_options();
|
||||
$this->add_http_headers();
|
||||
$this->add_header("Content-location: export.xml");
|
||||
}
|
||||
|
||||
/**
|
||||
* Disabling sending the header so that resource won't be blocked by CORB. See parent method documentation.
|
||||
* @return void
|
||||
* @since 2.7.10 3.0.4 3.1.2 3.2.0 N°4368 method creation
|
||||
*/
|
||||
public function add_xcontent_type_options()
|
||||
{
|
||||
// Nothing to do !
|
||||
}
|
||||
|
||||
public function output()
|
||||
{
|
||||
if (!$this->m_bPassThrough)
|
||||
|
||||
@@ -14,7 +14,7 @@ define('APPCONF', APPROOT.'conf/');
|
||||
* @used-by utils::GetItopVersionWikiSyntax()
|
||||
* @used-by iTopModulesPhpVersionIntegrationTest
|
||||
*/
|
||||
define('ITOP_CORE_VERSION', '2.7.9');
|
||||
define('ITOP_CORE_VERSION', '2.7.10');
|
||||
|
||||
|
||||
require_once APPROOT.'bootstrap.inc.php';
|
||||
|
||||
@@ -134,6 +134,12 @@ class CMDBSource
|
||||
const ENUM_DB_VENDOR_MARIADB = 'MariaDB';
|
||||
const ENUM_DB_VENDOR_PERCONA = 'Percona';
|
||||
|
||||
/**
|
||||
* @since 2.7.10 3.0.4 3.1.2 3.0.2 N°6889 constant creation
|
||||
* @internal will be removed in a future version
|
||||
*/
|
||||
const MYSQL_DEFAULT_PORT = 3306;
|
||||
|
||||
/**
|
||||
* Error: 1205 SQLSTATE: HY000 (ER_LOCK_WAIT_TIMEOUT)
|
||||
* Message: Lock wait timeout exceeded; try restarting transaction
|
||||
@@ -319,16 +325,19 @@ class CMDBSource
|
||||
/**
|
||||
* @param string $sDbHost initial value ("p:domain:port" syntax)
|
||||
* @param string $sServer server variable to update
|
||||
* @param int $iPort port variable to update
|
||||
* @param int|null $iPort port variable to update, will return null if nothing is specified in $sDbHost
|
||||
*
|
||||
* @since 2.7.10 3.0.4 3.1.2 3.2.0 N°6889 will return null in $iPort if port isn't present in $sDbHost. Use {@see MYSQL_DEFAULT_PORT} if needed
|
||||
*
|
||||
* @link http://php.net/manual/en/mysqli.persistconns.php documentation for the "p:" prefix (persistent connexion)
|
||||
*/
|
||||
public static function InitServerAndPort($sDbHost, &$sServer, &$iPort)
|
||||
{
|
||||
$aConnectInfo = explode(':', $sDbHost);
|
||||
|
||||
$bUsePersistentConnection = false;
|
||||
if (strcasecmp($aConnectInfo[0], 'p') == 0)
|
||||
if (strcasecmp($aConnectInfo[0], 'p') === 0)
|
||||
{
|
||||
// we might have "p:" prefix to use persistent connections (see http://php.net/manual/en/mysqli.persistconns.php)
|
||||
$bUsePersistentConnection = true;
|
||||
$sServer = $aConnectInfo[0].':'.$aConnectInfo[1];
|
||||
}
|
||||
@@ -346,10 +355,6 @@ class CMDBSource
|
||||
{
|
||||
$iPort = (int)($aConnectInfo[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$iPort = 3306;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1320,6 +1320,14 @@ class Config
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
],
|
||||
'security.enable_header_xcontent_type_options' => [
|
||||
'type' => 'bool',
|
||||
'description' => 'If set to false, iTop will stop sending the X-Content-Type-Options HTTP header. This header could trigger CORB protection on certain resources (JSON, XML, HTML, text) therefore blocking them.',
|
||||
'default' => true,
|
||||
'value' => '',
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
],
|
||||
'behind_reverse_proxy' => [
|
||||
'type' => 'bool',
|
||||
'description' => 'If true, then proxies custom header (X-Forwarded-*) are taken into account. Use only if the webserver is not publicly accessible (reachable only by the reverse proxy)',
|
||||
|
||||
@@ -2297,15 +2297,19 @@ abstract class DBObject implements iDisplay
|
||||
continue;
|
||||
}
|
||||
|
||||
/** @noinspection NotOptimalIfConditionsInspection */
|
||||
/** @noinspection TypeUnsafeComparisonInspection */
|
||||
if (utils::IsNullOrEmptyString($sRemoteObjectClass)
|
||||
|| utils::IsNullOrEmptyString($sRemoteObjectKey)
|
||||
|| ($sRemoteObjectKey == 0) // non-strict comparison as we might have bad surprises
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 0 : Undefined ext. key (EG. non-mandatory and no value provided)
|
||||
// < 0 : Non yet persisted object
|
||||
/** @noinspection TypeUnsafeComparisonInspection Non-strict comparison as object ID can be string */
|
||||
if ($sRemoteObjectKey <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (false === $oIsObjectLoadableCallback($sRemoteObjectClass, $sRemoteObjectKey)) {
|
||||
throw new InvalidExternalKeyValueException($this, $sAttDefCode);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,9 @@
|
||||
* A class to serialize the execution of some code sections
|
||||
* Emulates the API of PECL Mutex class
|
||||
* Relies on MySQL locks because the API sem_get is not always present in the
|
||||
* installed PHP.
|
||||
* installed PHP.
|
||||
*
|
||||
* @link https://dev.mysql.com/doc/refman/5.7/en/locking-functions.html MySQL locking functions documentation
|
||||
*
|
||||
* @copyright Copyright (C) 2013-2018 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
// Beware the version number MUST be enclosed with quotes otherwise v2.3.0 becomes v2 0.3 .0
|
||||
$version: "v2.7.9";
|
||||
$version: "v2.7.10";
|
||||
$approot-relative: "../../../../../" !default; // relative to env-***/branding/themes/***/main.css
|
||||
|
||||
// Base colors
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'authent-cas/2.7.9',
|
||||
'authent-cas/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'authent-external/2.7.9',
|
||||
'authent-external/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -9,7 +9,7 @@ if (function_exists('ldap_connect'))
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'authent-ldap/2.7.9',
|
||||
'authent-ldap/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'authent-local/2.7.9',
|
||||
'authent-local/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
/** @noinspection PhpUnhandledExceptionInspection */
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'combodo-db-tools/2.7.9',
|
||||
'combodo-db-tools/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-attachments/2.7.9',
|
||||
'itop-attachments/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-backup/2.7.9',
|
||||
'itop-backup/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-bridge-virtualization-storage/2.7.9',
|
||||
'itop-bridge-virtualization-storage/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-change-mgmt-itil/2.7.9',
|
||||
'itop-change-mgmt-itil/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-change-mgmt/2.7.9',
|
||||
'itop-change-mgmt/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-config-mgmt/2.7.9',
|
||||
'itop-config-mgmt/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-config/2.7.9',
|
||||
'itop-config/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
/** @noinspection PhpUnhandledExceptionInspection */
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-core-update/2.7.9',
|
||||
'itop-core-update/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-datacenter-mgmt/2.7.9',
|
||||
'itop-datacenter-mgmt/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-endusers-devices/2.7.9',
|
||||
'itop-endusers-devices/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
/** @noinspection PhpUnhandledExceptionInspection */
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-files-information/2.7.9',
|
||||
'itop-files-information/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-full-itil/2.7.9',
|
||||
'itop-full-itil/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -7,7 +7,7 @@ class HubConnectorPage extends NiceWebPage
|
||||
parent::__construct($sTitle);
|
||||
|
||||
$this->no_cache();
|
||||
$this->add_xframe_options();
|
||||
$this->add_http_headers();
|
||||
|
||||
$sImagesDir = utils::GetAbsoluteUrlAppRoot().'images';
|
||||
$sModuleImagesDir = utils::GetAbsoluteUrlModulesRoot().'itop-hub-connector/images';
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-hub-connector/2.7.9',
|
||||
'itop-hub-connector/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-incident-mgmt-itil/2.7.9',
|
||||
'itop-incident-mgmt-itil/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-knownerror-mgmt/2.7.9',
|
||||
'itop-knownerror-mgmt/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-oauth-client/2.7.9',
|
||||
'itop-oauth-client/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
/** @noinspection PhpUnhandledExceptionInspection */
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-portal-base/2.7.9', array(
|
||||
'itop-portal-base/2.7.10', array(
|
||||
// Identification
|
||||
'label' => 'Portal Development Library',
|
||||
'category' => 'Portal',
|
||||
|
||||
@@ -1150,14 +1150,14 @@ class ObjectFormManager extends FormManager
|
||||
// Writing object to DB
|
||||
try
|
||||
{
|
||||
$this->oObject->CheckChangedExtKeysValues(function ($sClass, $sId) use ($oSecurityHelper): bool {
|
||||
return $oSecurityHelper->IsActionAllowed(UR_ACTION_READ, $sClass, $sId);
|
||||
});
|
||||
$this->oObject->DBWrite();
|
||||
} catch (CoreCannotSaveObjectException $e) {
|
||||
throw new Exception($e->getHtmlMessage());
|
||||
} catch (InvalidExternalKeyValueException $e) {
|
||||
throw new Exception($e->getIssue());
|
||||
$sExceptionMessage = $e->getIssue();
|
||||
$sExceptionMessage .= var_export($e->getContextData(), true);
|
||||
|
||||
throw new Exception($sExceptionMessage);
|
||||
} catch (Exception $e) {
|
||||
if ($bIsNew) {
|
||||
throw new Exception(Dict::S('Portal:Error:ObjectCannotBeCreated'));
|
||||
@@ -1368,6 +1368,12 @@ class ObjectFormManager extends FormManager
|
||||
}
|
||||
}
|
||||
}
|
||||
/** @var SecurityHelper $oSecurityHelper */
|
||||
$oSecurityHelper = $this->oContainer->get('security_helper');
|
||||
// N°7023 - Note that we check for ext. key now as we want the check to be done on user inputs and NOT on ext. keys set programatically, so it must be done before the DoComputeValues
|
||||
$this->oObject->CheckChangedExtKeysValues(function ($sClass, $sId) use ($oSecurityHelper): bool {
|
||||
return $oSecurityHelper->IsActionAllowed(UR_ACTION_READ, $sClass, $sId);
|
||||
});
|
||||
$this->oObject->DoComputeValues();
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
/** @noinspection PhpUnhandledExceptionInspection */
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-portal/2.7.9', array(
|
||||
'itop-portal/2.7.10', array(
|
||||
// Identification
|
||||
'label' => 'Enhanced Customer Portal',
|
||||
'category' => 'Portal',
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-problem-mgmt/2.7.9',
|
||||
'itop-problem-mgmt/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-profiles-itil/2.7.9',
|
||||
'itop-profiles-itil/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-request-mgmt-itil/2.7.9',
|
||||
'itop-request-mgmt-itil/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-request-mgmt/2.7.9',
|
||||
'itop-request-mgmt/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-service-mgmt-provider/2.7.9',
|
||||
'itop-service-mgmt-provider/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-service-mgmt/2.7.9',
|
||||
'itop-service-mgmt/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-sla-computation/2.7.9',
|
||||
'itop-sla-computation/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-storage-mgmt/2.7.9',
|
||||
'itop-storage-mgmt/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__,
|
||||
'itop-tickets/2.7.9',
|
||||
'itop-tickets/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-virtualization-mgmt/2.7.9',
|
||||
'itop-virtualization-mgmt/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-welcome-itil/2.7.9',
|
||||
'itop-welcome-itil/2.7.10',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<information>
|
||||
<version>2.7.9</version>
|
||||
<version>2.7.10</version>
|
||||
</information>
|
||||
|
||||
@@ -67,7 +67,7 @@ try
|
||||
|
||||
// X-Frame http header : set in page constructor, but we need to allow frame integration for this specific page
|
||||
// so we're resetting its value ! (see N°3416)
|
||||
$oPage->add_xframe_options('');
|
||||
$oPage->add_http_headers('');
|
||||
|
||||
$oPage->add_header("Last-Modified: Wed, 15 Jun 2015 13:21:15 GMT"); // An arbitrary date in the past is ok
|
||||
}
|
||||
@@ -88,7 +88,7 @@ try
|
||||
|
||||
// X-Frame http header : set in page constructor, but we need to allow frame integration for this specific page
|
||||
// so we're resetting its value ! (see N°3416)
|
||||
$oPage->add_xframe_options('');
|
||||
$oPage->add_http_headers('');
|
||||
|
||||
$oPage->add_header("Last-Modified: Wed, 15 Jun 2016 13:21:15 GMT"); // An arbitrary date in the past is ok
|
||||
}
|
||||
@@ -103,7 +103,7 @@ try
|
||||
|
||||
// X-Frame http header : set in page constructor, but we need to allow frame integration for this specific page
|
||||
// so we're resetting its value ! (see N°3416)
|
||||
$oPage->add_xframe_options('');
|
||||
$oPage->add_http_headers('');
|
||||
|
||||
$oPage->add(file_get_contents(Utils::GetCachePath().$sSignature.'.js'));
|
||||
break;
|
||||
|
||||
@@ -1036,7 +1036,7 @@ try
|
||||
|
||||
// X-Frame http header : set in page constructor, but we need to allow frame integration for this specific page
|
||||
// so we're resetting its value ! (see N°3416)
|
||||
$oPage->add_xframe_options('');
|
||||
$oPage->add_http_headers('');
|
||||
|
||||
// N°4129 - Prevent XSS attacks & other script executions
|
||||
if (utils::GetConfig()->Get('security.disable_inline_documents_sandbox') === false) {
|
||||
|
||||
@@ -305,9 +305,8 @@ class DBBackup
|
||||
// Store the results in a temporary file
|
||||
$sTmpFileName = self::EscapeShellArg($sBackupFileName);
|
||||
|
||||
$sPortOption = self::GetMysqliCliSingleOption('port', $this->iDBPort);
|
||||
$sPortAndTransportOptions = self::GetMysqlCliPortAndTransportOptions($this->sDBHost, $this->iDBPort);
|
||||
$sTlsOptions = self::GetMysqlCliTlsOptions($this->oConfig);
|
||||
$sProtocolOption = self::GetMysqlCliTransportOption($this->sDBHost);
|
||||
|
||||
$sMysqlVersion = CMDBSource::GetDBVersion();
|
||||
$bIsMysqlSupportUtf8mb4 = (version_compare($sMysqlVersion, self::MYSQL_VERSION_WITH_UTF8MB4_IN_PROGRAMS) === -1);
|
||||
@@ -326,10 +325,10 @@ EOF;
|
||||
chmod($sMySQLDumpCnfFile, 0600);
|
||||
file_put_contents($sMySQLDumpCnfFile, $sMySQLDumpCnf, LOCK_EX);
|
||||
|
||||
// Note: opt implicitely sets lock-tables... which cancels the benefit of single-transaction!
|
||||
// Note: opt implicitly sets lock-tables... which cancels the benefit of single-transaction!
|
||||
// skip-lock-tables compensates and allows for writes during a backup
|
||||
$sCommand = "$sMySQLDump --defaults-extra-file=\"$sMySQLDumpCnfFile\" --opt --skip-lock-tables --default-character-set=".$sMysqldumpCharset." --add-drop-database --single-transaction --host=$sHost $sPortOption $sProtocolOption --user=$sUser $sTlsOptions --result-file=$sTmpFileName $sDBName $sTables 2>&1";
|
||||
$sCommandDisplay = "$sMySQLDump --defaults-extra-file=\"$sMySQLDumpCnfFile\" --opt --skip-lock-tables --default-character-set=".$sMysqldumpCharset." --add-drop-database --single-transaction --host=$sHost $sPortOption $sProtocolOption --user=xxxxx $sTlsOptions --result-file=$sTmpFileName $sDBName $sTables";
|
||||
$sCommand = "$sMySQLDump --defaults-extra-file=\"$sMySQLDumpCnfFile\" --opt --skip-lock-tables --default-character-set=" . $sMysqldumpCharset . " --add-drop-database --single-transaction --host=$sHost $sPortAndTransportOptions --user=$sUser $sTlsOptions --result-file=$sTmpFileName $sDBName $sTables 2>&1";
|
||||
$sCommandDisplay = "$sMySQLDump --defaults-extra-file=\"$sMySQLDumpCnfFile\" --opt --skip-lock-tables --default-character-set=" . $sMysqldumpCharset . " --add-drop-database --single-transaction --host=$sHost $sPortAndTransportOptions --user=xxxxx $sTlsOptions --result-file=$sTmpFileName $sDBName $sTables";
|
||||
|
||||
// Now run the command for real
|
||||
$this->LogInfo("backup: generate data file with command: $sCommandDisplay");
|
||||
@@ -523,25 +522,37 @@ EOF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define if we should force a transport option
|
||||
*
|
||||
* @param string $sHost
|
||||
* @return string CLI options for port and protocol
|
||||
*
|
||||
* @return string .
|
||||
|
||||
* @since 2.7.9 3.0.4 3.1.1 N°6123
|
||||
* @since 2.7.9 3.0.4 3.1.1 N°6123 method creation
|
||||
* @since 2.7.10 3.0.4 3.1.2 3.2.0 N°6889 rename method to return both port and transport options. Keep default socket connexion if we are on localhost with no port
|
||||
*
|
||||
* @link https://bugs.mysql.com/bug.php?id=55796 MySQL CLI tools will ignore `--port` option on localhost
|
||||
* @link https://jira.mariadb.org/browse/MDEV-14974 Since 10.6.1 the MariaDB CLI tools will use the `--port` option on host=localhost
|
||||
*/
|
||||
public static function GetMysqlCliTransportOption(string $sHost)
|
||||
private static function GetMysqlCliPortAndTransportOptions(string $sHost, ?int $iPort): string
|
||||
{
|
||||
$sTransportOptions = '';
|
||||
|
||||
/** N°6123 As we're using a --port option, if we use localhost as host,
|
||||
* MariaDB > 10.6 will implicitly change its protocol from socket to tcp and throw a warning **/
|
||||
if($sHost === 'localhost'){
|
||||
$sTransportOptions = '--protocol=tcp';
|
||||
if (strtolower($sHost) === 'localhost') {
|
||||
/**
|
||||
* Since MariaDB 10.6.1 if we have host=localhost, and only the --port option we will get a warning
|
||||
* To avoid this warning if we want to set --port option we must set --protocol=tcp
|
||||
**/
|
||||
if (is_null($iPort)) {
|
||||
// no port specified => no option to return, this will mean using socket protocol (unix socket)
|
||||
return '';
|
||||
}
|
||||
|
||||
$sPortOption = self::GetMysqliCliSingleOption('port', $iPort);
|
||||
$sTransportOptions = ' --protocol=tcp';
|
||||
return $sPortOption . $sTransportOptions;
|
||||
}
|
||||
|
||||
return $sTransportOptions;
|
||||
if (is_null($iPort)) {
|
||||
$iPort = CMDBSource::MYSQL_DEFAULT_PORT;
|
||||
}
|
||||
$sPortOption = self::GetMysqliCliSingleOption('port', $iPort);
|
||||
|
||||
return $sPortOption;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -38,7 +38,7 @@ $oP = new SetupPage('iTop email test utility');
|
||||
|
||||
// Although this page doesn't expose sensitive info, with it we can send multiple emails
|
||||
// So we're adding this http header to reduce CSRF exposure...
|
||||
$oP->add_xframe_options('DENY');
|
||||
$oP->add_http_headers('DENY');
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -576,7 +576,7 @@ abstract class Controller
|
||||
{
|
||||
case 'html':
|
||||
$this->m_oPage = new iTopWebPage($this->GetOperationTitle());
|
||||
$this->m_oPage->add_xframe_options();
|
||||
$this->m_oPage->add_http_headers();
|
||||
|
||||
if ($this->m_bIsBreadCrumbEnabled) {
|
||||
if (count($this->m_aBreadCrumbEntry) > 0) {
|
||||
|
||||
@@ -782,7 +782,7 @@ try
|
||||
|
||||
case 'create_structure':
|
||||
$oP->no_cache();
|
||||
$oP->add_xframe_options('DENY');
|
||||
$oP->add_http_headers('DENY');
|
||||
$iPlannedContacts = Utils::ReadParam('plannedcontacts');
|
||||
$iPlannedContracts = Utils::ReadParam('plannedcontracts');
|
||||
|
||||
|
||||
@@ -23,21 +23,31 @@ namespace Combodo\iTop\Test\UnitTest\ReleaseChecklist;
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
use iTopDesignFormat;
|
||||
use utils;
|
||||
|
||||
|
||||
/**
|
||||
* Class iTopDesignFormatChecklistTest
|
||||
*
|
||||
* @covers iTopDesignFormat
|
||||
* Class SetupCssIntegrityChecklistTest
|
||||
*/
|
||||
class SetupCssIntegrityChecklistTest extends ItopTestCase
|
||||
{
|
||||
public function testSetupCssIntegrity()
|
||||
{
|
||||
$sSetupCssPath = APPROOT.'css/setup.css';
|
||||
$sSetupCssContent = file_get_contents($sSetupCssPath);
|
||||
$this->assertContains('/* integrityCheck: begin (do not remove/edit) */', $sSetupCssContent);
|
||||
$this->assertContains('/* integrityCheck: end (do not remove/edit) */', $sSetupCssContent);
|
||||
$this->assertGreaterThan(4000, strlen($sSetupCssContent), "Test if the resulting file $sSetupCssPath is long enough, the value is totally arbitrary (at the time of the writing the file is 5660o long");
|
||||
$sCssFileAbsPath = APPROOT."css/setup.css";
|
||||
|
||||
// First check if the compiled file exists
|
||||
$this->assertTrue(file_exists($sCssFileAbsPath));
|
||||
|
||||
// Then check that it is not empty
|
||||
$sVersionedCssFileContent = file_get_contents($sCssFileAbsPath);
|
||||
$this->assertGreaterThan(0, strlen($sVersionedCssFileContent), "Compiled setup.css file seems empty");
|
||||
|
||||
// Then check that the compiled file is up-to-date
|
||||
$sScssFileRelPath = "css/setup.scss";
|
||||
$sScssFileAbsPath = APPROOT . $sScssFileRelPath;
|
||||
touch($sScssFileAbsPath);
|
||||
utils::GetCSSFromSASS($sScssFileRelPath);
|
||||
$sCompiledCssFileContent = file_get_contents($sCssFileAbsPath);
|
||||
$this->assertSame($sCompiledCssFileContent, $sVersionedCssFileContent, "Compiled setup.css file does not seem up to date as the one compiled just now is different");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,4 +135,37 @@ class CMDBSourceTest extends ItopTestCase
|
||||
$bIsTlsCnx = $this->InvokeNonPublicStaticMethod(CMDBSource::class, 'IsOpenedDbConnectionUsingTls',[$oMysqli]);
|
||||
$this->assertFalse($bIsTlsCnx);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider InitServerAndPortProvider
|
||||
* @since 2.7.10 3.0.4 3.1.2 3.2.0 N°6889 method creation to keep track of the behavior change (port will return null)
|
||||
*/
|
||||
public function testInitServerAndPort(string $sDbHost, string $sExpectedServer, ?int $iExpectedPort)
|
||||
{
|
||||
$sActualServer = null;
|
||||
$iActualPort = null;
|
||||
CMDBSource::InitServerAndPort($sDbHost, $sActualServer, $iActualPort);
|
||||
|
||||
$this->assertNotNull($sActualServer);
|
||||
$this->assertEquals($sExpectedServer, $sActualServer);
|
||||
$this->assertEquals($iExpectedPort, $iActualPort);
|
||||
}
|
||||
|
||||
public function InitServerAndPortProvider()
|
||||
{
|
||||
return [
|
||||
'localhost no port' => ['localhost', 'localhost', null],
|
||||
'localhost with port' => ['localhost:333306', 'localhost', 333306],
|
||||
'persistent localhost no port' => ['p:localhost', 'p:localhost', null],
|
||||
'persistent localhost with port' => ['p:localhost:333306', 'p:localhost', 333306],
|
||||
'ip no port' => ['192.168.1.10', '192.168.1.10', null],
|
||||
'ip with port' => ['192.168.1.10:333306', '192.168.1.10', 333306],
|
||||
'persistent ip no port' => ['p:192.168.1.10', 'p:192.168.1.10', null],
|
||||
'persistent ip with port' => ['p:192.168.1.10:333306', 'p:192.168.1.10', 333306],
|
||||
'domain no port' => ['dbserver.mycompany.com', 'dbserver.mycompany.com', null],
|
||||
'domain with port' => ['dbserver.mycompany.com:333306', 'dbserver.mycompany.com', 333306],
|
||||
'persistent domain no port' => ['p:dbserver.mycompany.com', 'p:dbserver.mycompany.com', null],
|
||||
'persistent domain with port' => ['p:dbserver.mycompany.com:333306', 'p:dbserver.mycompany.com', 333306],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,6 +244,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
$oPersonLinks = \DBObjectSet::FromScratch(lnkPersonToTeam::class);
|
||||
$oPersonLinks->AddObject(MetaModel::NewObject(lnkPersonToTeam::class, [
|
||||
'person_id' => self::INVALID_OBJECT_KEY,
|
||||
'team_id' => $oTeam->GetKey(),
|
||||
]));
|
||||
$oTeam->Set('persons_list', $oPersonLinks);
|
||||
|
||||
@@ -268,6 +269,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
$oPersonLinks = \DBObjectSet::FromScratch(lnkPersonToTeam::class);
|
||||
$oPersonLinks->AddObject(MetaModel::NewObject(lnkPersonToTeam::class, [
|
||||
'person_id' => $oPersonOnDemoOrg->GetKey(),
|
||||
'team_id' => $oTeam->GetKey(),
|
||||
]));
|
||||
$oTeam->Set('persons_list', $oPersonLinks);
|
||||
|
||||
@@ -289,6 +291,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
$oPersonLinks = \DBObjectSet::FromScratch(lnkPersonToTeam::class);
|
||||
$oPersonLinks->AddObject(MetaModel::NewObject(lnkPersonToTeam::class, [
|
||||
'person_id' => $oPersonOnItDepartmentOrg->GetKey(),
|
||||
'team_id' => $oTeam->GetKey(),
|
||||
]));
|
||||
$oTeam->Set('persons_list', $oPersonLinks);
|
||||
|
||||
|
||||
@@ -86,29 +86,44 @@ class DBBackupTest extends ItopTestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* Host is localhost, we should be forced into tcp
|
||||
*
|
||||
* @return void
|
||||
* @dataProvider GetMysqlCliPortAndTransportOptionsProvider
|
||||
* @since 2.7.10 3.0.4 3.1.2 3.2.0 test for N°6123 and N°6889
|
||||
*/
|
||||
public function testGetMysqlCliTransportOptionWithLocalhost()
|
||||
public function testGetMysqlCliPortAndTransportOptions(string $sDbHost, ?int $iPort, ?int $iExpectedPortValue, string $sExpectedProtocolCliOption)
|
||||
{
|
||||
$sHost= 'localhost';
|
||||
$sTransport = DBBackup::GetMysqlCliTransportOption($sHost);
|
||||
if (is_null($iExpectedPortValue)) {
|
||||
$sExpectedPortCliOption = '';
|
||||
} else {
|
||||
$sEscapedPortValue = \DBBackup::EscapeShellArg($iExpectedPortValue);
|
||||
$sExpectedPortCliOption = ' --port=' . $sEscapedPortValue;
|
||||
}
|
||||
|
||||
$this->assertStringStartsWith('--protocol=tcp', $sTransport);
|
||||
$this->assertStringEndsWith('--protocol=tcp', $sTransport);
|
||||
$sActualCliOptions = $this->InvokeNonPublicStaticMethod(DBBackup::class, 'GetMysqlCliPortAndTransportOptions', [$sDbHost, $iPort]);
|
||||
$this->assertEquals($sExpectedPortCliOption . $sExpectedProtocolCliOption, $sActualCliOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Host is not localhost, we shouldn't be forced into tcp
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetMysqlCliTransportOptionWithoutLocalhost()
|
||||
public function GetMysqlCliPortAndTransportOptionsProvider()
|
||||
{
|
||||
$sHost= '127.0.0.1';
|
||||
$sTransport = DBBackup::GetMysqlCliTransportOption($sHost);
|
||||
$iTestPort = 333306;
|
||||
$iDefaultPort = 3306; // cannot access \CMDBSource::MYSQL_DEFAULT_PORT in dataprovider :(
|
||||
|
||||
$this->assertEmpty($sTransport);
|
||||
return [
|
||||
'Localhost no port' => ['localhost', null, null, ''],
|
||||
'Localhost with port' => ['localhost', $iTestPort, $iTestPort, ' --protocol=tcp'],
|
||||
|
||||
// we want both port and protocol for 127.0.0.1, because it is an ip address so using tcp/ip stack !
|
||||
'127.0.0.1 no port' => ['127.0.0.1', null, $iDefaultPort, ''],
|
||||
'127.0.0.1 with port' => ['127.0.0.1', $iTestPort, $iTestPort, ''],
|
||||
|
||||
'IP no port' => ['192.168.1.15', null, $iDefaultPort, ''],
|
||||
'IP with port' => ['192.168.1.15', $iTestPort, $iTestPort, ''],
|
||||
|
||||
'DNS no port' => ['dbserver.mycompany.com', null, $iDefaultPort, ''],
|
||||
'DNS with port' => ['dbserver.mycompany.com', $iTestPort, $iTestPort, ''],
|
||||
|
||||
'Windows name no port' => ['dbserver', null, $iDefaultPort, ''],
|
||||
'Windows name with port' => ['dbserver', $iTestPort, $iTestPort, ''],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ function ReportErrorAndExit($sErrorMessage)
|
||||
else
|
||||
{
|
||||
$oP = new WebPage("iTop - Export");
|
||||
$oP->add_xframe_options();
|
||||
$oP->add_http_headers();
|
||||
$oP->p('ERROR: '.$sErrorMessage);
|
||||
$oP->output();
|
||||
exit(-1);
|
||||
@@ -63,7 +63,7 @@ function ReportErrorAndUsage($sErrorMessage)
|
||||
}
|
||||
else {
|
||||
$oP = new WebPage("iTop - Export");
|
||||
$oP->add_xframe_options();
|
||||
$oP->add_http_headers();
|
||||
$oP->p('ERROR: '.$sErrorMessage);
|
||||
Usage($oP);
|
||||
$oP->output();
|
||||
@@ -729,14 +729,14 @@ try
|
||||
// Note: Using NiceWebPage only for HTML export as it includes JS scripts & files, which makes no sense in other export formats. More over, it breaks Excel spreadsheet import.
|
||||
if($oExporter instanceof HTMLBulkExport) {
|
||||
$oP = new NiceWebPage('iTop export');
|
||||
$oP->add_xframe_options();
|
||||
$oP->add_http_headers();
|
||||
$oP->add_ready_script("$('table.listResults').tablesorter({widgets: ['MyZebra']});");
|
||||
$oP->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/font-awesome/css/all.min.css');
|
||||
$oP->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/font-awesome/css/v4-shims.min.css');
|
||||
}
|
||||
else {
|
||||
$oP = new WebPage('iTop export');
|
||||
$oP->add_xframe_options();
|
||||
$oP->add_http_headers();
|
||||
$oP->add_style("table br { mso-data-placement:same-cell; }"); // Trick for Excel: keep line breaks inside the same cell !
|
||||
}
|
||||
$oP->add_style("body { overflow: auto; }");
|
||||
@@ -759,7 +759,7 @@ catch (BulkExportMissingParameterException $e)
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$oP = new WebPage('iTop Export');
|
||||
$oP->add_xframe_options();
|
||||
$oP->add_http_headers();
|
||||
$oP->add('Error: '.utils::HtmlEntities($e->getMessage()));
|
||||
IssueLog::Error(utils::HtmlEntities($e->getMessage())."\n".$e->getTraceAsString());
|
||||
$oP->output();
|
||||
|
||||
Reference in New Issue
Block a user