Compare commits

...

46 Commits

Author SHA1 Message Date
odain
948bcb032a N°5341 - fix test 2023-04-07 07:06:32 +02:00
odain
128e7eed42 N°5341 - start testing ormcaselog rebuild when broken 2023-04-06 17:30:06 +02:00
odain
1b0dedaf31 N°5341 - refactoring to have a dedicated ormcase log service 2023-04-06 17:24:32 +02:00
Eric Espie
8d711fb37b N°5341 - Repair misalignment between case-log and case-log index (update only) 2023-02-03 15:51:43 +01:00
Pierre Goiffon
f65e14397c N°4660 Fix permissions changes in tests 2023-01-16 11:22:23 +01:00
Pierre Goiffon
c696a81c3a N°5821 JenkinsFile : introduce buildDiscarder 2023-01-12 10:42:06 +01:00
Molkobain
845adf43c6 N°5608 - Harmonize namespaces and merge duplicated test files 2023-01-10 22:36:35 +01:00
Molkobain
5916e4ea39 N°5608 - Ensure both old & new tests structure are ran for extensions for backward compatibility 2023-01-10 22:03:40 +01:00
Molkobain
fbc0a898ae N°5608 - Move test files to corresponding directories after branch rebase 2023-01-10 12:11:12 +01:00
Molkobain
36f8e58e25 N°5608 - Use new ItopTestCase::RequireOnceXXX in unit tests 2023-01-10 12:11:12 +01:00
Molkobain
6a7dbb06b0 N°5608 - Add methods to require_once an iTop or a unit test file to avoid crashes when tests dir is moved 2023-01-10 12:11:12 +01:00
Molkobain
5721a324c1 Tests: Always display test status for better feedback 2023-01-06 22:30:09 +01:00
Molkobain
7de6c72154 Tests: Rename provider method name to match convention 2023-01-06 22:30:09 +01:00
Molkobain
c0cee02351 N°5608 - Factorize all core modules tests to a single test suite 2023-01-06 22:30:09 +01:00
Molkobain
bb674fb873 N°5608 - Move/rename "status" unit tests to match their counterpart location/name 2023-01-06 22:30:09 +01:00
Molkobain
6136eadd31 N°5608 - Fix some broken require paths since move/rename 2023-01-06 22:30:08 +01:00
Molkobain
87cb73c038 N°5608 - Rename "test" folder to "tests" to better match conventions 2023-01-06 22:30:08 +01:00
Molkobain
11d8547cef N°5608 - Move/rename unit tests to match their counterpart location/name 2023-01-06 22:30:08 +01:00
Molkobain
0998c73a1a N°5608 - Add README files 2023-01-06 22:30:07 +01:00
Molkobain
471f66649a N°5608 - Rename unitary test folders for better understanding 2023-01-06 22:30:07 +01:00
Molkobain
e8bf9cf688 N°5608 - Move "twig" PHP unit test to new folder
Notice: Test was not working, still not working
2023-01-06 22:30:07 +01:00
Molkobain
4f88a0e7d2 N°5608 - Move legacy PHP unit tests (not run by CI) to a dedicated folder 2023-01-06 22:30:07 +01:00
Molkobain
c6b0e273e6 N°5608 - Rename "VisualTests" folder to match new convention 2023-01-06 22:30:07 +01:00
Molkobain
d9539f9d01 N°5608 - Add comments to main autoloader 2023-01-06 22:30:06 +01:00
Molkobain
a3e309acb5 N°5608 - Revert "authent-local" test suite to its original rank as it is crashing the CI 🤔 2023-01-06 22:30:06 +01:00
Molkobain
c06cbfd4a9 N°5608 - Rename "coreExtensions" test suite to correct datamodel module (authent-local) 2023-01-06 22:30:06 +01:00
Molkobain
1d7e4e1a42 N°5608 - Move unit tests to a dedicated folder and start reorganizing to match iTop folder structure 2023-01-06 22:30:06 +01:00
Eric Espie
92a36dcfdd 📝 Change packages for auto-documentation 2022-12-29 12:24:56 +01:00
Eric Espie
b37e74b407 📝 Change packages for auto-documentation 2022-12-28 09:51:46 +01:00
Pierre Goiffon
0d49c605e2 💡 Fix \DBSearch::FromOQL phpdoc + modifiers order 2022-12-15 15:36:14 +01:00
Molkobain
7c2f8f4d93 N°5765 - Setup: Never cache folder permissions test response (#374) 2022-12-14 09:33:54 +01:00
Pierre Goiffon
1f76ff940d N°5797 Replace wrong config load (#338) 2022-12-13 18:23:09 +01:00
Eric Espie
bb26e48d38 Update version to next release 2.7.9 2022-12-12 16:19:42 +01:00
Eric Espie
cf433f2f80 N°5725 - Twig update 'filter', 'map' and 'reduce' filters 2022-12-08 08:25:11 +01:00
Eric Espie
ae94e58a43 N°5725 - Twig update 'filter', 'map' and 'reduce' filters 2022-12-07 13:53:15 +01:00
Eric Espie
cda017fa4f N°5725 - Twig update 'filter', 'map' and 'reduce' filters 2022-12-07 13:37:52 +01:00
Pierre Goiffon
dad22f6f83 📄 Update Licenses 2022-12-07 11:04:33 +01:00
Eric Espie
9077f7ba37 N°5430 - OAuth authentication : customize redirect landing URL - remove unnecessary parameter to JS function OAuthConnect 2022-12-02 11:17:01 +01:00
Eric Espie
957ff40f30 N°5155 - Email by SMTP with self-signed certificate (changed default values to the previous behaviour) 2022-12-02 09:25:53 +01:00
Eric Espie
aff9c7748b N°5155 - Email by SMTP with self-signed certificate 2022-11-30 14:18:11 +01:00
Eric Espie
e518d34bc9 N°5553 - OAuth 2 : Hide Client Secret
* client_id is now 255 chars (AttributeString)
 * client_secret is now 64 chars (AttributePassword) and cannot be anymore in the uniqueness rules
 * The modification of redirect_url, client_id or client_secret change the status to inactive and generate a session message to ask for token regeneration
2022-11-30 14:15:37 +01:00
Eric Espie
f0141530b9 N°5725 - Twig update 'filter', 'map' and 'reduce' filters (+1 squashed commits)
Squashed commits:

[00148dec5] N°5725 - Twig update 'filter', 'map' and 'reduce' filters
2022-11-30 13:28:33 +01:00
xtophe38
ce5096a896 N°5758 Change setup test for GDPR consent (#336)
We were using SetupUtils::IsProductVersion, but this was blocking for certain packages like TeemIP standalone.
After this change we are now relying on a new method : \SetupUtils::IsConnectableToITopHub. It will check the iTop Hub Connector module presence instead.
2022-11-29 19:00:17 +01:00
Pierre Goiffon
23e0ed5e56 N°4449 Test for FPD detection in RuntimeDashboard 2022-11-29 18:10:17 +01:00
Pierre Goiffon
d412a52fcc N°4449 Fix FPD in dashboard export/import 2022-11-29 18:10:17 +01:00
Molkobain
3e18ad590f Fix image attributes not being visible in PDF exports 2022-11-25 19:30:35 +01:00
177 changed files with 1257 additions and 2088 deletions

4
.gitignore vendored
View File

@@ -8,7 +8,7 @@
# composer reserver directory, from sources, populate/update using "composer install"
vendor/*
test/vendor/*
tests/*/vendor/*
# all conf but listing prevention
/conf/**
@@ -33,7 +33,7 @@ test/vendor/*
!/log/web.config
# PHPUnit cache file
/test/.phpunit.result.cache
/tests/php-unit-tests/.phpunit.result.cache
# Jetbrains

8
Jenkinsfile vendored
View File

@@ -1,6 +1,14 @@
def infra
node(){
properties([
buildDiscarder(
logRotator(
daysToKeepStr: "28",
numToKeepStr: "500")
)
])
checkout scm
infra = load '/var/lib/jenkins/workspace/itop-test-infra_master/src/Infra.groovy'

View File

@@ -29,9 +29,9 @@ require_once(APPROOT.'application/newsroomprovider.class.inc.php');
* You may implement such interfaces in a module file (e.g. main.mymodule.php)
*
* @api
* @package LoginExtensibilityAPI
* @copyright Copyright (C) 2010-2012 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
* @package Extensibility
* @since 2.7.0
*/
interface iLoginExtension
@@ -39,12 +39,16 @@ interface iLoginExtension
/**
* Return the list of supported login modes for this plugin
*
* @api
*
* @return array of supported login modes
*/
public function ListSupportedLoginModes();
}
/**
* @api
* @package LoginExtensibilityAPI
* @since 2.7.0
*/
interface iLoginFSMExtension extends iLoginExtension
@@ -56,6 +60,7 @@ interface iLoginFSMExtension extends iLoginExtension
* if LoginWebPage::LOGIN_FSM_RETURN_OK is returned then the login is OK and terminated
* if LoginWebPage::LOGIN_FSM_RETURN_IGNORE is returned then the FSM will proceed to next plugin or state
*
* @api
* @param string $sLoginState (see LoginWebPage::LOGIN_STATE_...)
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
*
@@ -65,6 +70,8 @@ interface iLoginFSMExtension extends iLoginExtension
}
/**
* @api
* @package LoginExtensibilityAPI
* @since 2.7.0
*/
abstract class AbstractLoginFSMExtension implements iLoginFSMExtension
@@ -111,6 +118,7 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension
/**
* Initialization
*
* @api
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
*
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
@@ -124,6 +132,7 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension
* Detect login mode explicitly without respecting configured order (legacy mode)
* In most case do nothing here
*
* @api
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
*
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
@@ -140,6 +149,7 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension
* 1 - display login form
* 2 - read the values posted by the user
*
* @api
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
*
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
@@ -153,6 +163,7 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension
* Control the validity of the data provided by the user
* Automatic user provisioning can be done here
*
* @api
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
*
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
@@ -163,6 +174,7 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension
}
/**
* @api
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
*
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
@@ -173,6 +185,7 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension
}
/**
* @api
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
*
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
@@ -183,6 +196,7 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension
}
/**
* @api
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
*
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
@@ -193,6 +207,7 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension
}
/**
* @api
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
*
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
@@ -204,22 +219,28 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension
}
/**
* @api
* @package LoginExtensibilityAPI
* @since 2.7.0
*/
interface iLogoutExtension extends iLoginExtension
{
/**
* Execute all actions to log out properly
* @api
*/
public function LogoutAction();
}
/**
* @api
* @package UIExtensibilityAPI
* @since 2.7.0
*/
interface iLoginUIExtension extends iLoginExtension
{
/**
* @api
* @return LoginTwigContext
*/
public function GetTwigContext();
@@ -227,18 +248,20 @@ interface iLoginUIExtension extends iLoginExtension
/**
* @api
* @package Extensibility
* @package PreferencesExtensibilityAPI
* @since 2.7.0
*/
interface iPreferencesExtension
{
/**
* @api
* @param \WebPage $oPage
*
*/
public function DisplayPreferences(WebPage $oPage);
/**
* @api
* @param \WebPage $oPage
* @param string $sOperation
*
@@ -251,7 +274,7 @@ interface iPreferencesExtension
* Extend this class instead of implementing iPreferencesExtension if you don't need to overload all methods
*
* @api
* @package Extensibility
* @package PreferencesExtensibilityAPI
* @since 2.7.0
*/
abstract class AbstractPreferencesExtension implements iPreferencesExtension
@@ -297,7 +320,7 @@ abstract class AbstractPreferencesExtension implements iPreferencesExtension
* A recommended pattern is to cache data by the mean of static members.
*
* @api
* @package Extensibility
* @package UIExtensibilityAPI
*/
interface iApplicationUIExtension
{
@@ -319,6 +342,7 @@ interface iApplicationUIExtension
* }
* </code>
*
* @api
* @param DBObject $oObject The object being displayed
* @param WebPage $oPage The output context
* @param boolean $bEditMode True if the edition form is being displayed
@@ -332,6 +356,7 @@ interface iApplicationUIExtension
*
* The method is called rigth after all the tabs have been displayed
*
* @api
* @param DBObject $oObject The object being displayed
* @param WebPage $oPage The output context
* @param boolean $bEditMode True if the edition form is being displayed
@@ -346,6 +371,7 @@ interface iApplicationUIExtension
* The method is called after the changes from the standard form have been
* taken into account, and before saving the changes into the database.
*
* @api
* @param DBObject $oObject The object being edited
* @param string $sFormPrefix Prefix given to the HTML form inputs
*
@@ -360,6 +386,7 @@ interface iApplicationUIExtension
* javascript into the edition form, and if that code requires to store temporary data
* (this is the case when a file must be uploaded).
*
* @api
* @param string $sTempId Unique temporary identifier made of session_id and transaction_id. It identifies the object in a unique way.
*
* @return void
@@ -371,6 +398,7 @@ interface iApplicationUIExtension
*
* Sorry, the verb has been reserved. You must implement it, but it is not called as of now.
*
* @api
* @param DBObject $oObject The object being displayed
*
* @return string[] desc
@@ -382,6 +410,7 @@ interface iApplicationUIExtension
*
* Sorry, the verb has been reserved. You must implement it, but it is not called as of now.
*
* @api
* @param DBObject $oObject The object being displayed
*
* @return string Path of the icon, relative to the modules directory.
@@ -401,6 +430,7 @@ interface iApplicationUIExtension
* * HILIGHT_CLASS_OK
* * HILIGHT_CLASS_NONE
*
* @api
* @param DBObject $oObject The object being displayed
*
* @return integer The value representing the mood of the object
@@ -427,6 +457,7 @@ interface iApplicationUIExtension
*
* See also iPopupMenuExtension for greater flexibility
*
* @api
* @param DBObjectSet $oSet A set of persistent objects (DBObject)
*
* @return string[string]
@@ -438,7 +469,7 @@ interface iApplicationUIExtension
* Extend this class instead of implementing iApplicationUIExtension if you don't need to overload
*
* @api
* @package Extensibility
* @package UIExtensibilityAPI
* @since 2.7.0
*/
abstract class AbstractApplicationUIExtension implements iApplicationUIExtension
@@ -512,7 +543,7 @@ abstract class AbstractApplicationUIExtension implements iApplicationUIExtension
* or through the GUI.
*
* @api
* @package Extensibility
* @package ORMExtensibilityAPI
*/
interface iApplicationObjectExtension
{
@@ -525,6 +556,7 @@ interface iApplicationObjectExtension
* If the extension returns false, then the framework will perform the usual evaluation.
* Otherwise, the answer is definitively "yes, the object has changed".
*
* @api
* @param \cmdbAbstractObject $oObject The target object
*
* @return boolean True if something has changed for the target object
@@ -537,6 +569,7 @@ interface iApplicationObjectExtension
* The GUI calls this verb and reports any issue.
* Anyhow, this API can be called in other contexts such as the CSV import tool.
*
* @api
* @param \cmdbAbstractObject $oObject The target object
*
* @return string[] A list of errors message. An error message is made of one line and it can be displayed to the end-user.
@@ -550,6 +583,7 @@ interface iApplicationObjectExtension
*
* Please not that it is not possible to cascade deletion by this mean: only stopper issues can be handled.
*
* @api
* @param \cmdbAbstractObject $oObject The target object
*
* @return string[] A list of errors message. An error message is made of one line and it can be displayed to the end-user.
@@ -565,6 +599,7 @@ interface iApplicationObjectExtension
* * {@see DBObject::ListPreviousValuesForUpdatedAttributes()} : list of changed attributes and their values before the change
* * {@see DBObject::Get()} : for a given attribute the new value that was persisted
*
* @api
* @param \cmdbAbstractObject $oObject The target object
* @param CMDBChange|null $oChange A change context. Since 2.0 it is fine to ignore it, as the framework does maintain this information
* once for all the changes made within the current page
@@ -580,6 +615,7 @@ interface iApplicationObjectExtension
*
* The method is called right <b>after</b> the object has been written to the database.
*
* @api
* @param \cmdbAbstractObject $oObject The target object
* @param CMDBChange|null $oChange A change context. Since 2.0 it is fine to ignore it, as the framework does maintain this information
* once for all the changes made within the current page
@@ -593,6 +629,7 @@ interface iApplicationObjectExtension
*
* The method is called right <b>before</b> the object will be deleted from the database.
*
* @api
* @param \cmdbAbstractObject $oObject The target object
* @param CMDBChange|null $oChange A change context. Since 2.0 it is fine to ignore it, as the framework does maintain this information
* once for all the changes made within the current page
@@ -606,7 +643,7 @@ interface iApplicationObjectExtension
* Extend this class instead of iApplicationObjectExtension if you don't need to overload all methods
*
* @api
* @package Extensibility
* @package ORMExtensibilityAPI
* @since 2.7.0
*/
abstract class AbstractApplicationObjectExtension implements iApplicationObjectExtension
@@ -666,7 +703,7 @@ abstract class AbstractApplicationObjectExtension implements iApplicationObjectE
* by the application, as long as the class definition is included somewhere in the code
*
* @api
* @package Extensibility
* @package UIExtensibilityAPI
* @since 2.0
*/
interface iPopupMenuExtension
@@ -675,18 +712,21 @@ interface iPopupMenuExtension
* Insert an item into the Actions menu of a list
*
* $param is a DBObjectSet containing the list of objects
* @api
*/
const MENU_OBJLIST_ACTIONS = 1;
/**
* Insert an item into the Toolkit menu of a list
*
* $param is a DBObjectSet containing the list of objects
* @api
*/
const MENU_OBJLIST_TOOLKIT = 2;
/**
* Insert an item into the Actions menu on an object details page
*
* $param is a DBObject instance: the object currently displayed
* @api
*/
const MENU_OBJDETAILS_ACTIONS = 3;
/**
@@ -696,12 +736,14 @@ interface iPopupMenuExtension
* is being displayed.
*
* $param is a Dashboard instance: the dashboard currently displayed
* @api
*/
const MENU_DASHBOARD_ACTIONS = 4;
/**
* Insert an item into the User menu (upper right corner)
*
* $param is null
* @api
*/
const MENU_USER_ACTIONS = 5;
/**
@@ -709,6 +751,7 @@ interface iPopupMenuExtension
*
* $param is an array('portal_id' => $sPortalId, 'object' => $oObject) containing the portal id and a DBObject instance (the object on
* the current line)
* @api
*/
const PORTAL_OBJLISTITEM_ACTIONS = 7;
/**
@@ -716,6 +759,7 @@ interface iPopupMenuExtension
*
* $param is an array('portal_id' => $sPortalId, 'object' => $oObject) containing the portal id and a DBObject instance (the object
* currently displayed)
* @api
*/
const PORTAL_OBJDETAILS_ACTIONS = 8;
@@ -753,6 +797,7 @@ interface iPopupMenuExtension
* This method is called by the framework for each menu.
* The items will be inserted in the menu in the order of the returned array.
*
* @api
* @param int $iMenuId The identifier of the type of menu, as listed by the constants MENU_xxx
* @param mixed $param Depends on $iMenuId, see the constants defined above
*
@@ -765,7 +810,7 @@ interface iPopupMenuExtension
* Base class for the various types of custom menus
*
* @api
* @package Extensibility
* @package UIExtensibilityAPI
* @since 2.0
*/
abstract class ApplicationPopupMenuItem
@@ -826,6 +871,7 @@ abstract class ApplicationPopupMenuItem
}
/**
* @api
* @param $aCssClasses
*/
public function SetCssClasses($aCssClasses)
@@ -836,6 +882,7 @@ abstract class ApplicationPopupMenuItem
/**
* Adds a CSS class to the CSS classes that will be put on the menu item
*
* @api
* @param $sCssClass
*/
public function AddCssClass($sCssClass)
@@ -862,7 +909,7 @@ abstract class ApplicationPopupMenuItem
* Class for adding an item into a popup menu that browses to the given URL
*
* @api
* @package Extensibility
* @package UIExtensibilityAPI
* @since 2.0
*/
class URLPopupMenuItem extends ApplicationPopupMenuItem
@@ -875,6 +922,7 @@ class URLPopupMenuItem extends ApplicationPopupMenuItem
/**
* Constructor
*
* @api
* @param string $sUID The unique identifier of this menu in iTop... make sure you pass something unique enough
* @param string $sLabel The display label of the menu (must be localized)
* @param string $sURL If the menu is an hyperlink, provide the absolute hyperlink here
@@ -898,7 +946,7 @@ class URLPopupMenuItem extends ApplicationPopupMenuItem
* Class for adding an item into a popup menu that triggers some Javascript code
*
* @api
* @package Extensibility
* @package UIExtensibilityAPI
* @since 2.0
*/
class JSPopupMenuItem extends ApplicationPopupMenuItem
@@ -950,7 +998,7 @@ class JSPopupMenuItem extends ApplicationPopupMenuItem
* will automatically reduce several consecutive separators to just one
*
* @api
* @package Extensibility
* @package UIExtensibilityAPI
* @since 2.0
*/
class SeparatorPopupMenuItem extends ApplicationPopupMenuItem
@@ -959,6 +1007,7 @@ class SeparatorPopupMenuItem extends ApplicationPopupMenuItem
/**
* Constructor
* @api
*/
public function __construct()
{
@@ -976,7 +1025,7 @@ class SeparatorPopupMenuItem extends ApplicationPopupMenuItem
* Class for adding an item as a button that browses to the given URL
*
* @api
* @package Extensibility
* @package UIExtensibilityAPI
* @since 2.0
*/
class URLButtonItem extends URLPopupMenuItem
@@ -988,7 +1037,7 @@ class URLButtonItem extends URLPopupMenuItem
* Class for adding an item as a button that runs some JS code
*
* @api
* @package Extensibility
* @package UIExtensibilityAPI
* @since 2.0
*/
class JSButtonItem extends JSPopupMenuItem
@@ -1012,7 +1061,7 @@ class JSButtonItem extends JSPopupMenuItem
* the specified place and can use the passed iTopWebPage object to add javascript or CSS definitions
*
* @api
* @package Extensibility
* @package UIExtensibilityAPI
* @since 2.0
*/
interface iPageUIExtension
@@ -1020,6 +1069,7 @@ interface iPageUIExtension
/**
* Add content to the North pane
*
* @api
* @param iTopWebPage $oPage The page to insert stuff into.
*
* @return string The HTML content to add into the page
@@ -1029,6 +1079,7 @@ interface iPageUIExtension
/**
* Add content to the South pane
*
* @api
* @param iTopWebPage $oPage The page to insert stuff into.
*
* @return string The HTML content to add into the page
@@ -1038,6 +1089,7 @@ interface iPageUIExtension
/**
* Add content to the "admin banner"
*
* @api
* @param iTopWebPage $oPage The page to insert stuff into.
*
* @return string The HTML content to add into the page
@@ -1049,7 +1101,7 @@ interface iPageUIExtension
* Extend this class instead of iPageUIExtension if you don't need to overload all methods
*
* @api
* @package Extensibility
* @package UIExtensibilityAPI
* @since 2.7.0
*/
abstract class AbstractPageUIExtension implements iPageUIExtension
@@ -1084,7 +1136,7 @@ abstract class AbstractPageUIExtension implements iPageUIExtension
* Implement this interface to add content to any enhanced portal page
*
* @api
* @package Extensibility
* @package PortalExtensibilityAPI
*
* @since 2.4.0 interface creation
* @since 2.7.0 change method signatures due to Silex to Symfony migration
@@ -1098,6 +1150,7 @@ interface iPortalUIExtension
/**
* Returns an array of CSS file urls
*
* @api
* @param \Symfony\Component\DependencyInjection\Container $oContainer
*
* @return array
@@ -1107,6 +1160,7 @@ interface iPortalUIExtension
/**
* Returns inline (raw) CSS
*
* @api
* @param \Symfony\Component\DependencyInjection\Container $oContainer
*
* @return string
@@ -1116,6 +1170,7 @@ interface iPortalUIExtension
/**
* Returns an array of JS file urls
*
* @api
* @param \Symfony\Component\DependencyInjection\Container $oContainer
*
* @return array
@@ -1125,6 +1180,7 @@ interface iPortalUIExtension
/**
* Returns raw JS code
*
* @api
* @param \Symfony\Component\DependencyInjection\Container $oContainer
*
* @return string
@@ -1134,6 +1190,7 @@ interface iPortalUIExtension
/**
* Returns raw HTML code to put at the end of the <body> tag
*
* @api
* @param \Symfony\Component\DependencyInjection\Container $oContainer
*
* @return string
@@ -1143,6 +1200,7 @@ interface iPortalUIExtension
/**
* Returns raw HTML code to put at the end of the #main-wrapper element
*
* @api
* @param \Symfony\Component\DependencyInjection\Container $oContainer
*
* @return string
@@ -1152,6 +1210,7 @@ interface iPortalUIExtension
/**
* Returns raw HTML code to put at the end of the #topbar and #sidebar elements
*
* @api
* @param \Symfony\Component\DependencyInjection\Container $oContainer
*
* @return string
@@ -1163,7 +1222,7 @@ interface iPortalUIExtension
* Extend this class instead of iPortalUIExtension if you don't need to overload all methods
*
* @api
* @package Extensibility
* @package PortalExtensibilityAPI
* @since 2.4.0
*/
abstract class AbstractPortalUIExtension implements iPortalUIExtension
@@ -1229,7 +1288,7 @@ abstract class AbstractPortalUIExtension implements iPortalUIExtension
* Implement this interface to add new operations to the REST/JSON web service
*
* @api
* @package Extensibility
* @package RESTExtensibilityAPI
* @since 2.0.1
*/
interface iRestServiceProvider
@@ -1237,6 +1296,7 @@ interface iRestServiceProvider
/**
* Enumerate services delivered by this class
*
* @api
* @param string $sVersion The version (e.g. 1.0) supported by the services
*
* @return array An array of hash 'verb' => verb, 'description' => description
@@ -1246,6 +1306,7 @@ interface iRestServiceProvider
/**
* Enumerate services delivered by this class
*
* @api
* @param string $sVersion The version (e.g. 1.0) supported by the services
* @param string $sVerb
* @param array $aParams
@@ -1259,69 +1320,90 @@ interface iRestServiceProvider
* Minimal REST response structure. Derive this structure to add response data and error codes.
*
* @api
* @package Extensibility
* @package RESTExtensibilityAPI
* @since 2.0.1
*/
class RestResult
{
/**
* Result: no issue has been encountered
* @api
*/
const OK = 0;
/**
* Result: missing/wrong credentials or the user does not have enough rights to perform the requested operation
* @api
*/
const UNAUTHORIZED = 1;
/**
* Result: the parameter 'version' is missing
* @api
*/
const MISSING_VERSION = 2;
/**
* Result: the parameter 'json_data' is missing
* @api
*/
const MISSING_JSON = 3;
/**
* Result: the input structure is not a valid JSON string
* @api
*/
const INVALID_JSON = 4;
/**
* Result: the parameter 'auth_user' is missing, authentication aborted
* @api
*/
const MISSING_AUTH_USER = 5;
/**
* Result: the parameter 'auth_pwd' is missing, authentication aborted
* @api
*/
const MISSING_AUTH_PWD = 6;
/**
* Result: no operation is available for the specified version
* @api
*/
const UNSUPPORTED_VERSION = 10;
/**
* Result: the requested operation is not valid for the specified version
* @api
*/
const UNKNOWN_OPERATION = 11;
/**
* Result: the requested operation cannot be performed because it can cause data (integrity) loss
* @api
*/
const UNSAFE = 12;
/**
* Result: the request page number is not valid. It must be an integer greater than 0
* @api
*/
const INVALID_PAGE = 13;
/**
* Result: the operation could not be performed, see the message for troubleshooting
* @api
*/
const INTERNAL_ERROR = 100;
/**
* Default constructor - ok!
* @api
*/
public function __construct()
{
$this->code = RestResult::OK;
}
/**
* @var int
* @api
*/
public $code;
/**
* @var string
* @api
*/
public $message;
}
@@ -1329,7 +1411,7 @@ class RestResult
* Helpers for implementing REST services
*
* @api
* @package Extensibility
* @package RESTExtensibilityAPI
*/
class RestUtils
{
@@ -1478,6 +1560,7 @@ class RestUtils
/**
* Read and interpret object search criteria from a Rest/Json structure
*
* @api
* @param string $sClass Name of the class
* @param StdClass $oCriteria Hash of attribute code => value (can be a substructure or a scalar, depending on the nature of the
* attriute)
@@ -1587,6 +1670,7 @@ class RestUtils
/**
* Search objects from a polymorph search specification (Rest/Json)
*
* @api
* @param string $sClass Name of the class
* @param mixed $key Either search criteria (substructure), or an object or an OQL string.
* @param int $iLimit The limit of results to return

View File

@@ -1478,6 +1478,29 @@ JS
return $this->sDefinitionFile;
}
/**
* @param string $sDashboardFileRelative can also be an absolute path (compatibility with old URL)
*
* @return string full path to the Dashboard file
* @throws \SecurityException if path isn't under approot
* @uses utils::RealPath()
* @since 2.7.8 3.0.3 3.1.0 N°4449 remove FPD
*/
public static function GetDashboardFileFromRelativePath($sDashboardFileRelative)
{
if (utils::RealPath($sDashboardFileRelative, APPROOT)) {
// compatibility with old URL containing absolute path !
return $sDashboardFileRelative;
}
$sDashboardFile = APPROOT.$sDashboardFileRelative;
if (false === utils::RealPath($sDashboardFile, APPROOT)) {
throw new SecurityException('Invalid dashboard file !');
}
return $sDashboardFile;
}
/**
* @param string $sDefinitionFile
*/

View File

@@ -1329,19 +1329,19 @@ class utils
$oDashboard = $param;
$sDashboardId = $oDashboard->GetId();
$sDashboardFile = $oDashboard->GetDefinitionFile();
$sDashboardFileRelative = utils::LocalPath($sDashboardFile);
$sDlgTitle = addslashes(Dict::S('UI:ImportDashboardTitle'));
$sDlgText = addslashes(Dict::S('UI:ImportDashboardText'));
$sCloseBtn = addslashes(Dict::S('UI:Button:Cancel'));
$sDashboardFileJS = addslashes($sDashboardFile);
$sDashboardFileURL = urlencode($sDashboardFile);
$sDashboardFileJS = addslashes($sDashboardFileRelative);
$sDashboardFileURL = urlencode($sDashboardFileRelative);
$sUploadDashboardTransactId = utils::GetNewTransactionId();
$aResult = array(
new SeparatorPopupMenuItem(),
new URLPopupMenuItem('UI:ExportDashboard', Dict::S('UI:ExportDashBoard'), utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=export_dashboard&id='.$sDashboardId.'&file='.$sDashboardFileURL),
new JSPopupMenuItem('UI:ImportDashboard', Dict::S('UI:ImportDashBoard'), "UploadDashboard({dashboard_id: '$sDashboardId', file: '$sDashboardFileJS', title: '$sDlgTitle', text: '$sDlgText', close_btn: '$sCloseBtn', transaction: '$sUploadDashboardTransactId' })"),
);
if ($oDashboard->GetReloadURL())
{
if ($oDashboard->GetReloadURL()) {
$aResult[] = new SeparatorPopupMenuItem();
$aResult[] = new URLPopupMenuItem('UI:Menu:PrintableVersion', Dict::S('UI:Menu:PrintableVersion'), $oDashboard->GetReloadURL().'&printable=1', '_blank');
}

View File

@@ -14,7 +14,7 @@ define('APPCONF', APPROOT.'conf/');
* @used-by utils::GetItopVersionWikiSyntax()
* @used-by iTopModulesPhpVersionIntegrationTest
*/
define('ITOP_CORE_VERSION', '2.7.8');
define('ITOP_CORE_VERSION', '2.7.9');
require_once APPROOT.'bootstrap.inc.php';

View File

@@ -555,6 +555,22 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => false,
),
'email_transport_smtp.allow_self_signed' => array(
'type' => 'bool',
'description' => 'Allow self signed peer certificates',
'default' => false,
'value' => false,
'source_of_value' => '',
'show_in_conf_sample' => false,
),
'email_transport_smtp.verify_peer' => array(
'type' => 'bool',
'description' => 'Verify peer certificate',
'default' => true,
'value' => true,
'source_of_value' => '',
'show_in_conf_sample' => false,
),
'email_css' => array(
'type' => 'string',
'description' => 'CSS that will override the standard stylesheet used for the notifications',

View File

@@ -754,14 +754,14 @@ abstract class DBSearch
* @see DBSearch::ToOQL()
*
* @param string $sQuery The OQL to convert to a DBSearch
* @param mixed[string] $aParams array of <mixed> params index by <string> name
* @param array $aParams array of <mixed> params index by <string> name
* @param ModelReflection|null $oMetaModel The MetaModel to use when checking the consistency of the OQL
*
* @return DBObjectSearch|DBUnionSearch
*
* @throws OQLException
*/
static public function FromOQL($sQuery, $aParams = null, ModelReflection $oMetaModel=null)
public static function FromOQL($sQuery, $aParams = null, ModelReflection $oMetaModel=null)
{
if (empty($sQuery))
{

View File

@@ -3,7 +3,7 @@
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
@@ -19,10 +19,11 @@
define('CASELOG_VISIBLE_ITEMS', 2);
define('CASELOG_SEPARATOR', "\n".'========== %1$s : %2$s (%3$d) ============'."\n\n");
require_once('ormcaselogservice.inc.php');
/**
* Class to store a "case log" in a structured way, keeping track of its successive entries
*
*
* @copyright Copyright (C) 2010-2017 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
@@ -30,19 +31,22 @@ class ormCaseLog {
protected $m_sLog;
protected $m_aIndex;
protected $m_bModified;
protected \ormCaseLogService $oOrmCaseLogService;
/**
* Initializes the log with the first (initial) entry
* @param $sLog string The text of the whole case log
* @param $aIndex array The case log index
*/
public function __construct($sLog = '', $aIndex = array())
public function __construct($sLog = '', $aIndex = [], \ormCaseLogService $oOrmCaseLogService=null)
{
$this->m_sLog = $sLog;
$this->m_aIndex = $aIndex;
$this->m_bModified = false;
$this->oOrmCaseLogService = (is_null($oOrmCaseLogService)) ? new \ormCaseLogService() : $oOrmCaseLogService;
$this->RebuildIndex();
}
public function GetText($bConvertToPlainText = false)
{
if ($bConvertToPlainText)
@@ -55,7 +59,7 @@ class ormCaseLog {
return $this->m_sLog;
}
}
public static function FromJSON($oJson)
{
if (!isset($oJson->items))
@@ -71,8 +75,8 @@ class ormCaseLog {
}
/**
* Return a value that will be further JSON encoded
*/
* Return a value that will be further JSON encoded
*/
public function GetForJSON()
{
// Order by ascending date
@@ -182,9 +186,9 @@ class ormCaseLog {
$sSeparator = sprintf(CASELOG_SEPARATOR, $aData['date'], $aData['user_login'], $aData['user_id']);
$sPlainText .= $sSeparator.$aData['message'];
}
return $sPlainText;
return $sPlainText;
}
public function GetIndex()
{
return $this->m_aIndex;
@@ -201,7 +205,7 @@ class ormCaseLog {
{
return ($this->m_sLog === null);
}
public function ClearModifiedFlag()
{
$this->m_bModified = false;
@@ -209,7 +213,7 @@ class ormCaseLog {
/**
* Produces an HTML representation, aimed at being used within an email
*/
*/
public function GetAsEmailHtml()
{
$sStyleCaseLogHeader = '';
@@ -290,10 +294,10 @@ class ormCaseLog {
$sHtml .= '</td></tr></table>';
return $sHtml;
}
/**
* Produces an HTML representation, aimed at being used to produce a PDF with TCPDF (no table)
*/
*/
public function GetAsSimpleHtml($aTransfoHandler = null)
{
$sStyleCaseLogEntry = '';
@@ -322,7 +326,7 @@ class ormCaseLog {
$sTextEntry = call_user_func($aTransfoHandler, $sTextEntry, true /* wiki "links" only */);
}
$sTextEntry = InlineImage::FixUrls($sTextEntry);
}
}
$iPos += $aIndex[$index]['text_length'];
$sEntry = '<li>';
@@ -384,7 +388,7 @@ class ormCaseLog {
/**
* Produces an HTML representation, aimed at being used within the iTop framework
*/
*/
public function GetAsHTML(WebPage $oP = null, $bEditMode = false, $aTransfoHandler = null)
{
$bPrintableVersion = (utils::ReadParam('printable', '0') == '1');
@@ -504,16 +508,19 @@ class ormCaseLog {
$sHtml .= '</td></tr></table>';
return $sHtml;
}
/**
* Add a new entry to the log or merge the given text into the currently modified entry
* Add a new entry to the log or merge the given text into the currently modified entry
* and updates the internal index
* @param $sText string The text of the new entry
* @param $sText string The text of the new entry
*/
public function AddLogEntry($sText, $sOnBehalfOf = '')
{
$sText = HTMLSanitizer::Sanitize($sText);
//date/time ops moved here for test stability
$iNow = time();
$sDate = date(AttributeDateTime::GetInternalFormat());
$sText = HTMLSanitizer::Sanitize($sText);
if ($sOnBehalfOf == '')
{
$sOnBehalfOf = UserRights::GetUserFriendlyName();
@@ -539,23 +546,28 @@ class ormCaseLog {
}
$sSeparator = sprintf(CASELOG_SEPARATOR, $sDate, $sOnBehalfOf, $iUserId);
$iSepLength = strlen($sSeparator);
$iTextlength = strlen($sText);
$this->m_sLog = $sSeparator.$sText.$this->m_sLog; // Latest entry printed first
// Rebuild failed
$iSepLength = strlen($sSeparator);
$iTextLength = strlen($sText);
$this->m_aIndex[] = array(
'user_name' => $sOnBehalfOf,
'user_id' => $iUserId,
'date' => time(),
'text_length' => $iTextlength,
'date' => $iNow,
'text_length' => $iTextLength,
'separator_length' => $iSepLength,
'format' => 'html',
);
$this->RebuildIndex();
$this->m_bModified = true;
}
public function AddLogEntryFromJSON($oJson, $bCheckUserId = true)
{
//date/time ops moved here for test stability
$iNow = time();
if (isset($oJson->user_id))
{
if (!UserRights::IsAdministrator())
@@ -586,7 +598,7 @@ class ormCaseLog {
$iUserId = UserRights::GetUserId();
$sOnBehalfOf = UserRights::GetUserFriendlyName();
}
if (isset($oJson->date))
{
$oDate = new DateTime($oJson->date);
@@ -594,7 +606,7 @@ class ormCaseLog {
}
else
{
$iDate = time();
$iDate = $iNow;
}
if (isset($oJson->format))
{
@@ -615,18 +627,19 @@ class ormCaseLog {
$sDate = date(AttributeDateTime::GetInternalFormat(), $iDate);
$sSeparator = sprintf(CASELOG_SEPARATOR, $sDate, $sOnBehalfOf, $iUserId);
$iSepLength = strlen($sSeparator);
$iTextlength = strlen($sText);
$this->m_sLog = $sSeparator.$sText.$this->m_sLog; // Latest entry printed first
// Rebuild failed
$iSepLength = strlen($sSeparator);
$iTextLength = strlen($sText);
$this->m_aIndex[] = array(
'user_name' => $sOnBehalfOf,
'user_id' => $iUserId,
'date' => $iDate,
'text_length' => $iTextlength,
'user_name' => $sOnBehalfOf,
'user_id' => $iUserId,
'date' => $iNow,
'text_length' => $iTextLength,
'separator_length' => $iSepLength,
'format' => $sFormat,
'format' => 'html',
);
$this->RebuildIndex();
$this->m_bModified = true;
}
@@ -643,7 +656,7 @@ class ormCaseLog {
/**
* Get the latest entry from the log
* @param string The expected output format text|html
* @param string $sFormat The expected output format text|html
* @return string
*/
public function GetLatestEntry($sFormat = 'text')
@@ -663,7 +676,7 @@ class ormCaseLog {
$sRes = utils::HtmlToText($sRaw);
}
break;
case 'html':
if ($aLastEntry['format'] == 'text')
{
@@ -688,7 +701,7 @@ class ormCaseLog {
$iLast = end($aKeys); // Strict standards: the parameter passed to 'end' must be a variable since it is passed by reference
return $iLast;
}
/**
* Get the text string corresponding to the given entry in the log (zero based index, older entries first)
* @param integer $iIndex
@@ -708,5 +721,13 @@ class ormCaseLog {
$sText = substr($this->m_sLog, $iPos, $this->m_aIndex[$index]['text_length']);
return $sText;
}
public function RebuildIndex(): void
{
$aIndex = $this->oOrmCaseLogService->RebuildIndex($this->m_sLog, $this->m_aIndex);
if (count($aIndex) !== 0) {
//index rebuild required
$this->m_aIndex = $aIndex;
}
}
}
?>

View File

@@ -0,0 +1,57 @@
<?php
/**
* @copyright Copyright (C) 2010-2022 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
class ormCaseLogService
{
const CASE_LOG_SEPARATOR_REGEX_FIND = "\n?========== \w+-\d+-\d+ \d+:\d+:\d+ : .*\s\(\d+\) ============\n\n";
const CASE_LOG_SEPARATOR_REGEX_EXTRACT = "\n?========== (?<date>\w+-\d+-\d+ \d+:\d+:\d+) : (?<user_name>.*)\s\((?<user_id>\d+)\) ============\n\n";
public function __construct()
{
}
/**
* @param $sLog
*
* @return array
*/
public function RebuildIndex(string $sLog, array $aIndex)
{
$aTexts = preg_split('/'.self::CASE_LOG_SEPARATOR_REGEX_FIND.'/', $sLog, 0, PREG_SPLIT_NO_EMPTY);
preg_match_all('/'.self::CASE_LOG_SEPARATOR_REGEX_FIND.'/', $sLog, $aMatches);
if (count($aTexts) != count($aMatches[0])) {
return [];
}
$aRebuiltIndex = [];
$iPrevDate = 0;
for ($index = count($aTexts) - 1; $index >= 0; $index--) {
$sSeparator = $aMatches[0][$index];
preg_match('/'.self::CASE_LOG_SEPARATOR_REGEX_EXTRACT.'/', $sSeparator, $aSeparatorParts);
try {
$iDate = (int)AttributeDateTime::GetAsUnixSeconds($aSeparatorParts['date']);
$iPrevDate = $iDate + 1;
}
catch (Exception $e) {
$iDate = $iPrevDate;
}
$user_id = $aSeparatorParts['user_id'];
$aRebuiltIndex[] = array(
'user_name' => $aSeparatorParts['user_name'],
'user_id' => $user_id ==='0' ? null : $user_id,
'date' => $iDate,
'text_length' => strlen($aTexts[$index]),
'separator_length' => strlen($sSeparator),
'format' => 'html',
);
}
return $aRebuiltIndex;
}
}

View File

@@ -25,6 +25,19 @@
class PDFBulkExport extends HTMLBulkExport
{
/**
* @var string For sample purposes
* @internal
* @since 2.7.8
*/
const ENUM_OUTPUT_TYPE_SAMPLE = 'sample';
/**
* @var string For the real export
* @internal
* @since 2.7.8
*/
const ENUM_OUTPUT_TYPE_REAL = 'real';
public function DisplayUsage(Page $oP)
{
$oP->p(" * pdf format options:");
@@ -190,6 +203,25 @@ EOF
return $sPDF;
}
/**
* @inheritDoc
* @since 2.7.8
*/
protected function GetSampleData($oObj, $sAttCode)
{
if ($sAttCode !== 'id')
{
$oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode);
// As sample data will be displayed in the web browser, AttributeImage needs to be rendered with a regular HTML format, meaning its "src" looking like "data:image/png;base64,iVBORw0KGgoAAAANSUh..."
// Whereas for the PDF generation it needs to be rendered with a TCPPDF-compatible format, meaning its "src" looking like "@iVBORw0KGgoAAAANSUh..."
if ($oAttDef instanceof AttributeImage) {
return $this->GetAttributeImageValue($oAttDef, $oObj->Get($sAttCode), static::ENUM_OUTPUT_TYPE_SAMPLE);
}
}
return parent::GetSampleData($oObj, $sAttCode);
}
protected function GetValue($oObj, $sAttCode)
{
switch($sAttCode)
@@ -205,31 +237,7 @@ EOF
$oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode);
if ($oAttDef instanceof AttributeImage)
{
// To limit the image size in the PDF output, we have to enforce the size as height/width because max-width/max-height have no effect
//
$iDefaultMaxWidthPx = 48;
$iDefaultMaxHeightPx = 48;
if ($value->IsEmpty())
{
$iNewWidth = $iDefaultMaxWidthPx;
$iNewHeight = $iDefaultMaxHeightPx;
$sUrl = $oAttDef->Get('default_image');
}
else
{
list($iWidth, $iHeight) = utils::GetImageSize($value->GetData());
$iMaxWidthPx = min($iDefaultMaxWidthPx, $oAttDef->Get('display_max_width'));
$iMaxHeightPx = min($iDefaultMaxHeightPx, $oAttDef->Get('display_max_height'));
$fScale = min($iMaxWidthPx / $iWidth, $iMaxHeightPx / $iHeight);
$iNewWidth = $iWidth * $fScale;
$iNewHeight = $iHeight * $fScale;
$sUrl = 'data:'.$value->GetMimeType().';base64,'.base64_encode($value->GetData());
}
$sRet = ($sUrl !== null) ? '<img src="'.$sUrl.'" style="width: '.$iNewWidth.'px; height: '.$iNewHeight.'px">' : '';
$sRet = '<div class="view-image">'.$sRet.'</div>';
$sRet = $this->GetAttributeImageValue($oAttDef, $value, static::ENUM_OUTPUT_TYPE_REAL);
}
else
{
@@ -258,4 +266,53 @@ EOF
{
return 'pdf';
}
/**
* @param \AttributeImage $oAttDef Instance of image attribute
* @param \ormDocument $oValue Value of image attribute
* @param string $sOutputType {@see \PDFBulkExport::ENUM_OUTPUT_TYPE_SAMPLE}, {@see \PDFBulkExport::ENUM_OUTPUT_TYPE_REAL}
*
* @return string Rendered value of $oAttDef / $oValue according to the desired $sOutputType
* @since 2.7.8
*/
protected function GetAttributeImageValue(AttributeImage $oAttDef, ormDocument $oValue, string $sOutputType)
{
// To limit the image size in the PDF output, we have to enforce the size as height/width because max-width/max-height have no effect
//
$iDefaultMaxWidthPx = 48;
$iDefaultMaxHeightPx = 48;
if ($oValue->IsEmpty()) {
$iNewWidth = $iDefaultMaxWidthPx;
$iNewHeight = $iDefaultMaxHeightPx;
$sUrl = $oAttDef->Get('default_image');
} else {
list($iWidth, $iHeight) = utils::GetImageSize($oValue->GetData());
$iMaxWidthPx = min($iDefaultMaxWidthPx, $oAttDef->Get('display_max_width'));
$iMaxHeightPx = min($iDefaultMaxHeightPx, $oAttDef->Get('display_max_height'));
$fScale = min($iMaxWidthPx / $iWidth, $iMaxHeightPx / $iHeight);
$iNewWidth = $iWidth * $fScale;
$iNewHeight = $iHeight * $fScale;
$sValueAsBase64 = base64_encode($oValue->GetData());
switch ($sOutputType) {
case static::ENUM_OUTPUT_TYPE_SAMPLE:
$sUrl = 'data:'.$oValue->GetMimeType().';base64,'.$sValueAsBase64;
break;
case static::ENUM_OUTPUT_TYPE_REAL:
default:
// TCPDF requires base64-encoded images to be rendered without the usual "data:<MIMETYPE>;base64" header but with an "@"
// @link https://tcpdf.org/examples/example_009/
$sUrl = '@'.$sValueAsBase64;
break;
}
}
$sRet = ($sUrl !== null) ? '<img src="'.$sUrl.'" style="width: '.$iNewWidth.'px; height: '.$iNewHeight.'px; vertical-align: middle; text-align:center;">' : '';
$sRet = '<div class="view-image">'.$sRet.'</div>';
return $sRet;
}
}

View File

@@ -129,7 +129,7 @@ class ObjectResult
/**
* REST response for services managing objects. Derive this structure to add information and/or constants
*
* @package Extensibility
* @package RESTExtensibilityAPI
* @package REST Services
* @api
*/
@@ -206,7 +206,7 @@ class RestResultWithRelations extends RestResultWithObjects
/**
* Deletion result codes for a target object (either deleted or updated)
*
* @package Extensibility
* @package RESTExtensibilityAPI
* @api
* @since 2.0.1
*/

View File

@@ -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.8";
$version: "v2.7.9";
$approot-relative: "../../../../../" !default; // relative to env-***/branding/themes/***/main.css
// Base colors

View File

@@ -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.8',
'authent-cas/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'authent-external/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'authent-ldap/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'authent-local/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'combodo-db-tools/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'itop-attachments/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'itop-backup/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'itop-bridge-virtualization-storage/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'itop-change-mgmt-itil/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'itop-change-mgmt/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'itop-config-mgmt/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'itop-config/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'itop-core-update/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'itop-datacenter-mgmt/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'itop-endusers-devices/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'itop-files-information/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'itop-full-itil/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'itop-hub-connector/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'itop-incident-mgmt-itil/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'itop-knownerror-mgmt/2.7.9',
array(
// Identification
//

View File

@@ -77,11 +77,10 @@ const oOpenSignInWindow = function (url, name) {
};
const OAuthConnect = function(sClass, sId, sAjaxUri, sReturnUri) {
const OAuthConnect = function(sClass, sId, sAjaxUri) {
sOAuthAjaxURI = sAjaxUri;
sOAuthObjClass = sClass;
sOAuthObjKey = sId;
sOAuthReturnURI = sReturnUri;
$.post(
sOAuthAjaxURI,

View File

@@ -52,12 +52,12 @@
<default_value/>
<is_null_allowed>true</is_null_allowed>
</field>
<field id="client_id" xsi:type="AttributeText">
<field id="client_id" xsi:type="AttributeString">
<sql>client_id</sql>
<default_value/>
<is_null_allowed>false</is_null_allowed>
</field>
<field id="client_secret" xsi:type="AttributeText">
<field id="client_secret" xsi:type="AttributePassword">
<sql>client_secret</sql>
<default_value/>
<is_null_allowed>false</is_null_allowed>
@@ -293,7 +293,6 @@
<attributes>
<attribute id="provider"/>
<attribute id="client_id"/>
<attribute id="client_secret"/>
</attributes>
<is_blocking>true</is_blocking>
</rule>
@@ -441,21 +440,6 @@
}
]]></code>
</method>
<method id="OnUpdate">
<static>false</static>
<access>protected</access>
<type>Overload-DBObject</type>
<code><![CDATA[
protected function OnUpdate()
{
$aChanges = $this->ListChanges();
if (array_key_exists('client_id', $aChanges) || array_key_exists('client_secret', $aChanges) || array_key_exists('redirect_url', $aChanges)) {
$sMessage = Dict::S('itop-oauth-client:Message:RegenerateToken');
self::SetSessionMessage(get_class($this), $this->GetKey(), 'RegenerateToken', $sMessage, 'info', 1);
}
}
]]></code>
</method>
<method id="DoCheckToWrite">
<static>false</static>
<access>public</access>
@@ -501,6 +485,12 @@
$this->Set('used_scope', 'advanced');
$this->Set('scope', '');
}
$aChanges = $this->ListChanges();
if (array_key_exists('client_id', $aChanges) || array_key_exists('client_secret', $aChanges) || array_key_exists('redirect_url', $aChanges)) {
$sMessage = Dict::S('itop-oauth-client:Message:RegenerateToken');
self::SetSessionMessage(get_class($this), $this->GetKey(), 'RegenerateToken', $sMessage, 'info', 1);
$this->Set('status', 'inactive');
}
}
]]></code>
</method>
@@ -604,7 +594,6 @@
<attributes>
<attribute id="provider"/>
<attribute id="client_id"/>
<attribute id="client_secret"/>
</attributes>
<is_blocking>true</is_blocking>
</rule>
@@ -799,6 +788,12 @@
$this->Set('used_scope', 'advanced');
$this->Set('scope', '');
}
$aChanges = $this->ListChanges();
if (array_key_exists('client_id', $aChanges) || array_key_exists('client_secret', $aChanges) || array_key_exists('redirect_url', $aChanges)) {
$sMessage = Dict::S('itop-oauth-client:Message:RegenerateToken');
self::SetSessionMessage(get_class($this), $this->GetKey(), 'RegenerateToken', $sMessage, 'info', 1);
$this->Set('status', 'inactive');
}
}
]]></code>
</method>
@@ -872,21 +867,6 @@
}
]]></code>
</method>
<method id="OnUpdate">
<static>false</static>
<access>protected</access>
<type>Overload-DBObject</type>
<code><![CDATA[
protected function OnUpdate()
{
$aChanges = $this->ListChanges();
if (array_key_exists('client_id', $aChanges) || array_key_exists('client_secret', $aChanges) || array_key_exists('redirect_url', $aChanges)) {
$sMessage = Dict::S('itop-oauth-client:Message:RegenerateToken');
self::SetSessionMessage(get_class($this), $this->GetKey(), 'RegenerateToken', $sMessage, 'info', 1);
}
}
]]></code>
</method>
</methods>
</class>
</classes>

View File

@@ -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.8',
'itop-oauth-client/2.7.9',
array(
// Identification
//

View File

@@ -7,7 +7,6 @@
namespace Combodo\iTop\OAuthClient\Service;
use ApplicationContext;
use Combodo\iTop\Core\Authentication\Client\OAuth\OAuthClientProviderFactory;
use Dict;
use iPopupMenuExtension;
use JSPopupMenuItem;
@@ -42,11 +41,10 @@ class PopupMenuExtension implements \iPopupMenuExtension
$sAjaxUri = utils::GetAbsoluteUrlModulePage(static::MODULE_CODE, 'ajax.php');
// Add a new menu item that triggers a custom JS function defined in our own javascript file: js/sample.js
$sJSFileUrl = utils::GetAbsoluteUrlModulesRoot().static::MODULE_CODE.'/assets/js/oauth_connect.js';
$sRedirectUri = OAuthClientProviderFactory::GetRedirectUri();
$aResult[] = new JSPopupMenuItem(
$sMenu.' from '.$sObjClass,
Dict::S($sMenu),
"OAuthConnect('$sClass', $sId, '$sAjaxUri', '$sRedirectUri')",
"OAuthConnect('$sClass', $sId, '$sAjaxUri')",
[$sJSFileUrl]
);

View File

@@ -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.8', array(
'itop-portal-base/2.7.9', array(
// Identification
'label' => 'Portal Development Library',
'category' => 'Portal',

View File

@@ -19,7 +19,9 @@
namespace Combodo\iTop\Portal\Twig;
use Closure;
use Dict;
use IssueLog;
use Twig\Extension\AbstractExtension;
use Twig_SimpleFilter;
use Twig_SimpleFunction;
@@ -98,17 +100,96 @@ class AppExtension extends AbstractExtension
return $sUrl;
});
//since 2.7.7 3.0.2 3.1.0 N°4867 "Twig content not allowed" error when use the extkey widget search icon in the user portal
//overwrite native twig filter : disable use of 'system' filter
// Since 2.7.8 filter more functions as filter 'filter' is used by the portal
$filters[] = new Twig_SimpleFilter('filter', function ($array, $arrow) {
if ($arrow == 'system'){
return json_encode($array);
$ret = $this->SanitizeFilter($array, $arrow);
if ($ret !== false) {
IssueLog::Error('Twig "filter" filter has limited capabilities');
return [$ret];
}
return twig_array_filter($array, $arrow);
return twig_array_filter($array, $arrow);
});
// Since 2.7.8 deactivate map
$filters[] = new Twig_SimpleFilter('map', function ($array, $arrow) {
IssueLog::Error('Twig "map" filter is deactivated');
return $array;
});
// Since 2.7.8 deactivate reduce
$filters[] = new Twig_SimpleFilter('reduce', function ($array, $arrow, $initial = null) {
IssueLog::Error('Twig "reduce" filter is deactivated');
return $array;
});
return $filters;
}
private function SanitizeFilter($array, $arrow)
{
$aRestricted = [
'system',
'exec',
'passthru',
'popen',
'proc_open',
'shell_exec',
'file_get_contents',
'file_put_contents',
'eval',
'pcntl_exec',
'chgrp',
'chmod',
'chown',
'lchgrp',
'lchown',
'umask',
'copy',
'delete',
'unlink',
'link',
'mkdir',
'rmdir',
'rename',
'symlink',
'tempnam',
'tmpfile',
'touch',
'fgetc',
'fgetcsv',
'fgets',
'fgetss',
'file',
'flock',
'fopen',
'fpassthru',
'fputcsv',
'fputs',
'fread',
'fscanf',
'ftruncate',
'fwrite',
'glob',
'readfile',
'readlink',
'parse_ini_file',
'mail',
];
$aRestrictedStartWith = ['ftp_', 'zip_', 'stream_'];
if (is_string($arrow)) {
if (in_array(strtolower($arrow), $aRestricted)) {
return json_encode($array);
}
foreach ($aRestrictedStartWith as $sRestrictedStartWith) {
if (utils::StartsWith($arrow, $sRestrictedStartWith)) {
return json_encode($array);
}
}
} elseif ($arrow instanceof Closure) {
return json_encode($array);
}
return false;
}
/**
* @return array|\Twig\TwigFunction[]|\Twig_SimpleFunction[]
*/

View File

@@ -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.8', array(
'itop-portal/2.7.9', array(
// Identification
'label' => 'Enhanced Customer Portal',
'category' => 'Portal',

View File

@@ -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.8',
'itop-problem-mgmt/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'itop-profiles-itil/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'itop-request-mgmt-itil/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'itop-request-mgmt/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'itop-service-mgmt-provider/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'itop-service-mgmt/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'itop-sla-computation/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'itop-storage-mgmt/2.7.9',
array(
// Identification
//

View File

@@ -3,7 +3,7 @@
SetupWebPage::AddModule(
__FILE__,
'itop-tickets/2.7.8',
'itop-tickets/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'itop-virtualization-mgmt/2.7.9',
array(
// Identification
//

View File

@@ -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.8',
'itop-welcome-itil/2.7.9',
array(
// Identification
//

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<information>
<version>2.7.8</version>
<version>2.7.9</version>
</information>

View File

@@ -2740,6 +2740,7 @@ return array(
'iWorkingTimeComputer' => $baseDir . '/core/computing.inc.php',
'lnkTriggerAction' => $baseDir . '/core/trigger.class.inc.php',
'ormCaseLog' => $baseDir . '/core/ormcaselog.class.inc.php',
'ormCaseLogService' => $baseDir . '/core/ormcaselogservice.class.inc.php',
'ormCustomFieldsValue' => $baseDir . '/core/ormcustomfieldsvalue.class.inc.php',
'ormDocument' => $baseDir . '/core/ormdocument.class.inc.php',
'ormLinkSet' => $baseDir . '/core/ormlinkset.class.inc.php',

View File

@@ -3108,6 +3108,7 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
'iWorkingTimeComputer' => __DIR__ . '/../..' . '/core/computing.inc.php',
'lnkTriggerAction' => __DIR__ . '/../..' . '/core/trigger.class.inc.php',
'ormCaseLog' => __DIR__ . '/../..' . '/core/ormcaselog.class.inc.php',
'ormCaseLogService' => __DIR__ . '/../..' . '/core/ormcaselogservice.class.inc.php',
'ormCustomFieldsValue' => __DIR__ . '/../..' . '/core/ormcustomfieldsvalue.class.inc.php',
'ormDocument' => __DIR__ . '/../..' . '/core/ormdocument.class.inc.php',
'ormLinkSet' => __DIR__ . '/../..' . '/core/ormlinkset.class.inc.php',

View File

@@ -1128,11 +1128,13 @@ try
case 'export_dashboard':
$sDashboardId = utils::ReadParam('id', '', false, 'raw_data');
$sDashboardFile = utils::ReadParam('file', '', false, 'raw_data');
$sDashboardFileRelative = utils::ReadParam('file', '', false, 'raw_data');
$sDashboardFile = RuntimeDashboard::GetDashboardFileFromRelativePath($sDashboardFileRelative);
$oKPI = new ExecutionKPI();
$oDashboard = RuntimeDashboard::GetDashboard($sDashboardFile, $sDashboardId);
if (!is_null($oDashboard))
{
if (!is_null($oDashboard)) {
$oPage->TrashUnexpectedOutput();
$oPage->SetContentType('text/xml');
$oPage->SetContentDisposition('attachment', 'dashboard_'.$oDashboard->GetTitle().'.xml');
@@ -1143,18 +1145,18 @@ try
case 'import_dashboard':
$sTransactionId = utils::ReadParam('transaction_id', '', false, 'transaction_id');
if (!utils::IsTransactionValid($sTransactionId, true))
{
if (!utils::IsTransactionValid($sTransactionId, true)) {
throw new SecurityException('ajax.render.php import_dashboard : invalid transaction_id');
}
$sDashboardId = utils::ReadParam('id', '', false, 'raw_data');
$sDashboardFile = utils::ReadParam('file', '', false, 'raw_data');
$sDashboardFileRelative = utils::ReadParam('file', '', false, 'raw_data');
$sDashboardFile = RuntimeDashboard::GetDashboardFileFromRelativePath($sDashboardFileRelative);
$oDashboard = RuntimeDashboard::GetDashboard($sDashboardFile, $sDashboardId);
$aResult = array('error' => '');
if (!is_null($oDashboard))
{
try
{
if (!is_null($oDashboard)) {
try {
$oDoc = utils::ReadPostedDocument('dashboard_upload_file');
$oDashboard->FromXml($oDoc->GetData());
$oDashboard->Save();

View File

@@ -1705,7 +1705,7 @@ to represent the company, product, or service to which they refer.**
</license>
<license>
<product scope="datamodels">apereo/phpcas</product>
<author>Joachim Fritschi - Adam Franco</author>
<author>Joachim Fritschi - Adam Franco - Henry Pan</author>
<license_type>Apache-2.0</license_type>
<text><![CDATA[
Apache License

View File

@@ -54,8 +54,8 @@ function ExecuteStep(sStep)
}
function CheckDirectoryConfFilesPermissions(sWikiVersion){
$.ajax('permissions-test-folder/permissions-test-subfolder/permissions-test-file',
{
$.ajax('permissions-test-folder/permissions-test-subfolder/permissions-test-file', {
cache: false,
statusCode: {
200: function() {
$('#details').prepend('<div class="message message-warning"><span class="message-title">Security issue:</span> iTop is bundled with directory-level configuration files. You must check that those files will be read by your web server (eg.' +

View File

@@ -1594,6 +1594,18 @@ JS
return array_key_exists('itsm-designer-connector', $aModules);
}
/**
* @param array $aModules List of available module codes
*
* @return bool true if the Hub connector is installed
*
* @since 2.7.8 3.0.3 3.1.0 N°5758 method creation
*/
public static function IsConnectableToITopHub($aModules)
{
return array_key_exists('itop-hub-connector', $aModules);
}
/**
* @param array $aModules Available modules with code as key and metadata array as values
* Same structure as the one returned by {@link \RunTimeEnvironment::AnalyzeInstallation}

View File

@@ -707,15 +707,17 @@ class WizStepLicense extends WizardStep
}
/**
* @return bool
* @return bool true if we need to display a GDPR confirmation
* @throws \Exception
* @since 2.7.7 3.0.2 3.1.0
* @since 2.7.7 3.0.2 3.1.0 N°5037 method creation
* @since 2.7.8 3.0.3 3.1.0 N°5758 rename from NeedsRgpdConsent to NeedsGdprConsent
*/
private function NeedsRgpdConsent()
private function NeedsGdprConsent()
{
$sMode = $this->oWizard->GetParameter('install_mode');
$aModules = SetupUtils::AnalyzeInstallation($this->oWizard);
return $sMode == 'install' && !SetupUtils::IsProductVersion($aModules);
return (($sMode === 'install') && SetupUtils::IsConnectableToITopHub($aModules));
}
/**
@@ -752,7 +754,7 @@ EOF
$oPage->add('</fieldset>');
$sChecked = ($this->oWizard->GetParameter('accept_license', 'no') == 'yes') ? ' checked ' : '';
$oPage->p('<input type="checkbox" class="check_select" name="accept_license" id="accept" value="yes" '.$sChecked.'><label for="accept">&nbsp;I accept the terms of the licenses of the '.count($aLicenses).' components mentioned above.</label>');
if ($this->NeedsRgpdConsent()) {
if ($this->NeedsGdprConsent()) {
$oPage->add('<div id="rgpd_message" class="message message-info">'.ITOP_APPLICATION.' software is compliant with the processing of personal data according to the European General Data Protection Regulation (GDPR).<p></p>
By installing '.ITOP_APPLICATION.' you agree that some information will be collected by Combodo to help you manage your instances and for statistical purposes.
This data remains anonymous until it is associated to a user account on iTop Hub.</p>

View File

@@ -315,7 +315,8 @@ class EMailLaminas extends Email
if ($bForceSynchronous) {
return $this->SendSynchronous($aIssues, $oLog);
} else {
$bConfigASYNC = MetaModel::GetConfig()->Get('email_asynchronous');
$oConfig = $this->LoadConfig();
$bConfigASYNC = $oConfig->Get('email_asynchronous');
if ($bConfigASYNC) {
return $this->SendAsynchronous($aIssues, $oLog);
} else {

View File

@@ -159,11 +159,14 @@ class EmailSwiftMailer extends EMail
$sEncryption = static::$m_oConfig->Get('email_transport_smtp.encryption');
$sUserName = static::$m_oConfig->Get('email_transport_smtp.username');
$sPassword = static::$m_oConfig->Get('email_transport_smtp.password');
$bAllowSelfSigned = static::$m_oConfig->Get('email_transport_smtp.allow_self_signed');
$bVerifyPeer = static::$m_oConfig->Get('email_transport_smtp.verify_peer');
$oTransport = new Swift_SmtpTransport($sHost, $sPort, $sEncryption);
if (strlen($sUserName) > 0) {
$oTransport->setUsername($sUserName);
$oTransport->setPassword($sPassword);
$oTransport->setStreamOptions(array('ssl' => array('allow_self_signed' => $bAllowSelfSigned, 'verify_peer' => $bVerifyPeer)));
}
break;
@@ -270,13 +273,11 @@ class EmailSwiftMailer extends EMail
}
else
{
$bConfigASYNC = MetaModel::GetConfig()->Get('email_asynchronous');
if ($bConfigASYNC)
{
$oConfig = $this->LoadConfig();
$bConfigASYNC = $oConfig->Get('email_asynchronous');
if ($bConfigASYNC) {
return $this->SendAsynchronous($aIssues, $oLog);
}
else
{
} else {
return $this->SendSynchronous($aIssues, $oLog);
}
}

View File

@@ -1,8 +0,0 @@
[itop]
itop_setup=test/setup_params/default-params.xml
itop_backup=test/backups/backup-itop.tar.gz
[phpunit]
; when empty phpunit_xml => no phpunit test performed
; phpunit xml file description. required for phpunit testing
phpunit_xml=test/phpunit.xml.dist

View File

@@ -1,392 +0,0 @@
<?php
/**
*
* Configuration file, generated by the iTop configuration wizard
*
* The file is used in MetaModel::LoadConfig() which does all the necessary initialization job
*
*/
$MySettings = array(
// access_message: Message displayed to the users when there is any access restriction
// default: 'iTop is temporarily frozen, please wait... (the admin team)'
'access_message' => 'iTop is temporarily frozen, please wait... (the admin team)',
// access_mode: Access mode: ACCESS_READONLY = 0, ACCESS_ADMIN_WRITE = 2, ACCESS_FULL = 3
// default: 3
'access_mode' => 3,
// activity_panel.entry_form_opened_by_default: Whether or not the new entry form will be automatically opened when viewing an object.
// default: false
'activity_panel.entry_form_opened_by_default' => false,
// activity_panel.show_author_name_below_entries: Whether or not to show the author friendlyname next to the date on the last entry.
// default: false
'activity_panel.show_author_name_below_entries' => false,
'allowed_login_types' => 'form|external|basic',
// apc_cache.enabled: If set, the APC cache is allowed (the PHP extension must also be active)
// default: true
'apc_cache.enabled' => true,
// apc_cache.query_ttl: Time to live set in APC for the prepared queries (seconds - 0 means no timeout)
// default: 3600
'apc_cache.query_ttl' => 3600,
// app_root_url: Root URL used for navigating within the application, or from an email to the application (you can put $SERVER_NAME$ as a placeholder for the server's name)
// default: ''
'app_root_url' => 'http://localhost/itop-dev/',
// behind_reverse_proxy: 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)
// default: false
'behind_reverse_proxy' => false,
// cron_max_execution_time: Duration (seconds) of the page cron.php, must be shorter than php setting max_execution_time and shorter than the web server response timeout
// default: 600
'cron_max_execution_time' => 600,
// csv_file_default_charset: Character set used by default for downloading and uploading data as a CSV file. Warning: it is case sensitive (uppercase is preferable).
// default: 'ISO-8859-1'
'csv_file_default_charset' => 'ISO-8859-1',
'csv_import_charsets' => array(),
// csv_import_history_display: Display the history tab in the import wizard
// default: false
'csv_import_history_display' => false,
// date_and_time_format: Format for date and time display (per language)
// default: array (
// 'default' =>
// array (
// 'date' => 'Y-m-d',
// 'time' => 'H:i:s',
// 'date_time' => '$date $time',
// ),
// )
'date_and_time_format' => array(
'default' =>
array(
'date' => 'Y-m-d',
'time' => 'H:i:s',
'date_time' => '$date $time',
),
),
'db_host' => 'localhost',
'db_name' => 'itop_dev',
'db_pwd' => '',
'db_subname' => '',
'db_user' => 'root',
// deadline_format: The format used for displaying "deadline" attributes: any string with the following placeholders: $date$, $difference$
// default: '$difference$'
'deadline_format' => '$difference$',
'default_language' => 'EN US',
// email_asynchronous: If set, the emails are sent off line, which requires cron.php to be activated. Exception: some features like the email test utility will force the serialized mode
// default: false
'email_asynchronous' => false,
// email_default_sender_address: Default address provided in the email from header field.
// default: ''
'email_default_sender_address' => '',
// email_default_sender_label: Default label provided in the email from header field.
// default: ''
'email_default_sender_label' => '',
// email_transport: Mean to send emails: PHPMail (uses the function mail()) or SMTP (implements the client protocol)
// default: 'PHPMail'
'email_transport' => 'PHPMail',
// email_validation_pattern: Regular expression to validate/detect the format of an eMail address
// default: '[a-zA-Z0-9._&\'-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z0-9-]{2,}'
'email_validation_pattern' => '[a-zA-Z0-9._&\'-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z0-9-]{2,}',
'encryption_key' => '061c5b88c47ed64664618cf37b91a442b5550704aacecc5f58f96fc98087333b',
'encryption_library' => 'OpenSSL',
'ext_auth_variable' => '$_SERVER[\'REMOTE_USER\']',
'fast_reload_interval' => 60,
// graphviz_path: Path to the Graphviz "dot" executable for graphing objects lifecycle
// default: '/usr/bin/dot'
'graphviz_path' => 'C:\\Program Files (x86)\\Graphviz2.38\\bin\\dot.exe',
// high_cardinality_classes: List of classes with high cardinality (Force manual submit of search)
// default: array (
// )
'high_cardinality_classes' => array(),
// inline_image_max_display_width: The maximum width (in pixels) when displaying images inside an HTML formatted attribute. Images will be displayed using this this maximum width.
// default: '250'
'inline_image_max_display_width' => '250',
// inline_image_max_storage_width: The maximum width (in pixels) when uploading images to be used inside an HTML formatted attribute. Images larger than the given size will be downsampled before storing them in the database.
// default: '1600'
'inline_image_max_storage_width' => '1600',
// link_set_attribute_qualifier: Link set from string: attribute qualifier (encloses both the attcode and the value)
// default: '\''
'link_set_attribute_qualifier' => '\'',
// link_set_attribute_separator: Link set from string: attribute separator
// default: ';'
'link_set_attribute_separator' => ';',
// link_set_item_separator: Link set from string: line separator
// default: '|'
'link_set_item_separator' => '|',
// link_set_value_separator: Link set from string: value separator (between the attcode and the value itself
// default: ':'
'link_set_value_separator' => ':',
'log_global' => true,
'log_issue' => true,
'log_kpi_duration' => 0,
'log_notification' => true,
'log_web_service' => true,
'max_display_limit' => 30,
// max_linkset_output: Maximum number of items shown when getting a list of related items in an email, using the form $this->some_list$. 0 means no limit.
// default: 100
'max_linkset_output' => 100,
// mentions.allowed_classes: Classes which can be mentioned through the autocomplete in the caselogs. Key of the array must be a single character that will trigger the autocomplete, value can be either a DM class or a valid OQL (eg. "@" => "Person", "?" => "SELECT FAQ WHERE status = 'published'")
// default: array (
// '@' => 'SELECT Person WHERE status = \'active\'',
// )
'mentions.allowed_classes' => array(
'@' => 'SELECT Person WHERE status = \'active\'',
),
'min_display_limit' => 20,
// online_help: Hyperlink to the online-help web page
// default: 'http://www.combodo.com/itop-help'
'online_help' => 'http://www.combodo.com/itop-help',
// optimize_requests_for_join_count: Optimize request joins to minimize the count (default is true, try to set it to false in case of performance issues)
// default: true
'optimize_requests_for_join_count' => true,
'password_hash_algo' => '2y',
// php_path: Path to the php executable in CLI mode
// default: 'php'
'php_path' => 'php',
// search_manual_submit: Force manual submit of search all requests
// default: false
'search_manual_submit' => false,
'secure_connection_required' => false,
// session_name: The name of the cookie used to store the PHP session id
// default: 'iTop'
'session_name' => 'iTop',
// shortcut_actions: Actions that are available as direct buttons next to the "Actions" menu
// default: 'UI:Menu:Modify,UI:Menu:New'
'shortcut_actions' => 'UI:Menu:Modify,UI:Menu:New',
// source_dir: Source directory for the datamodel files. (which gets compiled to env-production).
// default: ''
'source_dir' => 'datamodels/2.x/',
'standard_reload_interval' => 300,
// synchro_trace: Synchronization details: none, display, save (includes 'display')
// default: 'none'
'synchro_trace' => 'none',
// tag_set_item_separator: Tag set from string: tag label separator
// default: '|'
'tag_set_item_separator' => '|',
// timezone: Timezone (reference: http://php.net/manual/en/timezones.php). If empty, it will be left unchanged and MUST be explicitly configured in PHP
// default: 'Europe/Paris'
'timezone' => 'Europe/Paris',
// tracking_level_linked_set_default: Default tracking level if not explicitly set at the attribute level, for AttributeLinkedSet (defaults to NONE in case of a fresh install, LIST otherwise - this to preserve backward compatibility while upgrading from a version older than 2.0.3 - see TRAC #936)
// default: 1
'tracking_level_linked_set_default' => 0,
// url_validation_pattern: Regular expression to validate/detect the format of an URL (URL attributes and Wiki formatting for Text attributes)
// default: '(https?|ftp)\\://([a-zA-Z0-9+!*(),;?&=\\$_.-]+(\\:[a-zA-Z0-9+!*(),;?&=\\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\\:[0-9]{2,5})?(/([a-zA-Z0-9%+\\$_-]\\.?)+)*/?(\\?[a-zA-Z+&\\$_.-][a-zA-Z0-9;:[\\]@&%=+/\\$_.-]*)?(#[a-zA-Z_.-][a-zA-Z0-9+\\$_.-]*)?'
'url_validation_pattern' => '(https?|ftp)\\://([a-zA-Z0-9+!*(),;?&=\\$_.-]+(\\:[a-zA-Z0-9+!*(),;?&=\\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\\:[0-9]{2,5})?(/([a-zA-Z0-9%+\\$_-]\\.?)+)*/?(\\?[a-zA-Z+&\\$_.-][a-zA-Z0-9;:[\\]@&%=+/\\$_.-]*)?(#[a-zA-Z_.-][a-zA-Z0-9+\\$_.-]*)?',
);
/**
*
* Modules specific settings
*
*/
$MyModuleSettings = array(
'authent-cas' => array(
'cas_debug' => false,
'cas_host' => '',
'cas_port' => '',
'cas_context' => '',
'cas_version' => '',
),
'authent-ldap' => array(
'host' => 'localhost',
'port' => 389,
'default_user' => '',
'default_pwd' => '',
'base_dn' => 'dc=yourcompany,dc=com',
'user_query' => '(&(uid=%1$s)(inetuserstatus=ACTIVE))',
'options' => array(
17 => 3,
8 => 0,
),
'start_tls' => false,
'debug' => false,
),
'itop-attachments' => array(
'allowed_classes' => array(
0 => 'Ticket',
),
'position' => 'relations',
'preview_max_width' => 290,
'icon_preview_max_size' => 500000,
),
'itop-backup' => array(
'mysql_bindir' => '',
'week_days' => 'monday, tuesday, wednesday, thursday, friday',
'time' => '23:30',
'retention_count' => 5,
'enabled' => true,
'itop_backup_incident' => '',
),
'molkobain-console-tooltips' => array(
'decoration_class' => 'fas fa-question',
'enabled' => true,
),
'itop-time-tracking' => array(
'allowed_classes' => array(
'UserRequest' =>
array(
'calendar-tab' => 'SELECT UserRequest WHERE status != "closed"',
'stopwatch' => 'SELECT UserRequest WHERE status != "closed"',
'report-tab' => 'SELECT UserRequest WHERE status IN ("resolved", "closed")',
),
'Incident' =>
array(
'calendar-tab' => 'SELECT Incident WHERE status != "closed"',
'stopwatch' => 'SELECT Incident WHERE status != "closed"',
'report-tab' => 'SELECT Incident WHERE status IN ("resolved", "closed")',
),
'CustomerContract' =>
array(
'calendar-page' => 'SELECT CustomerContract WHERE status = "production"',
'report-tab' => 'SELECT CustomerContract',
),
),
'colors' => array(
'default_stopwatch' =>
array(
'text' => '#ffffff',
'background' => '#a6a6a6',
),
'default_calendar' =>
array(
'text' => '#ffffff',
'background' => '#FFCC80',
),
'classes' =>
array(
'UserRequest' =>
array(
'text' => '#ffffff',
'background' => 'shadeof:blue',
),
'Incident' =>
array(
'text' => '#ffffff',
'background' => 'shadeof:green',
),
'CustomerContract' =>
array(
'text' => '#ffffff',
'background' => 'shadeof:grey',
),
),
),
'clone_events' => false,
'default_event_duration' => '00:30:00',
'day_start_time' => '06:00:00',
'day_end_time' => '22:00:00',
'excluded_days' => array(
0 => 'Saturday',
1 => 'Sunday',
),
'first_day' => 1,
'business_hours' => array(
'days_of_week' =>
array(
0 => '1',
1 => '2',
2 => '3',
3 => '4',
4 => '5',
),
'start' => '08:00:00',
'end' => '18:00:00',
),
'minimum_event_duration_display' => '00:30:00',
'stopwatch_clean_periodicity' => 1,
'stopwatch_max_time' => 4,
'delete_max_event_age' => 30,
'default_report_query' => 'SELECT TimeSpent WHERE contact_id = :contact_id AND start_date >= :start_date AND end_date < :end_date',
'manager_report_query' => 'SELECT TimeSpent WHERE start_date >= :start_date AND end_date < :end_date',
'manager_report_silo' => 'SELECT Person',
'weekly_report_time_spent_attribute' => '',
'weekly_report_time_spent_default' => '30hrs',
'report_charts_definition' => array(
0 =>
array(
'group_by_attribute' => 'contact_id',
'label' => 'TimeTracking:ReportActivityPerUser',
),
1 =>
array(
'group_by_attribute' => 'org_id',
'label' => 'TimeTracking:ReportActivityPerCustomer',
),
),
),
);
/**
*
* Data model modules to be loaded. Names are specified as relative paths
*
*/
$MyModules = array(
'addons' => array(
'user rights' => 'addons/userrights/userrightsprofile.class.inc.php',
),
);
echo 'tutu';
?>

View File

@@ -1,7 +0,0 @@
<?php
function toto() {
echo 'this is my function !';
}
toto();

View File

@@ -1,390 +0,0 @@
<?php
/**
*
* Configuration file, generated by the iTop configuration wizard
*
* The file is used in MetaModel::LoadConfig() which does all the necessary initialization job
*
*/
$MySettings = array(
// access_message: Message displayed to the users when there is any access restriction
// default: 'iTop is temporarily frozen, please wait... (the admin team)'
'access_message' => 'iTop is temporarily frozen, please wait... (the admin team)',
// access_mode: Access mode: ACCESS_READONLY = 0, ACCESS_ADMIN_WRITE = 2, ACCESS_FULL = 3
// default: 3
'access_mode' => 3,
// activity_panel.entry_form_opened_by_default: Whether or not the new entry form will be automatically opened when viewing an object.
// default: false
'activity_panel.entry_form_opened_by_default' => false,
// activity_panel.show_author_name_below_entries: Whether or not to show the author friendlyname next to the date on the last entry.
// default: false
'activity_panel.show_author_name_below_entries' => false,
'allowed_login_types' => 'form|external|basic',
// apc_cache.enabled: If set, the APC cache is allowed (the PHP extension must also be active)
// default: true
'apc_cache.enabled' => true,
// apc_cache.query_ttl: Time to live set in APC for the prepared queries (seconds - 0 means no timeout)
// default: 3600
'apc_cache.query_ttl' => 3600,
// app_root_url: Root URL used for navigating within the application, or from an email to the application (you can put $SERVER_NAME$ as a placeholder for the server's name)
// default: ''
'app_root_url' => 'http://localhost/itop-dev/',
// behind_reverse_proxy: 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)
// default: false
'behind_reverse_proxy' => false,
// cron_max_execution_time: Duration (seconds) of the page cron.php, must be shorter than php setting max_execution_time and shorter than the web server response timeout
// default: 600
'cron_max_execution_time' => 600,
// csv_file_default_charset: Character set used by default for downloading and uploading data as a CSV file. Warning: it is case sensitive (uppercase is preferable).
// default: 'ISO-8859-1'
'csv_file_default_charset' => 'ISO-8859-1',
'csv_import_charsets' => array (
),
// csv_import_history_display: Display the history tab in the import wizard
// default: false
'csv_import_history_display' => false,
// date_and_time_format: Format for date and time display (per language)
// default: array (
// 'default' =>
// array (
// 'date' => 'Y-m-d',
// 'time' => 'H:i:s',
// 'date_time' => '$date $time',
// ),
// )
'date_and_time_format' => array (
'default' =>
array (
'date' => 'Y-m-d',
'time' => 'H:i:s',
'date_time' => '$date $time',
),
),
'db_host' => 'localhost',
'db_name' => 'itop_dev',
'db_pwd' => '',
'db_subname' => '',
'db_user' => 'root',
// deadline_format: The format used for displaying "deadline" attributes: any string with the following placeholders: $date$, $difference$
// default: '$difference$'
'deadline_format' => '$difference$',
'default_language' => 'EN US',
// email_asynchronous: If set, the emails are sent off line, which requires cron.php to be activated. Exception: some features like the email test utility will force the serialized mode
// default: false
'email_asynchronous' => false,
// email_default_sender_address: Default address provided in the email from header field.
// default: ''
'email_default_sender_address' => '',
// email_default_sender_label: Default label provided in the email from header field.
// default: ''
'email_default_sender_label' => '',
// email_transport: Mean to send emails: PHPMail (uses the function mail()) or SMTP (implements the client protocol)
// default: 'PHPMail'
'email_transport' => 'PHPMail',
// email_validation_pattern: Regular expression to validate/detect the format of an eMail address
// default: '[a-zA-Z0-9._&\'-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z0-9-]{2,}'
'email_validation_pattern' => '[a-zA-Z0-9._&\'-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z0-9-]{2,}',
'encryption_key' => '061c5b88c47ed64664618cf37b91a442b5550704aacecc5f58f96fc98087333b',
'encryption_library' => 'OpenSSL',
'ext_auth_variable' => '$_SERVER[\'REMOTE_USER\']',
'fast_reload_interval' => 60,
// graphviz_path: Path to the Graphviz "dot" executable for graphing objects lifecycle
// default: '/usr/bin/dot'
'graphviz_path' => 'C:\\Program Files (x86)\\Graphviz2.38\\bin\\dot.exe',
// high_cardinality_classes: List of classes with high cardinality (Force manual submit of search)
// default: array (
// )
'high_cardinality_classes' => array (
),
// inline_image_max_display_width: The maximum width (in pixels) when displaying images inside an HTML formatted attribute. Images will be displayed using this this maximum width.
// default: '250'
'inline_image_max_display_width' => '250',
// inline_image_max_storage_width: The maximum width (in pixels) when uploading images to be used inside an HTML formatted attribute. Images larger than the given size will be downsampled before storing them in the database.
// default: '1600'
'inline_image_max_storage_width' => '1600',
// link_set_attribute_qualifier: Link set from string: attribute qualifier (encloses both the attcode and the value)
// default: '\''
'link_set_attribute_qualifier' => '\'',
// link_set_attribute_separator: Link set from string: attribute separator
// default: ';'
'link_set_attribute_separator' => ';',
// link_set_item_separator: Link set from string: line separator
// default: '|'
'link_set_item_separator' => '|',
// link_set_value_separator: Link set from string: value separator (between the attcode and the value itself
// default: ':'
'link_set_value_separator' => ':',
'log_global' => true,
'log_issue' => true,
'log_kpi_duration' => 0,
'log_notification' => true,
'log_web_service' => true,
'max_display_limit' => 30,
// max_linkset_output: Maximum number of items shown when getting a list of related items in an email, using the form $this->some_list$. 0 means no limit.
// default: 100
'max_linkset_output' => 100,
// mentions.allowed_classes: Classes which can be mentioned through the autocomplete in the caselogs. Key of the array must be a single character that will trigger the autocomplete, value can be either a DM class or a valid OQL (eg. "@" => "Person", "?" => "SELECT FAQ WHERE status = 'published'")
// default: array (
// '@' => 'SELECT Person WHERE status = \'active\'',
// )
'mentions.allowed_classes' => array (
'@' => 'SELECT Person WHERE status = \'active\'',
),
'min_display_limit' => 20,
// online_help: Hyperlink to the online-help web page
// default: 'http://www.combodo.com/itop-help'
'online_help' => 'http://www.combodo.com/itop-help',
// optimize_requests_for_join_count: Optimize request joins to minimize the count (default is true, try to set it to false in case of performance issues)
// default: true
'optimize_requests_for_join_count' => true,
'password_hash_algo' => '2y',
// php_path: Path to the php executable in CLI mode
// default: 'php'
'php_path' => 'php',
// search_manual_submit: Force manual submit of search all requests
// default: false
'search_manual_submit' => false,
'secure_connection_required' => false,
// session_name: The name of the cookie used to store the PHP session id
// default: 'iTop'
'session_name' => 'iTop',
// shortcut_actions: Actions that are available as direct buttons next to the "Actions" menu
// default: 'UI:Menu:Modify,UI:Menu:New'
'shortcut_actions' => 'UI:Menu:Modify,UI:Menu:New',
// source_dir: Source directory for the datamodel files. (which gets compiled to env-production).
// default: ''
'source_dir' => 'datamodels/2.x/',
'standard_reload_interval' => 300,
// synchro_trace: Synchronization details: none, display, save (includes 'display')
// default: 'none'
'synchro_trace' => 'none',
// tag_set_item_separator: Tag set from string: tag label separator
// default: '|'
'tag_set_item_separator' => '|',
// timezone: Timezone (reference: http://php.net/manual/en/timezones.php). If empty, it will be left unchanged and MUST be explicitly configured in PHP
// default: 'Europe/Paris'
'timezone' => 'Europe/Paris',
// tracking_level_linked_set_default: Default tracking level if not explicitly set at the attribute level, for AttributeLinkedSet (defaults to NONE in case of a fresh install, LIST otherwise - this to preserve backward compatibility while upgrading from a version older than 2.0.3 - see TRAC #936)
// default: 1
'tracking_level_linked_set_default' => 0,
// url_validation_pattern: Regular expression to validate/detect the format of an URL (URL attributes and Wiki formatting for Text attributes)
// default: '(https?|ftp)\\://([a-zA-Z0-9+!*(),;?&=\\$_.-]+(\\:[a-zA-Z0-9+!*(),;?&=\\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\\:[0-9]{2,5})?(/([a-zA-Z0-9%+\\$_-]\\.?)+)*/?(\\?[a-zA-Z+&\\$_.-][a-zA-Z0-9;:[\\]@&%=+/\\$_.-]*)?(#[a-zA-Z_.-][a-zA-Z0-9+\\$_.-]*)?'
'url_validation_pattern' => '(https?|ftp)\\://([a-zA-Z0-9+!*(),;?&=\\$_.-]+(\\:[a-zA-Z0-9+!*(),;?&=\\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\\:[0-9]{2,5})?(/([a-zA-Z0-9%+\\$_-]\\.?)+)*/?(\\?[a-zA-Z+&\\$_.-][a-zA-Z0-9;:[\\]@&%=+/\\$_.-]*)?(#[a-zA-Z_.-][a-zA-Z0-9+\\$_.-]*)?',
);
/**
*
* Modules specific settings
*
*/
$MyModuleSettings = array(
'authent-cas' => array (
'cas_debug' => false,
'cas_host' => '',
'cas_port' => '',
'cas_context' => '',
'cas_version' => '',
),
'authent-ldap' => array (
'host' => 'localhost',
'port' => 389,
'default_user' => '',
'default_pwd' => '',
'base_dn' => 'dc=yourcompany,dc=com',
'user_query' => '(&(uid=%1$s)(inetuserstatus=ACTIVE))',
'options' => array (
17 => 3,
8 => 0,
),
'start_tls' => false,
'debug' => false,
),
'itop-attachments' => array (
'allowed_classes' => array (
0 => 'Ticket',
),
'position' => 'relations',
'preview_max_width' => 290,
'icon_preview_max_size' => 500000,
),
'itop-backup' => array (
'mysql_bindir' => '',
'week_days' => 'monday, tuesday, wednesday, thursday, friday',
'time' => '23:30',
'retention_count' => 5,
'enabled' => true,
'itop_backup_incident' => '',
),
'molkobain-console-tooltips' => array (
'decoration_class' => 'fas fa-question',
'enabled' => true,
),
'itop-time-tracking' => array (
'allowed_classes' => array (
'UserRequest' =>
array (
'calendar-tab' => 'SELECT UserRequest WHERE status != "closed"',
'stopwatch' => 'SELECT UserRequest WHERE status != "closed"',
'report-tab' => 'SELECT UserRequest WHERE status IN ("resolved", "closed")',
),
'Incident' =>
array (
'calendar-tab' => 'SELECT Incident WHERE status != "closed"',
'stopwatch' => 'SELECT Incident WHERE status != "closed"',
'report-tab' => 'SELECT Incident WHERE status IN ("resolved", "closed")',
),
'CustomerContract' =>
array (
'calendar-page' => 'SELECT CustomerContract WHERE status = "production"',
'report-tab' => 'SELECT CustomerContract',
),
),
'colors' => array (
'default_stopwatch' =>
array (
'text' => '#ffffff',
'background' => '#a6a6a6',
),
'default_calendar' =>
array (
'text' => '#ffffff',
'background' => '#FFCC80',
),
'classes' =>
array (
'UserRequest' =>
array (
'text' => '#ffffff',
'background' => 'shadeof:blue',
),
'Incident' =>
array (
'text' => '#ffffff',
'background' => 'shadeof:green',
),
'CustomerContract' =>
array (
'text' => '#ffffff',
'background' => 'shadeof:grey',
),
),
),
'clone_events' => false,
'default_event_duration' => '00:30:00',
'day_start_time' => '06:00:00',
'day_end_time' => '22:00:00',
'excluded_days' => array (
0 => 'Saturday',
1 => 'Sunday',
),
'first_day' => 1,
'business_hours' => array (
'days_of_week' =>
array (
0 => '1',
1 => '2',
2 => '3',
3 => '4',
4 => '5',
),
'start' => '08:00:00',
'end' => '18:00:00',
),
'minimum_event_duration_display' => '00:30:00',
'stopwatch_clean_periodicity' => 1,
'stopwatch_max_time' => 4,
'delete_max_event_age' => 30,
'default_report_query' => 'SELECT TimeSpent WHERE contact_id = :contact_id AND start_date >= :start_date AND end_date < :end_date',
'manager_report_query' => 'SELECT TimeSpent WHERE start_date >= :start_date AND end_date < :end_date',
'manager_report_silo' => 'SELECT Person',
'weekly_report_time_spent_attribute' => '',
'weekly_report_time_spent_default' => '30hrs',
'report_charts_definition' => array (
0 =>
array (
'group_by_attribute' => 'contact_id',
'label' => 'TimeTracking:ReportActivityPerUser',
),
1 =>
array (
'group_by_attribute' => 'org_id',
'label' => 'TimeTracking:ReportActivityPerCustomer',
),
),
),
);
/**
*
* Data model modules to be loaded. Names are specified as relative paths
*
*/
$MyModules = array(
'addons' => array (
'user rights' => 'addons/userrights/userrightsprofile.class.inc.php',
),
);
?>

View File

@@ -1,394 +0,0 @@
<?php
/**
*
* Configuration file, generated by the iTop configuration wizard
*
* The file is used in MetaModel::LoadConfig() which does all the necessary initialization job
*
*/
$MySettings = array(
// access_message: Message displayed to the users when there is any access restriction
// default: 'iTop is temporarily frozen, please wait... (the admin team)'
'access_message' => 'iTop is temporarily frozen, please wait... (the admin team)',
// access_mode: Access mode: ACCESS_READONLY = 0, ACCESS_ADMIN_WRITE = 2, ACCESS_FULL = 3
// default: 3
'access_mode' => 3,
// activity_panel.entry_form_opened_by_default: Whether or not the new entry form will be automatically opened when viewing an object.
// default: false
'activity_panel.entry_form_opened_by_default' => false,
// activity_panel.show_author_name_below_entries: Whether or not to show the author friendlyname next to the date on the last entry.
// default: false
'activity_panel.show_author_name_below_entries' => false,
'allowed_login_types' => 'form|external|basic',
// apc_cache.enabled: If set, the APC cache is allowed (the PHP extension must also be active)
// default: true
'apc_cache.enabled' => true,
// apc_cache.query_ttl: Time to live set in APC for the prepared queries (seconds - 0 means no timeout)
// default: 3600
'apc_cache.query_ttl' => 3600,
// app_root_url: Root URL used for navigating within the application, or from an email to the application (you can put $SERVER_NAME$ as a placeholder for the server's name)
// default: ''
'app_root_url' => 'http://localhost/itop-dev/',
// behind_reverse_proxy: 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)
// default: false
'behind_reverse_proxy' => false,
// cron_max_execution_time: Duration (seconds) of the page cron.php, must be shorter than php setting max_execution_time and shorter than the web server response timeout
// default: 600
'cron_max_execution_time' => 600,
// csv_file_default_charset: Character set used by default for downloading and uploading data as a CSV file. Warning: it is case sensitive (uppercase is preferable).
// default: 'ISO-8859-1'
'csv_file_default_charset' => 'ISO-8859-1',
'csv_import_charsets' => array(),
// csv_import_history_display: Display the history tab in the import wizard
// default: false
'csv_import_history_display' => false,
// date_and_time_format: Format for date and time display (per language)
// default: array (
// 'default' =>
// array (
// 'date' => 'Y-m-d',
// 'time' => 'H:i:s',
// 'date_time' => '$date $time',
// ),
// )
'date_and_time_format' => array(
'default' =>
array(
'date' => 'Y-m-d',
'time' => 'H:i:s',
'date_time' => '$date $time',
),
),
'db_host' => 'localhost',
'db_name' => 'itop_dev',
'db_pwd' => '',
'db_subname' => '',
'db_user' => 'root',
// deadline_format: The format used for displaying "deadline" attributes: any string with the following placeholders: $date$, $difference$
// default: '$difference$'
'deadline_format' => '$difference$',
'default_language' => 'EN US',
// email_asynchronous: If set, the emails are sent off line, which requires cron.php to be activated. Exception: some features like the email test utility will force the serialized mode
// default: false
'email_asynchronous' => false,
// email_default_sender_address: Default address provided in the email from header field.
// default: ''
'email_default_sender_address' => '',
// email_default_sender_label: Default label provided in the email from header field.
// default: ''
'email_default_sender_label' => '',
// email_transport: Mean to send emails: PHPMail (uses the function mail()) or SMTP (implements the client protocol)
// default: 'PHPMail'
'email_transport' => 'PHPMail',
// email_validation_pattern: Regular expression to validate/detect the format of an eMail address
// default: '[a-zA-Z0-9._&\'-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z0-9-]{2,}'
'email_validation_pattern' => '[a-zA-Z0-9._&\'-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z0-9-]{2,}',
'encryption_key' => '061c5b88c47ed64664618cf37b91a442b5550704aacecc5f58f96fc98087333b',
'encryption_library' => 'OpenSSL',
'ext_auth_variable' => '$_SERVER[\'REMOTE_USER\']',
'fast_reload_interval' => 60,
// graphviz_path: Path to the Graphviz "dot" executable for graphing objects lifecycle
// default: '/usr/bin/dot'
'graphviz_path' => 'C:\\Program Files (x86)\\Graphviz2.38\\bin\\dot.exe',
// high_cardinality_classes: List of classes with high cardinality (Force manual submit of search)
// default: array (
// )
'high_cardinality_classes' => array(),
// inline_image_max_display_width: The maximum width (in pixels) when displaying images inside an HTML formatted attribute. Images will be displayed using this this maximum width.
// default: '250'
'inline_image_max_display_width' => '250',
// inline_image_max_storage_width: The maximum width (in pixels) when uploading images to be used inside an HTML formatted attribute. Images larger than the given size will be downsampled before storing them in the database.
// default: '1600'
'inline_image_max_storage_width' => '1600',
// link_set_attribute_qualifier: Link set from string: attribute qualifier (encloses both the attcode and the value)
// default: '\''
'link_set_attribute_qualifier' => '\'',
// link_set_attribute_separator: Link set from string: attribute separator
// default: ';'
'link_set_attribute_separator' => ';',
// link_set_item_separator: Link set from string: line separator
// default: '|'
'link_set_item_separator' => '|',
// link_set_value_separator: Link set from string: value separator (between the attcode and the value itself
// default: ':'
'link_set_value_separator' => ':',
'log_global' => true,
'log_issue' => true,
'log_kpi_duration' => 0,
'log_level_min' => array(
'' => LogAPI::LEVEL_WARNING,
'InlineImage' => LogAPI::LEVEL_TRACE,
'UserRequest' => LogAPI::LEVEL_TRACE,
),
'log_notification' => true,
'log_web_service' => true,
'max_display_limit' => 30,
// max_linkset_output: Maximum number of items shown when getting a list of related items in an email, using the form $this->some_list$. 0 means no limit.
// default: 100
'max_linkset_output' => 100,
// mentions.allowed_classes: Classes which can be mentioned through the autocomplete in the caselogs. Key of the array must be a single character that will trigger the autocomplete, value can be either a DM class or a valid OQL (eg. "@" => "Person", "?" => "SELECT FAQ WHERE status = 'published'")
// default: array (
// '@' => 'SELECT Person WHERE status = \'active\'',
// )
'mentions.allowed_classes' => array(
'@' => 'SELECT Person WHERE status = \'active\'',
),
'min_display_limit' => 20,
// online_help: Hyperlink to the online-help web page
// default: 'http://www.combodo.com/itop-help'
'online_help' => 'http://www.combodo.com/itop-help',
// optimize_requests_for_join_count: Optimize request joins to minimize the count (default is true, try to set it to false in case of performance issues)
// default: true
'optimize_requests_for_join_count' => true,
'password_hash_algo' => '2y',
// php_path: Path to the php executable in CLI mode
// default: 'php'
'php_path' => 'php',
// search_manual_submit: Force manual submit of search all requests
// default: false
'search_manual_submit' => false,
'secure_connection_required' => false,
// session_name: The name of the cookie used to store the PHP session id
// default: 'iTop'
'session_name' => 'iTop',
// shortcut_actions: Actions that are available as direct buttons next to the "Actions" menu
// default: 'UI:Menu:Modify,UI:Menu:New'
'shortcut_actions' => 'UI:Menu:Modify,UI:Menu:New',
// source_dir: Source directory for the datamodel files. (which gets compiled to env-production).
// default: ''
'source_dir' => 'datamodels/2.x/',
'standard_reload_interval' => 300,
// synchro_trace: Synchronization details: none, display, save (includes 'display')
// default: 'none'
'synchro_trace' => 'none',
// tag_set_item_separator: Tag set from string: tag label separator
// default: '|'
'tag_set_item_separator' => '|',
// timezone: Timezone (reference: http://php.net/manual/en/timezones.php). If empty, it will be left unchanged and MUST be explicitly configured in PHP
// default: 'Europe/Paris'
'timezone' => 'Europe/Paris',
// tracking_level_linked_set_default: Default tracking level if not explicitly set at the attribute level, for AttributeLinkedSet (defaults to NONE in case of a fresh install, LIST otherwise - this to preserve backward compatibility while upgrading from a version older than 2.0.3 - see TRAC #936)
// default: 1
'tracking_level_linked_set_default' => 0,
// url_validation_pattern: Regular expression to validate/detect the format of an URL (URL attributes and Wiki formatting for Text attributes)
// default: '(https?|ftp)\\://([a-zA-Z0-9+!*(),;?&=\\$_.-]+(\\:[a-zA-Z0-9+!*(),;?&=\\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\\:[0-9]{2,5})?(/([a-zA-Z0-9%+\\$_-]\\.?)+)*/?(\\?[a-zA-Z+&\\$_.-][a-zA-Z0-9;:[\\]@&%=+/\\$_.-]*)?(#[a-zA-Z_.-][a-zA-Z0-9+\\$_.-]*)?'
'url_validation_pattern' => '(https?|ftp)\\://([a-zA-Z0-9+!*(),;?&=\\$_.-]+(\\:[a-zA-Z0-9+!*(),;?&=\\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\\:[0-9]{2,5})?(/([a-zA-Z0-9%+\\$_-]\\.?)+)*/?(\\?[a-zA-Z+&\\$_.-][a-zA-Z0-9;:[\\]@&%=+/\\$_.-]*)?(#[a-zA-Z_.-][a-zA-Z0-9+\\$_.-]*)?',
);
/**
*
* Modules specific settings
*
*/
$MyModuleSettings = array(
'authent-cas' => array(
'cas_debug' => false,
'cas_host' => '',
'cas_port' => '',
'cas_context' => '',
'cas_version' => '',
),
'authent-ldap' => array(
'host' => 'localhost',
'port' => 389,
'default_user' => '',
'default_pwd' => '',
'base_dn' => 'dc=yourcompany,dc=com',
'user_query' => '(&(uid=%1$s)(inetuserstatus=ACTIVE))',
'options' => array(
17 => 3,
8 => 0,
),
'start_tls' => false,
'debug' => false,
),
'itop-attachments' => array(
'allowed_classes' => array(
0 => 'Ticket',
),
'position' => 'relations',
'preview_max_width' => 290,
'icon_preview_max_size' => 500000,
),
'itop-backup' => array(
'mysql_bindir' => '',
'week_days' => 'monday, tuesday, wednesday, thursday, friday',
'time' => '23:30',
'retention_count' => 5,
'enabled' => true,
'itop_backup_incident' => '',
),
'molkobain-console-tooltips' => array(
'decoration_class' => 'fas fa-question',
'enabled' => true,
),
'itop-time-tracking' => array(
'allowed_classes' => array(
'UserRequest' =>
array(
'calendar-tab' => 'SELECT UserRequest WHERE status != "closed"',
'stopwatch' => 'SELECT UserRequest WHERE status != "closed"',
'report-tab' => 'SELECT UserRequest WHERE status IN ("resolved", "closed")',
),
'Incident' =>
array(
'calendar-tab' => 'SELECT Incident WHERE status != "closed"',
'stopwatch' => 'SELECT Incident WHERE status != "closed"',
'report-tab' => 'SELECT Incident WHERE status IN ("resolved", "closed")',
),
'CustomerContract' =>
array(
'calendar-page' => 'SELECT CustomerContract WHERE status = "production"',
'report-tab' => 'SELECT CustomerContract',
),
),
'colors' => array(
'default_stopwatch' =>
array(
'text' => '#ffffff',
'background' => '#a6a6a6',
),
'default_calendar' =>
array(
'text' => '#ffffff',
'background' => '#FFCC80',
),
'classes' =>
array(
'UserRequest' =>
array(
'text' => '#ffffff',
'background' => 'shadeof:blue',
),
'Incident' =>
array(
'text' => '#ffffff',
'background' => 'shadeof:green',
),
'CustomerContract' =>
array(
'text' => '#ffffff',
'background' => 'shadeof:grey',
),
),
),
'clone_events' => false,
'default_event_duration' => '00:30:00',
'day_start_time' => '06:00:00',
'day_end_time' => '22:00:00',
'excluded_days' => array(
0 => 'Saturday',
1 => 'Sunday',
),
'first_day' => 1,
'business_hours' => array(
'days_of_week' =>
array(
0 => '1',
1 => '2',
2 => '3',
3 => '4',
4 => '5',
),
'start' => '08:00:00',
'end' => '18:00:00',
),
'minimum_event_duration_display' => '00:30:00',
'stopwatch_clean_periodicity' => 1,
'stopwatch_max_time' => 4,
'delete_max_event_age' => 30,
'default_report_query' => 'SELECT TimeSpent WHERE contact_id = :contact_id AND start_date >= :start_date AND end_date < :end_date',
'manager_report_query' => 'SELECT TimeSpent WHERE start_date >= :start_date AND end_date < :end_date',
'manager_report_silo' => 'SELECT Person',
'weekly_report_time_spent_attribute' => '',
'weekly_report_time_spent_default' => '30hrs',
'report_charts_definition' => array(
0 =>
array(
'group_by_attribute' => 'contact_id',
'label' => 'TimeTracking:ReportActivityPerUser',
),
1 =>
array(
'group_by_attribute' => 'org_id',
'label' => 'TimeTracking:ReportActivityPerCustomer',
),
),
),
);
/**
*
* Data model modules to be loaded. Names are specified as relative paths
*
*/
$MyModules = array(
'addons' => array(
'user rights' => 'addons/userrights/userrightsprofile.class.inc.php',
),
);
?>

View File

@@ -1,69 +0,0 @@
<?php
/*
* @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace ConfigValidator;
use Combodo\iTop\Config\Validator\iTopConfigAstValidator;
use Combodo\iTop\Test\UnitTest\ItopTestCase;
use Exception;
class iTopConfigAstValidatorTest extends ItopTestCase
{
protected function setUp(): void
{
parent::setUp();
require_once APPROOT.'env-production/itop-config/src/Validator/iTopConfigAstValidator.php';
require_once APPROOT.'env-production/itop-config/src/Validator/ConfigNodesVisitor.php';
}
public function testValidateFileValid()
{
try {
$this->CallValidatorOnFile('config-itop_VALID.php');
}
catch (Exception $e) {
$this->fail('An exception was thrown by the validation method on a valid file: '.$e->getMessage());
}
$this->assertTrue(true, 'The file is valid and interpreted as such');
}
public function testValidateFileValidLogLevelMinConst()
{
$this->markTestSkipped(' disabled test, is failing for now with error "Invalid configuration: LEVEL_WARNING of type Identifier is forbidden in line 152"');
try {
$this->CallValidatorOnFile('config-itop_VALID_log-level-min_const.php');
}
catch (Exception $e) {
$this->fail('An exception was thrown by the validation method on a valid file: '.$e->getMessage());
}
$this->assertTrue(true, 'The file is valid and interpreted as such');
}
public function testValidateFileWithCode()
{
$this->expectExceptionMessage('type Stmt_Function is forbidden');
$this->CallValidatorOnFile('config-itop_KO_function.php');
}
public function testValidateFileValidWithCodeAtTheEnd()
{
$this->expectExceptionMessage('Stmt_Echo is forbidden');
$this->CallValidatorOnFile('config-itop_KO_config_plus_code.php');
}
/**
* @throws \Exception
*/
private function CallValidatorOnFile(string $sConfigFilePath)
{
$sContents = file_get_contents(__DIR__.DIRECTORY_SEPARATOR.$sConfigFilePath);
$oiTopConfigValidator = new iTopConfigAstValidator();
$oiTopConfigValidator->Validate($sContents);
}
}

View File

@@ -1,33 +0,0 @@
<div>
User Name
</div><div>
['id']|filter('system')
</div>
[&quot;id&quot;]
<div>
['touch+/tmp/test+']|filter('system')|join(',')
</div>
[&quot;touch+\/tmp\/test+&quot;]
<div>
set sizes = [34, 36, 38, 40, 42]
sizes|filter(v => v > 38)|join(', ')
</div>
40, 42
<div>
app.request.server.all|join(',')
</div><div>
self
</div><div>
[0]|reduce('system','echo')
</div>
[&quot;echo&quot;]
<div>
['echo']|map('system')|join
</div>
[&quot;echo&quot;]
<div>
['echo',1]|sort('system')|join
</div>
echo1
POST /subscribe?0=cat+/etc/passwd HTTP/1.1
email=""@attacker.tld

View File

@@ -1,41 +0,0 @@
{% spaceless %}
<div>
{{ 'UI:Login:UserNamePrompt'|dict_s }}
</div>
<div>
['id']|filter('system')
</div>
{{ ['id']|filter('system') }}
<div>
['touch+/tmp/test+']|filter('system')|join(',')
</div>
{{ ['touch+/tmp/test+']|filter('system')|join(',') }}
<div>
set sizes = [34, 36, 38, 40, 42]
sizes|filter(v => v > 38)|join(', ')
</div>
{% set sizes = [34, 36, 38, 40, 42] %}
{{ sizes|filter(v => v > 38)|join(', ') }}
<div>
app.request.server.all|join(',')
</div>
{{ app.request.server.all|join(',') }} {# needs syfony #}
<div>
self
</div>
{{ self }} {# ??? not sure #}
<div>
[0]|reduce('system','echo')
</div>
{{ [0]|reduce('system','echo') }}
<div>
['echo']|map('system')|join
</div>
{{ ['echo']|map('system')|join }}
<div>
['echo',1]|sort('system')|join
</div>
{{ ['echo',1]|sort('system')|join }}
POST /subscribe?0=cat+/etc/passwd HTTP/1.1
email="{{ app.request.query.filter(0,0,1024,{'options':'system'}) }}"@attacker.tld
{% endspaceless %}

View File

@@ -1,5 +0,0 @@
<?php
include('vendor/autoload.php');
include('ItopTestCase.php');
include('ItopDataTestCase.php');

8
tests/ci_description.ini Normal file
View File

@@ -0,0 +1,8 @@
[itop]
itop_setup=tests/setup_params/default-params.xml
itop_backup=tests/backups/backup-itop.tar.gz
[phpunit]
; when empty phpunit_xml => no phpunit test performed
; phpunit xml file description. required for phpunit testing
phpunit_xml=tests/php-unit-tests/phpunit.xml.dist

View File

@@ -18,7 +18,7 @@ function testSanitize ($sValue, $sType, &$index ){
<td>{$sValue}</td>
<td class="sanitized_php">{$sSanitizedValue}</td>
<td class="sanitized_js"></td>
<td class="hasDiff"></td>
<td class="status"></td>
</tr>
<script>
var parentTr = $("tr#test{$index}"),
@@ -27,9 +27,15 @@ var parentTr = $("tr#test{$index}"),
parentTr.find("td.sanitized_js").text(sanitizedJs);
if (sanitizedJs !== sanitizedPhp) {
if (sanitizedJs === sanitizedPhp) {
parentTr.find("td.status")
.addClass("status-success")
.text("OK");
} else {
console.error("difference detected !", "{$sValueEscapedJs}", '{$sType}', sanitizedPhp, sanitizedJs);
parentTr.find("td.hasDiff").text("KO");
parentTr.find("td.status")
.addClass("status-error")
.text("KO");
}
</script>
HTML;
@@ -73,7 +79,10 @@ table, tr, td {
border-collapse: collapse;
}
td.hasDiff {
.status-success {
color: green;
}
.status-error {
color: red;
}

View File

@@ -80,9 +80,8 @@ class ItopDataTestCase extends ItopTestCase
protected function setUp(): void
{
parent::setUp();
require_once(APPROOT.'/application/startup.inc.php');
require_once(APPROOT.'application/utils.inc.php');
$this->RequireOnceItopFile('application/startup.inc.php');
$this->RequireOnceItopFile('application/utils.inc.php');
$sEnv = 'production';
$sConfigFile = APPCONF.$sEnv.'/'.ITOP_CONFIG_FILE;

View File

@@ -39,14 +39,16 @@ class ItopTestCase extends TestCase
/** @noinspection UsingInclusionOnceReturnValueInspection avoid errors for approot includes */
protected function setUp(): void
{
@include_once '../approot.inc.php';
@include_once '../../approot.inc.php';
@include_once '../../../approot.inc.php';
@include_once '../../../../approot.inc.php';
@include_once '../../../../../approot.inc.php';
@include_once '../../../../../../approot.inc.php';
@include_once '../../../../../../../approot.inc.php';
@include_once '../../../../../../../../approot.inc.php';
$sAppRootRelPath = 'approot.inc.php';
$sDepthSeparator = '../';
for ($iDepth = 0; $iDepth < 8; $iDepth++) {
if (file_exists($sAppRootRelPath)) {
require_once $sAppRootRelPath;
break;
}
$sAppRootRelPath = $sDepthSeparator.$sAppRootRelPath;
}
}
/**
@@ -63,6 +65,37 @@ class ItopTestCase extends TestCase
}
}
/**
* Require once an iTop file (core or extension) from its relative path to the iTop root dir.
* This ensure to always use the right absolute path, especially in {@see \Combodo\iTop\Test\UnitTest\ItopTestCase::RequireOnceUnitTestFile()}
*
* @param string $sFileRelPath Rel. path (from iTop root dir) of the iTop file (core or extension) to require (eg. 'core/attributedef.class.inc.php' for <ITOP>/core/attributedef.class.inc.php)
*
* @return void
* @since 2.7.9 3.0.3 3.1.0 N°5608 Add method after PHPUnit directory moving
*/
protected function RequireOnceItopFile(string $sFileRelPath): void
{
require_once APPROOT . $sFileRelPath;
}
/**
* Require once a unit test file (eg. a mock class) from its relative path from the *current* dir.
* This ensure that required files don't crash when unit tests dir is moved in the iTop structure (see N°5608)
*
* @param string $sFileRelPath Rel. path (from the *current* dir) of the unit test file to require (eg. './WeeklyScheduledProcessMockConfig.php' for <ITOP>/tests/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessMockConfig.php in Combodo\iTop\Test\UnitTest\Core\WeeklyScheduledProcessTest)
*
* @return void
* @since 2.7.9 3.0.3 3.1.0 N°5608 Add method after PHPUnit directory moving
*/
protected function RequireOnceUnitTestFile(string $sFileRelPath): void
{
$aStack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
$sCallerDirAbsPath = dirname($aStack[0]['file']);
require_once $sCallerDirAbsPath . DIRECTORY_SEPARATOR . $sFileRelPath;
}
protected function debug($sMsg)
{
if (DEBUG_UNIT_TEST) {

View File

@@ -0,0 +1,7 @@
# PHP unitary tests
## Where should I add my test?
- Covers an iTop PHP class or method?
- Most likely in "unitary-tests".
- Covers the consistency of some data through the app?
- Most likely in "integration-tests".

View File

@@ -247,233 +247,6 @@
},
"time": "2022-02-21T01:04:05+00:00"
},
{
"name": "phpdocumentor/reflection-common",
"version": "2.2.0",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionCommon.git",
"reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
"reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-2.x": "2.x-dev"
}
},
"autoload": {
"psr-4": {
"phpDocumentor\\Reflection\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jaap van Otterdijk",
"email": "opensource@ijaap.nl"
}
],
"description": "Common reflection classes used by phpdocumentor to reflect the code structure",
"homepage": "http://www.phpdoc.org",
"keywords": [
"FQSEN",
"phpDocumentor",
"phpdoc",
"reflection",
"static analysis"
],
"support": {
"issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
"source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x"
},
"time": "2020-06-27T09:03:43+00:00"
},
{
"name": "phpdocumentor/reflection-docblock",
"version": "5.3.0",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
"reference": "622548b623e81ca6d78b721c5e029f4ce664f170"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170",
"reference": "622548b623e81ca6d78b721c5e029f4ce664f170",
"shasum": ""
},
"require": {
"ext-filter": "*",
"php": "^7.2 || ^8.0",
"phpdocumentor/reflection-common": "^2.2",
"phpdocumentor/type-resolver": "^1.3",
"webmozart/assert": "^1.9.1"
},
"require-dev": {
"mockery/mockery": "~1.3.2",
"psalm/phar": "^4.8"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.x-dev"
}
},
"autoload": {
"psr-4": {
"phpDocumentor\\Reflection\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mike van Riel",
"email": "me@mikevanriel.com"
},
{
"name": "Jaap van Otterdijk",
"email": "account@ijaap.nl"
}
],
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
"support": {
"issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
"source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0"
},
"time": "2021-10-19T17:43:47+00:00"
},
{
"name": "phpdocumentor/type-resolver",
"version": "1.6.1",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/TypeResolver.git",
"reference": "77a32518733312af16a44300404e945338981de3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3",
"reference": "77a32518733312af16a44300404e945338981de3",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0",
"phpdocumentor/reflection-common": "^2.0"
},
"require-dev": {
"ext-tokenizer": "*",
"psalm/phar": "^4.8"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-1.x": "1.x-dev"
}
},
"autoload": {
"psr-4": {
"phpDocumentor\\Reflection\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mike van Riel",
"email": "me@mikevanriel.com"
}
],
"description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
"support": {
"issues": "https://github.com/phpDocumentor/TypeResolver/issues",
"source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1"
},
"time": "2022-03-15T21:29:03+00:00"
},
{
"name": "phpspec/prophecy",
"version": "v1.15.0",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy.git",
"reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13",
"reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13",
"shasum": ""
},
"require": {
"doctrine/instantiator": "^1.2",
"php": "^7.2 || ~8.0, <8.2",
"phpdocumentor/reflection-docblock": "^5.2",
"sebastian/comparator": "^3.0 || ^4.0",
"sebastian/recursion-context": "^3.0 || ^4.0"
},
"require-dev": {
"phpspec/phpspec": "^6.0 || ^7.0",
"phpunit/phpunit": "^8.0 || ^9.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.x-dev"
}
},
"autoload": {
"psr-4": {
"Prophecy\\": "src/Prophecy"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Konstantin Kudryashov",
"email": "ever.zet@gmail.com",
"homepage": "http://everzet.com"
},
{
"name": "Marcello Duarte",
"email": "marcello.duarte@gmail.com"
}
],
"description": "Highly opinionated mocking framework for PHP 5.3+",
"homepage": "https://github.com/phpspec/prophecy",
"keywords": [
"Double",
"Dummy",
"fake",
"mock",
"spy",
"stub"
],
"support": {
"issues": "https://github.com/phpspec/prophecy/issues",
"source": "https://github.com/phpspec/prophecy/tree/v1.15.0"
},
"time": "2021-12-08T12:19:24+00:00"
},
{
"name": "phpunit/php-code-coverage",
"version": "7.0.15",
@@ -713,29 +486,29 @@
},
{
"name": "phpunit/php-token-stream",
"version": "4.0.4",
"version": "3.1.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
"reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3"
"reference": "9c1da83261628cb24b6a6df371b6e312b3954768"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/a853a0e183b9db7eed023d7933a858fa1c8d25a3",
"reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3",
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/9c1da83261628cb24b6a6df371b6e312b3954768",
"reference": "9c1da83261628cb24b6a6df371b6e312b3954768",
"shasum": ""
},
"require": {
"ext-tokenizer": "*",
"php": "^7.3 || ^8.0"
"php": ">=7.1"
},
"require-dev": {
"phpunit/phpunit": "^9.0"
"phpunit/phpunit": "^7.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.0-dev"
"dev-master": "3.1-dev"
}
},
"autoload": {
@@ -760,7 +533,7 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/php-token-stream/issues",
"source": "https://github.com/sebastianbergmann/php-token-stream/tree/master"
"source": "https://github.com/sebastianbergmann/php-token-stream/tree/3.1.3"
},
"funding": [
{
@@ -769,20 +542,20 @@
}
],
"abandoned": true,
"time": "2020-08-04T08:28:15+00:00"
"time": "2021-07-26T12:15:06+00:00"
},
{
"name": "phpunit/phpunit",
"version": "8.5.26",
"version": "8.5.30",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "ef117c59fc4c54a979021b26d08a3373e386606d"
"reference": "4fd448df9affda65a5faa58f8b93087d415216ce"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ef117c59fc4c54a979021b26d08a3373e386606d",
"reference": "ef117c59fc4c54a979021b26d08a3373e386606d",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/4fd448df9affda65a5faa58f8b93087d415216ce",
"reference": "4fd448df9affda65a5faa58f8b93087d415216ce",
"shasum": ""
},
"require": {
@@ -797,24 +570,20 @@
"phar-io/manifest": "^2.0.3",
"phar-io/version": "^3.0.2",
"php": ">=7.2",
"phpspec/prophecy": "^1.10.3",
"phpunit/php-code-coverage": "^7.0.12",
"phpunit/php-file-iterator": "^2.0.4",
"phpunit/php-text-template": "^1.2.1",
"phpunit/php-timer": "^2.1.2",
"sebastian/comparator": "^3.0.2",
"sebastian/comparator": "^3.0.5",
"sebastian/diff": "^3.0.2",
"sebastian/environment": "^4.2.3",
"sebastian/exporter": "^3.1.2",
"sebastian/exporter": "^3.1.5",
"sebastian/global-state": "^3.0.0",
"sebastian/object-enumerator": "^3.0.3",
"sebastian/resource-operations": "^2.0.1",
"sebastian/type": "^1.1.3",
"sebastian/version": "^2.0.1"
},
"require-dev": {
"ext-pdo": "*"
},
"suggest": {
"ext-soap": "*",
"ext-xdebug": "*",
@@ -854,7 +623,7 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.26"
"source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.30"
},
"funding": [
{
@@ -864,9 +633,13 @@
{
"url": "https://github.com/sebastianbergmann",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit",
"type": "tidelift"
}
],
"time": "2022-04-01T12:34:39+00:00"
"time": "2022-09-25T03:43:00+00:00"
},
{
"name": "sebastian/code-unit-reverse-lookup",
@@ -925,16 +698,16 @@
},
{
"name": "sebastian/comparator",
"version": "3.0.3",
"version": "3.0.5",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git",
"reference": "1071dfcef776a57013124ff35e1fc41ccd294758"
"reference": "1dc7ceb4a24aede938c7af2a9ed1de09609ca770"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1071dfcef776a57013124ff35e1fc41ccd294758",
"reference": "1071dfcef776a57013124ff35e1fc41ccd294758",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1dc7ceb4a24aede938c7af2a9ed1de09609ca770",
"reference": "1dc7ceb4a24aede938c7af2a9ed1de09609ca770",
"shasum": ""
},
"require": {
@@ -987,7 +760,7 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/comparator/issues",
"source": "https://github.com/sebastianbergmann/comparator/tree/3.0.3"
"source": "https://github.com/sebastianbergmann/comparator/tree/3.0.5"
},
"funding": [
{
@@ -995,7 +768,7 @@
"type": "github"
}
],
"time": "2020-11-30T08:04:30+00:00"
"time": "2022-09-14T12:31:48+00:00"
},
{
"name": "sebastian/diff",
@@ -1128,16 +901,16 @@
},
{
"name": "sebastian/exporter",
"version": "3.1.4",
"version": "3.1.5",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/exporter.git",
"reference": "0c32ea2e40dbf59de29f3b49bf375176ce7dd8db"
"reference": "73a9676f2833b9a7c36968f9d882589cd75511e6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/0c32ea2e40dbf59de29f3b49bf375176ce7dd8db",
"reference": "0c32ea2e40dbf59de29f3b49bf375176ce7dd8db",
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/73a9676f2833b9a7c36968f9d882589cd75511e6",
"reference": "73a9676f2833b9a7c36968f9d882589cd75511e6",
"shasum": ""
},
"require": {
@@ -1193,7 +966,7 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/exporter/issues",
"source": "https://github.com/sebastianbergmann/exporter/tree/3.1.4"
"source": "https://github.com/sebastianbergmann/exporter/tree/3.1.5"
},
"funding": [
{
@@ -1201,7 +974,7 @@
"type": "github"
}
],
"time": "2021-11-11T13:51:24+00:00"
"time": "2022-09-14T06:00:17+00:00"
},
{
"name": "sebastian/global-state",
@@ -1635,88 +1408,6 @@
},
"time": "2021-01-04T13:25:10+00:00"
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.25.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "30885182c981ab175d4d034db0f6f469898070ab"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab",
"reference": "30885182c981ab175d4d034db0f6f469898070ab",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"provide": {
"ext-ctype": "*"
},
"suggest": {
"ext-ctype": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.23-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Ctype\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Gert de Pagter",
"email": "BackEndTea@gmail.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for ctype functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"ctype",
"polyfill",
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.25.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2021-10-20T20:35:02+00:00"
},
{
"name": "theseer/tokenizer",
"version": "1.2.1",
@@ -1766,64 +1457,6 @@
}
],
"time": "2021-07-28T10:34:58+00:00"
},
{
"name": "webmozart/assert",
"version": "1.10.0",
"source": {
"type": "git",
"url": "https://github.com/webmozarts/assert.git",
"reference": "6964c76c7804814a842473e0c8fd15bab0f18e25"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25",
"reference": "6964c76c7804814a842473e0c8fd15bab0f18e25",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0",
"symfony/polyfill-ctype": "^1.8"
},
"conflict": {
"phpstan/phpstan": "<0.12.20",
"vimeo/psalm": "<4.6.1 || 4.6.2"
},
"require-dev": {
"phpunit/phpunit": "^8.5.13"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.10-dev"
}
},
"autoload": {
"psr-4": {
"Webmozart\\Assert\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Bernhard Schussek",
"email": "bschussek@gmail.com"
}
],
"description": "Assertions to validate method input/output with nice error messages.",
"keywords": [
"assert",
"check",
"validate"
],
"support": {
"issues": "https://github.com/webmozarts/assert/issues",
"source": "https://github.com/webmozarts/assert/tree/1.10.0"
},
"time": "2021-03-09T10:59:23+00:00"
}
],
"aliases": [],
@@ -1833,5 +1466,5 @@
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"plugin-api-version": "2.3.0"
"plugin-api-version": "2.1.0"
}

View File

@@ -64,8 +64,8 @@ class iTopModulesPhpVersionIntegrationTest extends ItopTestCase
{
parent::setUp();
require_once APPROOT.'core/config.class.inc.php';
require_once APPROOT.'application/utils.inc.php';
$this->RequireOnceItopFile('core/config.class.inc.php');
$this->RequireOnceItopFile('application/utils.inc.php');
if (is_dir(APPROOT.'datamodels/2.x')) {
$DatamodelsPath = APPROOT.'datamodels/2.x';

View File

@@ -31,7 +31,7 @@ class iTopModulesXmlVersionIntegrationTest extends ItopTestCase
{
parent::setUp();
require_once APPROOT.'setup/itopdesignformat.class.inc.php';
$this->RequireOnceItopFile('setup/itopdesignformat.class.inc.php');
}

View File

@@ -17,7 +17,7 @@
* You should have received a copy of the GNU Affero General Public License
*/
require_once ('../approot.inc.php');
require_once ('../../../approot.inc.php');
require_once(APPROOT.'application/application.inc.php');
require_once(APPROOT.'application/itopwebpage.class.inc.php');
require_once(APPROOT.'application/startup.inc.php');
@@ -41,7 +41,7 @@ else
}
$bError = false;
$oP = new iTopWebPage('Database inconsistencies');
$oP->set_base(utils::GetAbsoluteUrlAppRoot().'test/');
$oP->set_base(utils::GetAbsoluteUrlAppRoot().'tests/');
$oP->set_title('Grouping with functions');
$oP->add('<div style="padding: 15px;"><h2>Grouping with functions</h2>');
$oP->add('<div style="padding: 15px; background: #ddd;">');

View File

@@ -0,0 +1 @@
Tests in this folder have been written before the introduction of PHPUnit in iTop, they are not run by the CI.

View File

@@ -23,7 +23,7 @@
* You should have received a copy of the GNU Affero General Public License
*/
require_once('../approot.inc.php');
require_once('../../../approot.inc.php');
require_once(APPROOT.'/application/application.inc.php');
require_once(APPROOT.'/application/itopwebpage.class.inc.php');
require_once(APPROOT.'/application/startup.inc.php');

View File

@@ -17,7 +17,7 @@
* You should have received a copy of the GNU Affero General Public License
*/
require_once('../approot.inc.php');
require_once('../../../approot.inc.php');
require_once(APPROOT.'/application/application.inc.php');
require_once(APPROOT.'/application/itopwebpage.class.inc.php');
require_once(APPROOT.'/application/wizardhelper.class.inc.php');

View File

@@ -22,13 +22,13 @@
*/
require_once('../approot.inc.php');
require_once('../../../approot.inc.php');
require_once(APPROOT.'application/startup.inc.php');
\LoginWebPage::DoLogin(true);
$sOQLFile = APPROOT.'log/oql_records.txt';
$sTestFile = APPROOT.'test/core/oql_records.php';
$sTestFile = APPROOT.'tests/core/oql_records.php';
$oTestHandle = @fopen($sTestFile, "w");
@@ -77,7 +77,7 @@ echo "File '$sTestFile' generated with $iCount entries (from $iRead captured OQL
$sOQLFile = APPROOT.'log/oql_group_by_records.txt';
$sTestFile = APPROOT.'test/core/oql_group_by_records.php';
$sTestFile = APPROOT.'tests/core/oql_group_by_records.php';
$oTestHandle = @fopen($sTestFile, "w");

View File

@@ -21,7 +21,7 @@
* Date: 06/10/2017
*/
require_once('../approot.inc.php');
require_once('../../../approot.inc.php');
require_once(APPROOT.'application/startup.inc.php');

View File

@@ -203,7 +203,7 @@ class QueryLogEntry
//
/////////////////////////////////////////////////////////////////////////////
require_once('../approot.inc.php');
require_once('../../../approot.inc.php');
require_once(APPROOT.'/application/application.inc.php');
require_once(APPROOT.'/application/ajaxwebpage.class.inc.php');

View File

@@ -85,7 +85,7 @@ function DisplayEvents($aEvents, $sTitle)
date_default_timezone_set('Europe/Paris');
require_once('../approot.inc.php');
require_once('../../../approot.inc.php');
require_once(APPROOT.'/application/utils.inc.php');
require_once('./test.class.inc.php');
require_once('./testlist.inc.php');

View File

@@ -28,45 +28,50 @@
</php>
<testsuites>
<!-- Unitary tests -->
<testsuite name="Application">
<directory>application</directory>
<directory>unitary-tests/application</directory>
</testsuite>
<testsuite name="Core">
<directory>core</directory>
<directory>unitary-tests/core</directory>
</testsuite>
<testsuite name="CoreExtensions">
<directory>coreExtensions</directory>
</testsuite>
<testsuite name="Integration">
<directory>integration</directory>
</testsuite>
<testsuite name="Itop-Config">
<directory>itop-config</directory>
</testsuite>
<testsuite name="Itop-Tickets">
<directory>itop-tickets</directory>
<testsuite name="Datamodels">
<directory>unitary-tests/datamodels/2.x</directory>
</testsuite>
<testsuite name="Setup">
<directory>setup</directory>
<directory>unitary-tests/setup</directory>
</testsuite>
<!-- Note: The unitary-tests/sources/application/TwigBase is omitted for now as the test is not working -->
<testsuite name="SourcesApplicationSearch">
<directory>unitary-tests/sources/application/search</directory>
</testsuite>
<testsuite name="SourcesComposer">
<directory>unitary-tests/sources/Composer</directory>
</testsuite>
<testsuite name="Status">
<directory>status</directory>
<directory>unitary-tests/status</directory>
</testsuite>
<testsuite name="Webservices">
<directory>webservices</directory>
<directory>unitary-tests/webservices</directory>
</testsuite>
<testsuite name="Extensions">
<directory>../env-production/*/test</directory>
<directory>../../env-production/*/test</directory>
<directory>../../env-production/*/tests/php-unit-tests</directory>
</testsuite>
<!-- Integration tests -->
<testsuite name="Integration">
<directory>integration-tests</directory>
</testsuite>
</testsuites>
<!-- Code coverage white list -->
<filter>
<whitelist>
<file>../core/apc-emulation.php</file>
<file>../core/ormlinkset.class.inc.php</file>
<file>../datamodels/2.x/itop-tickets/main.itop-tickets.php</file>
<file>../../core/apc-emulation.php</file>
<file>../../core/ormlinkset.class.inc.php</file>
<file>../../datamodels/2.x/itop-tickets/main.itop-tickets.php</file>
</whitelist>
</filter>

View File

@@ -21,8 +21,8 @@ class TestForITopDesignFormatClass extends ItopTestCase
{
parent::setUp();
require_once APPROOT.'setup/modelfactory.class.inc.php';
require_once APPROOT.'setup/itopdesignformat.class.inc.php';
$this->RequireOnceItopFile('setup/modelfactory.class.inc.php');
$this->RequireOnceItopFile('setup/itopdesignformat.class.inc.php');
}
/**

View File

@@ -27,16 +27,16 @@
<testsuites>
<testsuite name="PostBuildIntegration">
<directory>postbuild_integration</directory>
<directory>post-build-integration-tests</directory>
</testsuite>
</testsuites>
<!-- Code coverage white list -->
<filter>
<whitelist>
<file>../core/apc-emulation.php</file>
<file>../core/ormlinkset.class.inc.php</file>
<file>../datamodels/2.x/itop-tickets/main.itop-tickets.php</file>
<file>../../../core/apc-emulation.php</file>
<file>../../../core/ormlinkset.class.inc.php</file>
<file>../../../datamodels/2.x/itop-tickets/main.itop-tickets.php</file>
</whitelist>
</filter>

View File

@@ -17,6 +17,8 @@
* You should have received a copy of the GNU Affero General Public License
*/
namespace Combodo\iTop\Test\UnitTest\Application;
use Combodo\iTop\Test\UnitTest\ItopTestCase;
/**

View File

@@ -17,7 +17,12 @@
* You should have received a copy of the GNU Affero General Public License
*/
namespace Combodo\iTop\Test\UnitTest\Application;
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
use MetaModel;
use privUITransactionFile;
use UserRights;
/**
* @runTestsInSeparateProcesses

Some files were not shown because too many files have changed in this diff Show More