diff --git a/addons/userrights/userrightsprofile.class.inc.php b/addons/userrights/userrightsprofile.class.inc.php index 7325661c0..386876c24 100644 --- a/addons/userrights/userrightsprofile.class.inc.php +++ b/addons/userrights/userrightsprofile.class.inc.php @@ -54,7 +54,7 @@ class URP_Profiles extends UserRightsBaseClassGUI { $aParams = array ( - "category" => "addon/userrights", + "category" => "addon/userrights,grant_by_profile", "key_type" => "autoincrement", "name_attcode" => "name", "state_attcode" => "", diff --git a/application/audit.category.class.inc.php b/application/audit.category.class.inc.php index f4a90c807..4b11d99f3 100644 --- a/application/audit.category.class.inc.php +++ b/application/audit.category.class.inc.php @@ -34,7 +34,7 @@ class AuditCategory extends cmdbAbstractObject { $aParams = array ( - "category" => "application", + "category" => "application, grant_by_profile", "key_type" => "autoincrement", "name_attcode" => "name", "state_attcode" => "", diff --git a/application/audit.rule.class.inc.php b/application/audit.rule.class.inc.php index 8fe0bca2c..fc66cc411 100644 --- a/application/audit.rule.class.inc.php +++ b/application/audit.rule.class.inc.php @@ -35,7 +35,7 @@ class AuditRule extends cmdbAbstractObject { $aParams = array ( - "category" => "application", + "category" => "application, grant_by_profile", "key_type" => "autoincrement", "name_attcode" => "name", "state_attcode" => "", diff --git a/application/datamodel.application.xml b/application/datamodel.application.xml index 335cabd56..e1b66547b 100644 --- a/application/datamodel.application.xml +++ b/application/datamodel.application.xml @@ -1,5 +1,5 @@ - + portal/index.php @@ -19,4 +19,9 @@ + + + 80 + + diff --git a/application/menunode.class.inc.php b/application/menunode.class.inc.php index af12fb44d..06cf0cf8c 100644 --- a/application/menunode.class.inc.php +++ b/application/menunode.class.inc.php @@ -61,11 +61,23 @@ require_once(APPROOT."/application/user.dashboard.class.inc.php"); class ApplicationMenu { + /** + * @var bool + */ static $bAdditionalMenusLoaded = false; + /** + * @var array + */ static $aRootMenus = array(); + /** + * @var array + */ static $aMenusIndex = array(); + /** + * @var string + */ static $sFavoriteSiloQuery = 'SELECT Organization'; - + static public function LoadAdditionalMenus() { if (!self::$bAdditionalMenusLoaded) @@ -96,7 +108,7 @@ class ApplicationMenu /** * Set the query used to limit the list of displayed organizations in the drop-down menu * @param $sOQL string The OQL query returning a list of Organization objects - * @return none + * @return void */ static public function SetFavoriteSiloQuery($sOQL) { @@ -111,11 +123,34 @@ class ApplicationMenu { return self::$sFavoriteSiloQuery; } - - + + /** + * Check wether a menu Id is enabled or not + * @param $sMenuId + * @throws DictExceptionMissingString + */ + static public function CheckMenuIdEnabled($sMenuId) + { + self::LoadAdditionalMenus(); + $oMenuNode = self::GetMenuNode(self::GetMenuIndexById($sMenuId)); + if (is_null($oMenuNode) || !$oMenuNode->IsEnabled()) + { + require_once(APPROOT.'/setup/setuppage.class.inc.php'); + $oP = new SetupPage(Dict::S('UI:PageTitle:FatalError')); + $oP->add("

".Dict::S('UI:Login:Error:AccessRestricted')."

\n"); + $oP->p("".Dict::S('UI:LogOffMenu').""); + $oP->output(); + exit; + } + } + /** * Main function to add a menu entry into the application, can be called during the definition * of the data model objects + * @param MenuNode $oMenuNode + * @param $iParentIndex + * @param $fRank + * @return int */ static public function InsertMenu(MenuNode $oMenuNode, $iParentIndex, $fRank) { @@ -160,9 +195,12 @@ class ApplicationMenu self::LoadAdditionalMenus(); return self::$aMenusIndex; } - + /** * Entry point to display the whole menu into the web page, used by iTopWebPage + * @param $oPage + * @param $aExtraParams + * @throws DictExceptionMissingString */ static public function DisplayMenu($oPage, $aExtraParams) { @@ -173,34 +211,65 @@ class ApplicationMenu $iActiveMenu = self::GetMenuIndexById(self::GetActiveNodeId()); foreach(self::$aRootMenus as $aMenu) { + if (!self::CanDisplayMenu($aMenu)) { continue; } $oMenuNode = self::GetMenuNode($aMenu['index']); - if (!$oMenuNode->IsEnabled()) continue; // Don't display a non-enabled menu $oPage->AddToMenu('

'.$oMenuNode->GetTitle().'

'); $oPage->AddToMenu('
'); + $oPage->AddToMenu(''); + if ($bActive) { - $oPage->AddToMenu(''); - if ($bActive) - { $oPage->add_ready_script( <<AddToMenu('
'); $iAccordion++; } } - + + /** + * Recursively check if the menu and at least one of his sub-menu is enabled + * @param array $aMenu menu entry + * @return bool true if at least one menu is enabled + */ + static private function CanDisplayMenu($aMenu) + { + $oMenuNode = self::GetMenuNode($aMenu['index']); + if ($oMenuNode->IsEnabled()) + { + $aChildren = self::GetChildren($aMenu['index']); + if (count($aChildren) > 0) + { + foreach($aChildren as $aSubMenu) + { + if (self::CanDisplayMenu($aSubMenu)) + { + return true; + } + } + } + else + { + return true; + } + } + return false; + } + /** * Handles the display of the sub-menus (called recursively if necessary) + * @param WebPage $oPage + * @param array $aMenus + * @param array $aExtraParams + * @param int $iActiveMenu * @return true if the currently selected menu is one of the submenus + * @throws DictExceptionMissingString */ static protected function DisplaySubMenu($oPage, $aMenus, $aExtraParams, $iActiveMenu = -1) { @@ -218,13 +287,12 @@ EOF $sHyperlink = $oMenu->GetHyperlink($aExtraParams); if ($sHyperlink != '') { - $oPage->AddToMenu('
  • '.$oMenu->GetTitle().'
  • '); + $oPage->AddToMenu('
  • '.$oMenu->GetTitle().'
  • '); } else { - $oPage->AddToMenu('
  • '.$oMenu->GetTitle().'
  • '); + $oPage->AddToMenu('
  • '.$oMenu->GetTitle().'
  • '); } - $aCurrentMenu = self::$aMenusIndex[$index]; if ($iActiveMenu == $index) { $bActive = true; @@ -239,8 +307,12 @@ EOF } return $bActive; } + /** * Helper function to sort the menus based on their rank + * @param $a + * @param $b + * @return int */ static public function CompareOnRank($a, $b) { @@ -255,17 +327,21 @@ EOF } return $result; } - + /** - * Helper function to retrieve the MenuNodeObject based on its ID + * Helper function to retrieve the MenuNode Object based on its ID + * @param int $index + * @return MenuNode|null */ static public function GetMenuNode($index) { return isset(self::$aMenusIndex[$index]) ? self::$aMenusIndex[$index]['node'] : null; } - + /** * Helper function to get the list of child(ren) of a menu + * @param int $index + * @return array */ static public function GetChildren($index) { @@ -304,8 +380,11 @@ EOF $sMenuId = self::GetDefaultMenuId(); } return $sMenuId; - } + } + /** + * @return null|string + */ static public function GetDefaultMenuId() { static $sDefaultMenuId = null; @@ -322,6 +401,10 @@ EOF return $sDefaultMenuId; } + /** + * @param $sMenuId + * @return string + */ static public function GetRootMenuId($sMenuId) { $iMenuIndex = self::GetMenuIndexById($sMenuId); @@ -366,8 +449,17 @@ EOF */ abstract class MenuNode { + /** + * @var string + */ protected $sMenuId; + /** + * @var int + */ protected $index; + /** + * @var int + */ protected $iParentIndex; /** @@ -394,7 +486,7 @@ abstract class MenuNode * Stimulus to check: if the user can 'apply' this stimulus, then she/he can see this menu */ protected $m_aEnableStimuli; - + /** * Create a menu item, sets the condition to have it displayed and inserts it into the application's main menu * @param string $sMenuId Unique identifier of the menu (used to identify the menu for bookmarking, and for getting the labels from the dictionary) @@ -404,9 +496,8 @@ abstract class MenuNode * @param mixed $iActionCode UR_ACTION_READ, UR_ACTION_MODIFY, UR_ACTION_DELETE, UR_ACTION_BULKREAD, UR_ACTION_BULKMODIFY or UR_ACTION_BULKDELETE * @param integer $iAllowedResults Expected "rights" for the action: either UR_ALLOWED_YES, UR_ALLOWED_NO, UR_ALLOWED_DEPENDS or a mix of them... * @param string $sEnableStimulus The user can see this menu if she/he has enough rights to apply this stimulus - * @return MenuNode */ - public function __construct($sMenuId, $iParentIndex = -1, $fRank = 0, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null) + public function __construct($sMenuId, $iParentIndex = -1, $fRank = 0.0, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null) { $this->sMenuId = $sMenuId; $this->iParentIndex = $iParentIndex; @@ -425,26 +516,43 @@ abstract class MenuNode $this->index = ApplicationMenu::InsertMenu($this, $iParentIndex, $fRank); } + /** + * @return array + */ public function ReflectionProperties() { return $this->aReflectionProperties; } - + + /** + * @return string + */ public function GetMenuId() { return $this->sMenuId; } + /** + * @return int + */ public function GetParentIndex() { return $this->iParentIndex; } + /** + * @return string + * @throws DictExceptionMissingString + */ public function GetTitle() { return Dict::S("Menu:$this->sMenuId", str_replace('_', ' ', $this->sMenuId)); } - + + /** + * @return string + * @throws DictExceptionMissingString + */ public function GetLabel() { $sRet = Dict::S("Menu:$this->sMenuId+", ""); @@ -463,7 +571,10 @@ abstract class MenuNode } return $sRet; } - + + /** + * @return int + */ public function GetIndex() { return $this->index; @@ -479,6 +590,10 @@ abstract class MenuNode } } + /** + * @param $aExtraParams + * @return string + */ public function GetHyperlink($aExtraParams) { $aExtraParams['c[menu]'] = $this->GetMenuId(); @@ -536,9 +651,19 @@ abstract class MenuNode } return true; } - + + /** + * @param WebPage $oPage + * @param array $aExtraParams + * @return mixed + */ public abstract function RenderContent(WebPage $oPage, $aExtraParams = array()); - + + /** + * @param $sHyperlink + * @param $aExtraParams + * @return string + */ protected function AddParams($sHyperlink, $aExtraParams) { if (count($aExtraParams) > 0) @@ -572,13 +697,17 @@ class MenuGroup extends MenuNode * @param string $sEnableClass Name of class of object * @param integer $iActionCode Either UR_ACTION_READ, UR_ACTION_MODIFY, UR_ACTION_DELETE, UR_ACTION_BULKREAD, UR_ACTION_BULKMODIFY or UR_ACTION_BULKDELETE * @param integer $iAllowedResults Expected "rights" for the action: either UR_ALLOWED_YES, UR_ALLOWED_NO, UR_ALLOWED_DEPENDS or a mix of them... - * @return MenuGroup + * @param string $sEnableStimulus */ public function __construct($sMenuId, $fRank, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null) { parent::__construct($sMenuId, -1 /* no parent, groups are at root level */, $fRank, $sEnableClass, $iActionCode, $iAllowedResults, $sEnableStimulus); } - + + /** + * @param WebPage $oPage + * @param array $aExtraParams + */ public function RenderContent(WebPage $oPage, $aExtraParams = array()) { assert(false); // Shall never be called, groups do not display any content @@ -591,6 +720,9 @@ class MenuGroup extends MenuNode */ class TemplateMenuNode extends MenuNode { + /** + * @var string + */ protected $sTemplateFile; /** @@ -602,23 +734,34 @@ class TemplateMenuNode extends MenuNode * @param string $sEnableClass Name of class of object * @param integer $iActionCode Either UR_ACTION_READ, UR_ACTION_MODIFY, UR_ACTION_DELETE, UR_ACTION_BULKREAD, UR_ACTION_BULKMODIFY or UR_ACTION_BULKDELETE * @param integer $iAllowedResults Expected "rights" for the action: either UR_ALLOWED_YES, UR_ALLOWED_NO, UR_ALLOWED_DEPENDS or a mix of them... - * @return MenuNode + * @param string $sEnableStimulus */ - public function __construct($sMenuId, $sTemplateFile, $iParentIndex, $fRank = 0, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null) + public function __construct($sMenuId, $sTemplateFile, $iParentIndex, $fRank = 0.0, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null) { parent::__construct($sMenuId, $iParentIndex, $fRank, $sEnableClass, $iActionCode, $iAllowedResults, $sEnableStimulus); $this->sTemplateFile = $sTemplateFile; $this->aReflectionProperties['template_file'] = $sTemplateFile; } - + + /** + * @param $aExtraParams + * @return string + */ public function GetHyperlink($aExtraParams) { if ($this->sTemplateFile == '') return ''; return parent::GetHyperlink($aExtraParams); } - + + /** + * @param WebPage $oPage + * @param array $aExtraParams + * @return mixed|void + * @throws DictExceptionMissingString + */ public function RenderContent(WebPage $oPage, $aExtraParams = array()) { + ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId()); $sTemplate = @file_get_contents($this->sTemplateFile); if ($sTemplate !== false) { @@ -639,17 +782,29 @@ class TemplateMenuNode extends MenuNode */ class OQLMenuNode extends MenuNode { + /** + * @var string + */ protected $sPageTitle; + /** + * @var string + */ protected $sOQL; + /** + * @var bool + */ protected $bSearch; + /** + * @var bool|null + */ protected $bSearchFormOpen; /** * Extra parameters to be passed to the display block to fine tune its appearence */ protected $m_aParams; - - + + /** * Create a menu item based on an OQL query and inserts it into the application's main menu * @param string $sMenuId Unique identifier of the menu (used to identify the menu for bookmarking, and for getting the labels from the dictionary) @@ -660,9 +815,10 @@ class OQLMenuNode extends MenuNode * @param string $sEnableClass Name of class of object * @param integer $iActionCode Either UR_ACTION_READ, UR_ACTION_MODIFY, UR_ACTION_DELETE, UR_ACTION_BULKREAD, UR_ACTION_BULKMODIFY or UR_ACTION_BULKDELETE * @param integer $iAllowedResults Expected "rights" for the action: either UR_ALLOWED_YES, UR_ALLOWED_NO, UR_ALLOWED_DEPENDS or a mix of them... - * @return MenuNode + * @param string $sEnableStimulus + * @param bool $bSearchFormOpen */ - public function __construct($sMenuId, $sOQL, $iParentIndex, $fRank = 0, $bSearch = false, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null, $bSearchFormOpen = null) + public function __construct($sMenuId, $sOQL, $iParentIndex, $fRank = 0.0, $bSearch = false, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null, $bSearchFormOpen = null) { parent::__construct($sMenuId, $iParentIndex, $fRank, $sEnableClass, $iActionCode, $iAllowedResults, $sEnableStimulus); $this->sPageTitle = "Menu:$sMenuId+"; @@ -695,9 +851,18 @@ class OQLMenuNode extends MenuNode $this->aReflectionProperties[$sKey] = $value; } } - + + /** + * @param WebPage $oPage + * @param array $aExtraParams + * @return mixed|void + * @throws CoreException + * @throws DictExceptionMissingString + * @throws OQLException + */ public function RenderContent(WebPage $oPage, $aExtraParams = array()) { + ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId()); OQLMenuNode::RenderOQLSearch ( $this->sOQL, @@ -711,6 +876,19 @@ class OQLMenuNode extends MenuNode ); } + /** + * @param $sOql + * @param $sTitle + * @param $sUsageId + * @param $bSearchPane + * @param $bSearchOpen + * @param WebPage $oPage + * @param array $aExtraParams + * @param bool $bEnableBreadcrumb + * @throws CoreException + * @throws DictExceptionMissingString + * @throws OQLException + */ public static function RenderOQLSearch($sOql, $sTitle, $sUsageId, $bSearchPane, $bSearchOpen, WebPage $oPage, $aExtraParams = array(), $bEnableBreadcrumb = false) { $sUsageId = utils::GetSafeId($sUsageId); @@ -746,22 +924,28 @@ class OQLMenuNode extends MenuNode */ class SearchMenuNode extends MenuNode { + /** + * @var string + */ protected $sPageTitle; + /** + * @var string + */ protected $sClass; - + /** * Create a menu item based on an OQL query and inserts it into the application's main menu * @param string $sMenuId Unique identifier of the menu (used to identify the menu for bookmarking, and for getting the labels from the dictionary) * @param string $sClass The class of objects to search for - * @param string $sPageTitle Title displayed into the page's content (will be looked-up in the dictionnary for translation) * @param integer $iParentIndex ID of the parent menu * @param float $fRank Number used to order the list, any number will do, but for a given level (i.e same parent) all menus are sorted based on this value + * @param bool $bSearch (not used) * @param string $sEnableClass Name of class of object * @param integer $iActionCode Either UR_ACTION_READ, UR_ACTION_MODIFY, UR_ACTION_DELETE, UR_ACTION_BULKREAD, UR_ACTION_BULKMODIFY or UR_ACTION_BULKDELETE * @param integer $iAllowedResults Expected "rights" for the action: either UR_ALLOWED_YES, UR_ALLOWED_NO, UR_ALLOWED_DEPENDS or a mix of them... - * @return MenuNode + * @param string $sEnableStimulus */ - public function __construct($sMenuId, $sClass, $iParentIndex, $fRank = 0, $bSearch = false, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null) + public function __construct($sMenuId, $sClass, $iParentIndex, $fRank = 0.0, $bSearch = false, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null) { parent::__construct($sMenuId, $iParentIndex, $fRank, $sEnableClass, $iActionCode, $iAllowedResults, $sEnableStimulus); $this->sPageTitle = "Menu:$sMenuId+"; @@ -769,8 +953,16 @@ class SearchMenuNode extends MenuNode $this->aReflectionProperties['class'] = $sClass; } + /** + * @param WebPage $oPage + * @param array $aExtraParams + * @return mixed|void + * @throws DictExceptionMissingString + * @throws Exception + */ public function RenderContent(WebPage $oPage, $aExtraParams = array()) { + ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId()); $oPage->SetBreadCrumbEntry("menu-".$this->sMenuId, $this->GetTitle(), '', '', utils::GetAbsoluteUrlAppRoot().'images/search.png'); $oSearch = new DBObjectSearch($this->sClass); @@ -789,8 +981,11 @@ class SearchMenuNode extends MenuNode */ class WebPageMenuNode extends MenuNode { + /** + * @var string + */ protected $sHyperlink; - + /** * Create a menu item that points to any web page (not only UI.php) * @param string $sMenuId Unique identifier of the menu (used to identify the menu for bookmarking, and for getting the labels from the dictionary) @@ -800,21 +995,29 @@ class WebPageMenuNode extends MenuNode * @param string $sEnableClass Name of class of object * @param integer $iActionCode Either UR_ACTION_READ, UR_ACTION_MODIFY, UR_ACTION_DELETE, UR_ACTION_BULKREAD, UR_ACTION_BULKMODIFY or UR_ACTION_BULKDELETE * @param integer $iAllowedResults Expected "rights" for the action: either UR_ALLOWED_YES, UR_ALLOWED_NO, UR_ALLOWED_DEPENDS or a mix of them... - * @return MenuNode + * @param string $sEnableStimulus */ - public function __construct($sMenuId, $sHyperlink, $iParentIndex, $fRank = 0, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null) + public function __construct($sMenuId, $sHyperlink, $iParentIndex, $fRank = 0.0, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null) { parent::__construct($sMenuId, $iParentIndex, $fRank, $sEnableClass, $iActionCode, $iAllowedResults, $sEnableStimulus); $this->sHyperlink = $sHyperlink; $this->aReflectionProperties['url'] = $sHyperlink; } + /** + * @param array $aExtraParams + * @return string + */ public function GetHyperlink($aExtraParams) { $aExtraParams['c[menu]'] = $this->GetMenuId(); return $this->AddParams( $this->sHyperlink, $aExtraParams); } - + + /** + * @param WebPage $oPage + * @param array $aExtraParams + */ public function RenderContent(WebPage $oPage, $aExtraParams = array()) { assert(false); // Shall never be called, the external web page will handle the display by itself @@ -829,8 +1032,11 @@ class WebPageMenuNode extends MenuNode */ class NewObjectMenuNode extends MenuNode { + /** + * @var string + */ protected $sClass; - + /** * Create a menu item that points to the URL for creating a new object, the menu will be added only if the current user has enough * rights to create such an object (or an object of a child class) @@ -838,15 +1044,22 @@ class NewObjectMenuNode extends MenuNode * @param string $sClass URL to the page to load. Use relative URL if you want to keep the application portable ! * @param integer $iParentIndex ID of the parent menu * @param float $fRank Number used to order the list, any number will do, but for a given level (i.e same parent) all menus are sorted based on this value - * @return MenuNode + * @param string $sEnableClass + * @param int|null $iActionCode + * @param int $iAllowedResults + * @param string $sEnableStimulus */ - public function __construct($sMenuId, $sClass, $iParentIndex, $fRank = 0) + public function __construct($sMenuId, $sClass, $iParentIndex, $fRank = 0.0, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null) { - parent::__construct($sMenuId, $iParentIndex, $fRank); + parent::__construct($sMenuId, $iParentIndex, $fRank, $sEnableClass, $iActionCode, $iAllowedResults, $sEnableStimulus); $this->sClass = $sClass; $this->aReflectionProperties['class'] = $sClass; } + /** + * @param string[] $aExtraParams + * @return string + */ public function GetHyperlink($aExtraParams) { $sHyperlink = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=new&class='.$this->sClass; @@ -857,6 +1070,7 @@ class NewObjectMenuNode extends MenuNode /** * Overload the check of the "enable" state of this menu to take into account * derived classes of objects + * @throws CoreException */ public function IsEnabled() { @@ -875,7 +1089,12 @@ class NewObjectMenuNode extends MenuNode } } return $bActionIsAllowed; - } + } + + /** + * @param WebPage $oPage + * @param string[] $aExtraParams + */ public function RenderContent(WebPage $oPage, $aExtraParams = array()) { assert(false); // Shall never be called, the external web page will handle the display by itself @@ -888,32 +1107,44 @@ require_once(APPROOT.'application/dashboard.class.inc.php'); */ class DashboardMenuNode extends MenuNode { + /** + * @var string + */ protected $sDashboardFile; - + /** * Create a menu item based on a custom template and inserts it into the application's main menu * @param string $sMenuId Unique identifier of the menu (used to identify the menu for bookmarking, and for getting the labels from the dictionary) - * @param string $sTemplateFile Path (or URL) to the file that will be used as a template for displaying the page's content + * @param string $sDashboardFile * @param integer $iParentIndex ID of the parent menu * @param float $fRank Number used to order the list, any number will do, but for a given level (i.e same parent) all menus are sorted based on this value * @param string $sEnableClass Name of class of object * @param integer $iActionCode Either UR_ACTION_READ, UR_ACTION_MODIFY, UR_ACTION_DELETE, UR_ACTION_BULKREAD, UR_ACTION_BULKMODIFY or UR_ACTION_BULKDELETE - * @param integer $iAllowedResults Expected "rights" for the action: either UR_ALLOWED_YES, UR_ALLOWED_NO, UR_ALLOWED_DEPENDS or a mix of them... - * @return MenuNode + * @param integer $iAllowedResults Expected "rights" for the action: either UR_ALLOWED_YES, UR_ALLOWED_NO, UR_ALLOWED_DEPENDS + * @param string $sEnableStimulus */ - public function __construct($sMenuId, $sDashboardFile, $iParentIndex, $fRank = 0, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null) + public function __construct($sMenuId, $sDashboardFile, $iParentIndex, $fRank = 0.0, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null) { parent::__construct($sMenuId, $iParentIndex, $fRank, $sEnableClass, $iActionCode, $iAllowedResults, $sEnableStimulus); $this->sDashboardFile = $sDashboardFile; $this->aReflectionProperties['definition_file'] = $sDashboardFile; } - + + /** + * @param string[] $aExtraParams + * @return string + */ public function GetHyperlink($aExtraParams) { if ($this->sDashboardFile == '') return ''; return parent::GetHyperlink($aExtraParams); } + /** + * @return null|RuntimeDashboard + * @throws CoreException + * @throws Exception + */ public function GetDashboard() { $sDashboardDefinition = @file_get_contents($this->sDashboardFile); @@ -945,8 +1176,15 @@ class DashboardMenuNode extends MenuNode return $oDashboard; } + /** + * @param WebPage $oPage + * @param string[] $aExtraParams + * @throws CoreException + * @throws Exception + */ public function RenderContent(WebPage $oPage, $aExtraParams = array()) { + ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId()); $oDashboard = $this->GetDashboard(); if ($oDashboard != null) { @@ -1020,7 +1258,12 @@ EOF $oPage->p("Error: failed to load dashboard file: '{$this->sDashboardFile}'"); } } - + + /** + * @param WebPage $oPage + * @throws CoreException + * @throws Exception + */ public function RenderEditor(WebPage $oPage) { $oDashboard = $this->GetDashboard(); @@ -1033,7 +1276,11 @@ EOF $oPage->p("Error: failed to load dashboard file: '{$this->sDashboardFile}'"); } } - + + /** + * @param $oDashlet + * @throws Exception + */ public function AddDashlet($oDashlet) { $oDashboard = $this->GetDashboard(); @@ -1055,15 +1302,28 @@ EOF */ class ShortcutContainerMenuNode extends MenuNode { + /** + * @param string[] $aExtraParams + * @return string + */ public function GetHyperlink($aExtraParams) { return ''; } + /** + * @param WebPage $oPage + * @param string[] $aExtraParams + * @return mixed|void + */ public function RenderContent(WebPage $oPage, $aExtraParams = array()) { } + /** + * @throws CoreException + * @throws Exception + */ public function PopulateChildMenus() { // Load user shortcuts in DB @@ -1075,7 +1335,7 @@ class ShortcutContainerMenuNode extends MenuNode while ($oShortcut = $oBMSet->Fetch()) { $sName = $this->GetMenuId().'_'.$oShortcut->GetKey(); - $oShortcutMenu = new ShortcutMenuNode($sName, $oShortcut, $this->GetIndex(), $fRank++); + new ShortcutMenuNode($sName, $oShortcut, $this->GetIndex(), $fRank++); } // Complete the tree @@ -1091,8 +1351,11 @@ require_once(APPROOT.'application/shortcut.class.inc.php'); */ class ShortcutMenuNode extends MenuNode { + /** + * @var Shortcut + */ protected $oShortcut; - + /** * Create a menu item based on a custom template and inserts it into the application's main menu * @param string $sMenuId Unique identifier of the menu (used to identify the menu for bookmarking, and for getting the labels from the dictionary) @@ -1102,15 +1365,20 @@ class ShortcutMenuNode extends MenuNode * @param string $sEnableClass Name of class of object * @param integer $iActionCode Either UR_ACTION_READ, UR_ACTION_MODIFY, UR_ACTION_DELETE, UR_ACTION_BULKREAD, UR_ACTION_BULKMODIFY or UR_ACTION_BULKDELETE * @param integer $iAllowedResults Expected "rights" for the action: either UR_ALLOWED_YES, UR_ALLOWED_NO, UR_ALLOWED_DEPENDS or a mix of them... - * @return MenuNode + * @param string $sEnableStimulus */ - public function __construct($sMenuId, $oShortcut, $iParentIndex, $fRank = 0, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null) + public function __construct($sMenuId, $oShortcut, $iParentIndex, $fRank = 0.0, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null) { parent::__construct($sMenuId, $iParentIndex, $fRank, $sEnableClass, $iActionCode, $iAllowedResults, $sEnableStimulus); $this->oShortcut = $oShortcut; $this->aReflectionProperties['shortcut'] = $oShortcut->GetKey(); } - + + /** + * @param string[] $aExtraParams + * @return string + * @throws CoreException + */ public function GetHyperlink($aExtraParams) { $sContext = $this->oShortcut->Get('context'); @@ -1126,16 +1394,31 @@ class ShortcutMenuNode extends MenuNode return parent::GetHyperlink($aExtraParams); } + /** + * @param WebPage $oPage + * @param string[] $aExtraParams + * @return mixed|void + * @throws DictExceptionMissingString + */ public function RenderContent(WebPage $oPage, $aExtraParams = array()) { + ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId()); $this->oShortcut->RenderContent($oPage, $aExtraParams); } + /** + * @return string + * @throws CoreException + */ public function GetTitle() { return $this->oShortcut->Get('name'); } - + + /** + * @return string + * @throws CoreException + */ public function GetLabel() { return $this->oShortcut->Get('name'); diff --git a/application/query.class.inc.php b/application/query.class.inc.php index f856b59e6..d19a2279f 100644 --- a/application/query.class.inc.php +++ b/application/query.class.inc.php @@ -32,7 +32,7 @@ abstract class Query extends cmdbAbstractObject { $aParams = array ( - "category" => "core/cmdb,view_in_gui,application", + "category" => "core/cmdb,view_in_gui,application,grant_by_profile", "key_type" => "autoincrement", "name_attcode" => "name", "state_attcode" => "", @@ -64,7 +64,7 @@ class QueryOQL extends Query { $aParams = array ( - "category" => "core/cmdb,view_in_gui,application", + "category" => "core/cmdb,view_in_gui,application,grant_by_profile", "key_type" => "autoincrement", "name_attcode" => "name", "state_attcode" => "", diff --git a/core/action.class.inc.php b/core/action.class.inc.php index df5367985..e6317819f 100644 --- a/core/action.class.inc.php +++ b/core/action.class.inc.php @@ -39,7 +39,7 @@ abstract class Action extends cmdbAbstractObject { $aParams = array ( - "category" => "core/cmdb", + "category" => "grant_by_profile,core/cmdb", "key_type" => "autoincrement", "name_attcode" => "name", "state_attcode" => "", @@ -103,7 +103,7 @@ abstract class ActionNotification extends Action { $aParams = array ( - "category" => "core/cmdb", + "category" => "grant_by_profile,core/cmdb", "key_type" => "autoincrement", "name_attcode" => "name", "state_attcode" => "", @@ -136,7 +136,7 @@ class ActionEmail extends ActionNotification { $aParams = array ( - "category" => "core/cmdb,application", + "category" => "grant_by_profile,core/cmdb,application", "key_type" => "autoincrement", "name_attcode" => "name", "state_attcode" => "", diff --git a/core/trigger.class.inc.php b/core/trigger.class.inc.php index eb5b5dba1..512de48ce 100644 --- a/core/trigger.class.inc.php +++ b/core/trigger.class.inc.php @@ -38,7 +38,7 @@ abstract class Trigger extends cmdbAbstractObject { $aParams = array ( - "category" => "core/cmdb", + "category" => "grant_by_profile,core/cmdb", "key_type" => "autoincrement", "name_attcode" => "description", "state_attcode" => "", @@ -97,7 +97,7 @@ abstract class TriggerOnObject extends Trigger { $aParams = array ( - "category" => "core/cmdb", + "category" => "grant_by_profile,core/cmdb", "key_type" => "autoincrement", "name_attcode" => "description", "state_attcode" => "", @@ -194,7 +194,7 @@ class TriggerOnPortalUpdate extends TriggerOnObject { $aParams = array ( - "category" => "core/cmdb,application", + "category" => "grant_by_profile,core/cmdb,application", "key_type" => "autoincrement", "name_attcode" => "description", "state_attcode" => "", @@ -220,7 +220,7 @@ abstract class TriggerOnStateChange extends TriggerOnObject { $aParams = array ( - "category" => "core/cmdb", + "category" => "grant_by_profile,core/cmdb", "key_type" => "autoincrement", "name_attcode" => "description", "state_attcode" => "", @@ -249,7 +249,7 @@ class TriggerOnStateEnter extends TriggerOnStateChange { $aParams = array ( - "category" => "core/cmdb,application", + "category" => "grant_by_profile,core/cmdb,application", "key_type" => "autoincrement", "name_attcode" => "description", "state_attcode" => "", @@ -277,7 +277,7 @@ class TriggerOnStateLeave extends TriggerOnStateChange { $aParams = array ( - "category" => "core/cmdb,application", + "category" => "grant_by_profile,core/cmdb,application", "key_type" => "autoincrement", "name_attcode" => "description", "state_attcode" => "", @@ -305,7 +305,7 @@ class TriggerOnObjectCreate extends TriggerOnObject { $aParams = array ( - "category" => "core/cmdb,application", + "category" => "grant_by_profile,core/cmdb,application", "key_type" => "autoincrement", "name_attcode" => "description", "state_attcode" => "", @@ -333,7 +333,7 @@ class lnkTriggerAction extends cmdbAbstractObject { $aParams = array ( - "category" => "core/cmdb,application", + "category" => "grant_by_profile,core/cmdb,application", "key_type" => "autoincrement", "name_attcode" => "", "state_attcode" => "", @@ -366,7 +366,7 @@ class TriggerOnThresholdReached extends TriggerOnObject { $aParams = array ( - "category" => "core/cmdb,application", + "category" => "grant_by_profile,core/cmdb,application", "key_type" => "autoincrement", "name_attcode" => "description", "state_attcode" => "", diff --git a/core/userrights.class.inc.php b/core/userrights.class.inc.php index 8831eabd0..c46bb898c 100644 --- a/core/userrights.class.inc.php +++ b/core/userrights.class.inc.php @@ -254,8 +254,8 @@ abstract class User extends cmdbAbstractObject return $this->oContactObject; } - /* - * Overload the standard behavior + /** + * Overload the standard behavior. */ public function DoCheckToWrite() { @@ -286,6 +286,12 @@ abstract class User extends cmdbAbstractObject { $this->m_aCheckIssues[] = Dict::Format('Class:User/Error:AtLeastOneProfileIsNeeded'); } + // Only administrators can manage administrators + if (UserRights::IsAdministrator($this) && !UserRights::IsAdministrator()) + { + + $this->m_aCheckIssues[] = Dict::Format('UI:Login:Error:AccessRestricted'); + } } function GetGrantAsHtml($sClass, $iAction) diff --git a/datamodels/2.x/itop-backup/ajax.backup.php b/datamodels/2.x/itop-backup/ajax.backup.php index 62e797c00..d2067371d 100644 --- a/datamodels/2.x/itop-backup/ajax.backup.php +++ b/datamodels/2.x/itop-backup/ajax.backup.php @@ -40,8 +40,8 @@ try case 'backup': require_once(APPROOT.'/application/startup.inc.php'); require_once(APPROOT.'/application/loginwebpage.class.inc.php'); - LoginWebPage::DoLogin(true); // Check user rights and prompt if needed (must be admin) - + LoginWebPage::DoLogin(); // Check user rights and prompt if needed + ApplicationMenu::CheckMenuIdEnabled('BackupStatus'); $oPage = new ajax_page(""); $oPage->no_cache(); $oPage->SetContentType('text/html'); @@ -70,7 +70,8 @@ try case 'restore_get_token': require_once(APPROOT.'/application/startup.inc.php'); require_once(APPROOT.'/application/loginwebpage.class.inc.php'); - LoginWebPage::DoLogin(true); // Check user rights and prompt if needed (must be admin) + LoginWebPage::DoLogin(); // Check user rights and prompt if needed + ApplicationMenu::CheckMenuIdEnabled('BackupStatus'); $oPage = new ajax_page(""); $oPage->no_cache(); @@ -166,7 +167,8 @@ EOF case 'download': require_once(APPROOT.'/application/startup.inc.php'); require_once(APPROOT.'/application/loginwebpage.class.inc.php'); - LoginWebPage::DoLogin(true); // Check user rights and prompt if needed (must be admin) + LoginWebPage::DoLogin(); // Check user rights and prompt if needed + ApplicationMenu::CheckMenuIdEnabled('BackupStatus'); if (utils::GetConfig()->Get('demo_mode')) { diff --git a/datamodels/2.x/itop-backup/datamodel.itop-backup.xml b/datamodels/2.x/itop-backup/datamodel.itop-backup.xml new file mode 100644 index 000000000..2a89ca50a --- /dev/null +++ b/datamodels/2.x/itop-backup/datamodel.itop-backup.xml @@ -0,0 +1,12 @@ + + + + + 15 + AdminTools + status.php + ResourceAdminMenu + UR_ACTION_MODIFY + + + diff --git a/datamodels/2.x/itop-backup/main.itop-backup.php b/datamodels/2.x/itop-backup/main.itop-backup.php index f0de61991..44029672c 100644 --- a/datamodels/2.x/itop-backup/main.itop-backup.php +++ b/datamodels/2.x/itop-backup/main.itop-backup.php @@ -75,9 +75,11 @@ class DBBackupScheduled extends DBBackup } /** - * List and order by date the backups in the given directory + * List and order by date the backups in the given directory * Note: the algorithm is currently based on the file modification date... because there is no "creation date" in general - */ + * @param string $sBackupDir + * @return array + */ public function ListFiles($sBackupDir) { $aFiles = array(); @@ -130,6 +132,11 @@ class BackupExec implements iScheduledProcess } } + /** + * @param int $iUnixTimeLimit + * @return string + * @throws Exception + */ public function Process($iUnixTimeLimit) { $oMutex = new iTopMutex('backup.'.utils::GetCurrentEnvironment()); @@ -182,10 +189,11 @@ class BackupExec implements iScheduledProcess return "Created the backup: $sBackupFile"; } - /* - Interpret current setting for the week days - @returns array of int (monday = 1) - */ + /** + * Interpret current setting for the week days + * @returns array of int (monday = 1) + * @throws Exception + */ public function InterpretWeekDays() { static $aWEEKDAYTON = array('monday' => 1, 'tuesday' => 2, 'wednesday' => 3, 'thursday' => 4, 'friday' => 5, 'saturday' => 6, 'sunday' => 7); @@ -216,10 +224,10 @@ class BackupExec implements iScheduledProcess return $aDays; } - /* - Gives the exact time at which the process must be run next time - @returns DateTime - */ + /** Gives the exact time at which the process must be run next time + * @return DateTime + * @throws Exception + */ public function GetNextOccurrence() { $bEnabled = MetaModel::GetConfig()->GetModuleSetting('itop-backup', 'enabled', true); @@ -279,15 +287,3 @@ class BackupExec implements iScheduledProcess return $oRet; } } - -class ItopBackup extends ModuleHandlerAPI -{ - public static function OnMenuCreation() - { - if (UserRights::IsAdministrator()) - { - $oAdminMenu = new MenuGroup('AdminTools', 80 /* fRank */); - new WebPageMenuNode('BackupStatus', utils::GetAbsoluteUrlModulePage('itop-backup', 'status.php'), $oAdminMenu->GetIndex(), 15 /* fRank */); - } - } -} diff --git a/datamodels/2.x/itop-backup/module.itop-backup.php b/datamodels/2.x/itop-backup/module.itop-backup.php index 52960d9c1..cd2b6bf49 100644 --- a/datamodels/2.x/itop-backup/module.itop-backup.php +++ b/datamodels/2.x/itop-backup/module.itop-backup.php @@ -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.4.0', + 'itop-backup/2.4.1', array( // Identification // @@ -21,7 +21,7 @@ SetupWebPage::AddModule( // 'datamodel' => array( 'main.itop-backup.php', - //'model.itop-backup.php', + 'model.itop-backup.php', ), 'webservice' => array( //'webservices.itop-backup.php', diff --git a/datamodels/2.x/itop-backup/status.php b/datamodels/2.x/itop-backup/status.php index dae1687fc..44493467c 100644 --- a/datamodels/2.x/itop-backup/status.php +++ b/datamodels/2.x/itop-backup/status.php @@ -37,17 +37,19 @@ require_once(APPROOT.'application/loginwebpage.class.inc.php'); ///////////////////////////////////////////////////////////////////// // Main program // -LoginWebPage::DoLogin(true); // Check user rights and prompt if needed (must be admin) +LoginWebPage::DoLogin(); // Check user rights and prompt if needed +ApplicationMenu::CheckMenuIdEnabled('BackupStatus'); //$sOperation = utils::ReadParam('operation', 'menu'); //$oAppContext = new ApplicationContext(); -$oP = new iTopWebPage(Dict::S('bkp-status-title')); -$oP->set_base(utils::GetAbsoluteUrlAppRoot().'pages/'); try { + $oP = new iTopWebPage(Dict::S('bkp-status-title')); + $oP->set_base(utils::GetAbsoluteUrlAppRoot().'pages/'); + $oP->add("

    ".Dict::S('bkp-status-title')."

    "); if (MetaModel::GetConfig()->Get('demo_mode')) @@ -93,7 +95,7 @@ try } foreach($aOutput as $sLine) { - //echo 'Info - mysqldump -V said: '.$sLine; + IssueLog::Info("$sCommand said: $sLine"); } $oP->p($sMySqlDump); @@ -394,6 +396,7 @@ EOF } catch(Exception $e) { + $oP = new iTopWebPage(Dict::S('bkp-status-title')); $oP->p(''.$e->getMessage().''); } diff --git a/datamodels/2.x/itop-config/config.php b/datamodels/2.x/itop-config/config.php index 8db06c29c..57efd01aa 100644 --- a/datamodels/2.x/itop-config/config.php +++ b/datamodels/2.x/itop-config/config.php @@ -24,12 +24,9 @@ * @license http://opensource.org/licenses/AGPL-3.0 */ -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'); - require_once(APPROOT.'application/loginwebpage.class.inc.php'); @@ -81,7 +78,8 @@ function TestConfig($sContents, $oP) ///////////////////////////////////////////////////////////////////// // Main program // -LoginWebPage::DoLogin(true); // Check user rights and prompt if needed (must be admin) +LoginWebPage::DoLogin(); // Check user rights and prompt if needed +ApplicationMenu::CheckMenuIdEnabled('ConfigEditor'); //$sOperation = utils::ReadParam('operation', 'menu'); //$oAppContext = new ApplicationContext(); diff --git a/datamodels/2.x/itop-config/datamodel.itop-config.xml b/datamodels/2.x/itop-config/datamodel.itop-config.xml new file mode 100644 index 000000000..3b3224180 --- /dev/null +++ b/datamodels/2.x/itop-config/datamodel.itop-config.xml @@ -0,0 +1,12 @@ + + + + + 50 + AdminTools + config.php + ResourceAdminMenu + UR_ACTION_MODIFY + + + diff --git a/datamodels/2.x/itop-config/main.itop-config.php b/datamodels/2.x/itop-config/main.itop-config.php deleted file mode 100644 index 32fc6cec1..000000000 --- a/datamodels/2.x/itop-config/main.itop-config.php +++ /dev/null @@ -1,30 +0,0 @@ -GetIndex(), 18 /* fRank */); - } - } -} diff --git a/datamodels/2.x/itop-config/module.itop-config.php b/datamodels/2.x/itop-config/module.itop-config.php index cab7d2227..b148b0aa0 100644 --- a/datamodels/2.x/itop-config/module.itop-config.php +++ b/datamodels/2.x/itop-config/module.itop-config.php @@ -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.4.0', + 'itop-config/2.4.1', array( // Identification // @@ -12,31 +12,22 @@ SetupWebPage::AddModule( // Setup // - 'dependencies' => array( - ), + 'dependencies' => array(), 'mandatory' => true, 'visible' => false, // Components // 'datamodel' => array( - 'main.itop-config.php', - //'model.itop-config.php', - ), - 'webservice' => array( - //'webservices.itop-config.php', + 'model.itop-config.php', ), + 'webservice' => array(), 'dictionary' => array( 'en.dict.itop-config.php', 'fr.dict.itop-config.php', - //'de.dict.itop-config.php', - ), - 'data.struct' => array( - //'data.struct.itop-config.xml', - ), - 'data.sample' => array( - //'data.sample.itop-config.xml', ), + 'data.struct' => array(), + 'data.sample' => array(), // Documentation // @@ -45,7 +36,6 @@ SetupWebPage::AddModule( // Default settings // - 'settings' => array( - ), + 'settings' => array(), ) ); diff --git a/datamodels/2.x/itop-profiles-itil/datamodel.itop-profiles-itil.xml b/datamodels/2.x/itop-profiles-itil/datamodel.itop-profiles-itil.xml index 1721f1282..8b99a67cf 100755 --- a/datamodels/2.x/itop-profiles-itil/datamodel.itop-profiles-itil.xml +++ b/datamodels/2.x/itop-profiles-itil/datamodel.itop-profiles-itil.xml @@ -103,6 +103,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/datamodels/2.x/itop-welcome-itil/datamodel.itop-welcome-itil.xml b/datamodels/2.x/itop-welcome-itil/datamodel.itop-welcome-itil.xml index c06ad9417..4261e2e40 100644 --- a/datamodels/2.x/itop-welcome-itil/datamodel.itop-welcome-itil.xml +++ b/datamodels/2.x/itop-welcome-itil/datamodel.itop-welcome-itil.xml @@ -1,5 +1,36 @@ - + + + + cmdbAbstractObject + + /* Resource access control abstraction. Can be herited by abstract resource access control classes. Generaly controlled using UR_ACTION_MODIFY access right. */ + true + + + + + + AbstractResource + + /* AdminTools menu access control. */ + true + grant_by_profile + + + + + + AbstractResource + + /* RunQueriesMenu menu access control. */ + true + grant_by_profile + + + + + 10 @@ -56,5 +87,81 @@ 20 WelcomeMenu + + 1 + AdminTools + + 1 + 1 + User + UR_ACTION_MODIFY + + + 2 + AdminTools + + + URP_Profiles + UR_ACTION_MODIFY + + + 3 + AdminTools + $pages/notifications.php + Trigger + UR_ACTION_MODIFY + + + 4 + AdminTools + + + AuditCategory + UR_ACTION_MODIFY + + + 8 + AdminTools + $pages/run_query.php + ResourceRunQueriesMenu + UR_ACTION_MODIFY + + + 8.5 + AdminTools + + 1 + Query + UR_ACTION_MODIFY + + + 9 + AdminTools + $webservices/export-v2.php?interactive=1 + ResourceAdminMenu + UR_ACTION_MODIFY + + + 10 + AdminTools + $pages/schema.php + ResourceAdminMenu + UR_ACTION_MODIFY + + + 11 + AdminTools + $pages/UniversalSearch.php + ResourceAdminMenu + UR_ACTION_MODIFY + + + 12 + AdminTools + + 1 + SynchroDataSource + UR_ACTION_MODIFY + diff --git a/datamodels/2.x/itop-welcome-itil/main.itop-welcome-itil.php b/datamodels/2.x/itop-welcome-itil/main.itop-welcome-itil.php index 388458157..3d5a6159a 100755 --- a/datamodels/2.x/itop-welcome-itil/main.itop-welcome-itil.php +++ b/datamodels/2.x/itop-welcome-itil/main.itop-welcome-itil.php @@ -16,8 +16,7 @@ // You should have received a copy of the GNU Affero General Public License // along with iTop. If not, see - -// Add the standard menus +// Add the standard menus (done in XML) /* * +--------------------+ * | Welcome | @@ -28,7 +27,7 @@ * +--------------------+ * CSV Import * +--------------------+ - * | Admin Tools | << Only present if the user is an admin + * | Admin Tools | * +--------------------+ * User Accounts * Profiles @@ -39,29 +38,6 @@ * Universal Search */ - -class ItopWelcome extends ModuleHandlerAPI -{ - public static function OnMenuCreation() - { - // Add the admin menus - if (UserRights::IsAdministrator()) - { - $oAdminMenu = new MenuGroup('AdminTools', 80 /* fRank */); - new OQLMenuNode('UserAccountsMenu', 'SELECT User', $oAdminMenu->GetIndex(), 1 /* fRank */,true); - new OQLMenuNode('ProfilesMenu', 'SELECT URP_Profiles', $oAdminMenu->GetIndex(), 2 /* fRank */); - new WebPageMenuNode('NotificationsMenu', utils::GetAbsoluteUrlAppRoot().'pages/notifications.php', $oAdminMenu->GetIndex(), 3 /* fRank */); - new OQLMenuNode('AuditCategories', 'SELECT AuditCategory', $oAdminMenu->GetIndex(), 4 /* fRank */); - new WebPageMenuNode('RunQueriesMenu', utils::GetAbsoluteUrlAppRoot().'pages/run_query.php', $oAdminMenu->GetIndex(), 8 /* fRank */); - new OQLMenuNode('QueryMenu', 'SELECT Query', $oAdminMenu->GetIndex(), 8.5 /* fRank */, true); - new WebPageMenuNode('ExportMenu', utils::GetAbsoluteUrlAppRoot().'webservices/export-v2.php?interactive=1', $oAdminMenu->GetIndex(), 9 /* fRank */); - new WebPageMenuNode('DataModelMenu', utils::GetAbsoluteUrlAppRoot().'pages/schema.php', $oAdminMenu->GetIndex(), 10 /* fRank */); - new WebPageMenuNode('UniversalSearchMenu', utils::GetAbsoluteUrlAppRoot().'pages/UniversalSearch.php', $oAdminMenu->GetIndex(), 11 /* fRank */); - new OQLMenuNode('DataSources', 'SELECT SynchroDataSource', $oAdminMenu->GetIndex(), 12 /* fRank */, true); - } - } -} - /** * Direct end-users to the standard Portal application */ diff --git a/pages/UniversalSearch.php b/pages/UniversalSearch.php index b092d96f2..8ca74edb6 100644 --- a/pages/UniversalSearch.php +++ b/pages/UniversalSearch.php @@ -32,7 +32,8 @@ require_once(APPROOT.'/application/applicationcontext.class.inc.php'); require_once(APPROOT.'/application/startup.inc.php'); require_once(APPROOT.'/application/loginwebpage.class.inc.php'); -LoginWebPage::DoLogin(true); // Check user rights and prompt if needed (must be admin) +LoginWebPage::DoLogin(); // Check user rights and prompt if needed +ApplicationMenu::CheckMenuIdEnabled('UniversalSearchMenu'); $oAppContext = new ApplicationContext(); diff --git a/pages/notifications.php b/pages/notifications.php index c77a6f82f..22468f25f 100644 --- a/pages/notifications.php +++ b/pages/notifications.php @@ -31,9 +31,8 @@ require_once(APPROOT.'/application/itopwebpage.class.inc.php'); require_once(APPROOT.'/application/startup.inc.php'); require_once(APPROOT.'/application/loginwebpage.class.inc.php'); -LoginWebPage::DoLogin(true); // Check user rights and prompt if needed (must be admin) - - +LoginWebPage::DoLogin(); // Check user rights and prompt if needed +ApplicationMenu::CheckMenuIdEnabled("NotificationsMenu"); // Main program // diff --git a/pages/run_query.php b/pages/run_query.php index e1ab03b8a..188272c76 100644 --- a/pages/run_query.php +++ b/pages/run_query.php @@ -27,11 +27,11 @@ 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'); - require_once(APPROOT.'/application/loginwebpage.class.inc.php'); -LoginWebPage::DoLogin(true); // Check user rights and prompt if needed (must be admin) + +LoginWebPage::DoLogin(); // Check user rights and prompt if needed +ApplicationMenu::CheckMenuIdEnabled('RunQueriesMenu'); function ShowExamples($oP, $sExpression) { diff --git a/pages/schema.php b/pages/schema.php index adee4e115..ea8ee8a34 100644 --- a/pages/schema.php +++ b/pages/schema.php @@ -31,8 +31,8 @@ require_once(APPROOT.'/application/itopwebpage.class.inc.php'); require_once(APPROOT.'/application/startup.inc.php'); require_once(APPROOT.'/application/loginwebpage.class.inc.php'); -LoginWebPage::DoLogin(true); // Check user rights and prompt if needed (must be admin) - +LoginWebPage::DoLogin(); // Check user rights and prompt if needed +ApplicationMenu::CheckMenuIdEnabled('DataModelMenu'); /** * Helper for this page -> link to a class diff --git a/setup/compiler.class.inc.php b/setup/compiler.class.inc.php index c8fb54121..53e54986c 100644 --- a/setup/compiler.class.inc.php +++ b/setup/compiler.class.inc.php @@ -740,7 +740,7 @@ EOF // Relative to the module if ($bIsUrl) { - $sPHP = "utils::GetAbsoluteUrlAppRoot().".self::QuoteForPHP($sModuleRelativeDir.''.$sPath); + $sPHP = "utils::GetAbsoluteUrlModulePage('$sModuleRelativeDir', ".self::QuoteForPHP($sPath).")"; } else { @@ -1817,12 +1817,32 @@ EOF; } $fRank = (float) $oMenu->GetChildText('rank'); + $sEnablePermission = 'UR_ALLOWED_YES'; + if ($sEnableClass = $oMenu->GetChildText('enable_class')) + { + $sEnableAction = $oMenu->GetChildText('enable_action', 'UR_ACTION_MODIFY'); + $sEnablePermission = $oMenu->GetChildText('enable_permission', 'UR_ALLOWED_YES'); + $sEnableStimulus = $oMenu->GetChildText('enable_stimulus'); + if ($sEnableStimulus != null) + { + $sOptionalEnableParams = ", '$sEnableClass', $sEnableAction, $sEnablePermission, '$sEnableStimulus'"; + } + else + { + $sOptionalEnableParams = ", '$sEnableClass', $sEnableAction, $sEnablePermission, null"; + } + } + else + { + $sOptionalEnableParams = ", null, UR_ACTION_MODIFY, UR_ALLOWED_YES, null"; + } + switch($sMenuClass) { case 'WebPageMenuNode': $sUrl = $oMenu->GetChildText('url'); $sUrlSpec = $this->PathToPHP($sUrl, $sModuleRelativeDir, true /* Url */); - $sNewMenu = "new WebPageMenuNode('$sMenuId', $sUrlSpec, $sParentSpec, $fRank);"; + $sNewMenu = "new WebPageMenuNode('$sMenuId', $sUrlSpec, $sParentSpec, $fRank {$sOptionalEnableParams});"; break; case 'DashboardMenuNode': @@ -1855,11 +1875,11 @@ EOF; } $oXMLDoc->save($sTempTargetDir.'/'.$sModuleRelativeDir.'/'.$sFileName); } - $sNewMenu = "new DashboardMenuNode('$sMenuId', $sTemplateSpec, $sParentSpec, $fRank);"; + $sNewMenu = "new DashboardMenuNode('$sMenuId', $sTemplateSpec, $sParentSpec, $fRank {$sOptionalEnableParams});"; break; case 'ShortcutContainerMenuNode': - $sNewMenu = "new ShortcutContainerMenuNode('$sMenuId', $sParentSpec, $fRank);"; + $sNewMenu = "new ShortcutContainerMenuNode('$sMenuId', $sParentSpec, $fRank {$sOptionalEnableParams});"; break; case 'OQLMenuNode': @@ -1879,64 +1899,28 @@ EOF; default: $sSearchFormOpen = 'null'; // Actual open/close status depend on the config } - $sSearchFormOpen = ($oMenu->GetChildText('search_form_open') == '') ? 'null' : 'false'; - $sNewMenu = "new OQLMenuNode('$sMenuId', $sOQL, $sParentSpec, $fRank, $bSearch, $sSearchFormOpen);"; + $sNewMenu = "new OQLMenuNode('$sMenuId', $sOQL, $sParentSpec, $fRank, $bSearch {$sOptionalEnableParams}, $sSearchFormOpen);"; break; case 'NewObjectMenuNode': $sClass = $oMenu->GetChildText('class'); - $sNewMenu = "new NewObjectMenuNode('$sMenuId', '$sClass', $sParentSpec, $fRank);"; + $sNewMenu = "new NewObjectMenuNode('$sMenuId', '$sClass', $sParentSpec, $fRank {$sOptionalEnableParams});"; break; case 'SearchMenuNode': $sClass = $oMenu->GetChildText('class'); - $sNewMenu = "new SearchMenuNode('$sMenuId', '$sClass', $sParentSpec, $fRank);"; + $sNewMenu = "new SearchMenuNode('$sMenuId', '$sClass', $sParentSpec, $fRank, null {$sOptionalEnableParams});"; break; case 'TemplateMenuNode': $sTemplateFile = $oMenu->GetChildText('template_file'); $sTemplateSpec = $this->PathToPHP($sTemplateFile, $sModuleRelativeDir); - - if ($sEnableClass = $oMenu->GetChildText('enable_class')) - { - $sEnableAction = $oMenu->GetChildText('enable_action', 'null'); - $sEnablePermission = $oMenu->GetChildText('enable_permission', 'UR_ALLOWED_YES'); - $sEnableStimulus = $oMenu->GetChildText('enable_stimulus'); - if ($sEnableStimulus != null) - { - $sNewMenu = "new TemplateMenuNode('$sMenuId', $sTemplateSpec, $sParentSpec, $fRank, '$sEnableClass', $sEnableAction, $sEnablePermission, '$sEnableStimulus');"; - } - else - { - $sNewMenu = "new TemplateMenuNode('$sMenuId', $sTemplateSpec, $sParentSpec, $fRank, '$sEnableClass', $sEnableAction, $sEnablePermission);"; - } - } - else - { - $sNewMenu = "new TemplateMenuNode('$sMenuId', $sTemplateSpec, $sParentSpec, $fRank);"; - } + $sNewMenu = "new TemplateMenuNode('$sMenuId', $sTemplateSpec, $sParentSpec, $fRank {$sOptionalEnableParams});"; break; case 'MenuGroup': default: - if ($sEnableClass = $oMenu->GetChildText('enable_class')) - { - $sEnableAction = $oMenu->GetChildText('enable_action', 'null'); - $sEnablePermission = $oMenu->GetChildText('enable_permission', 'UR_ALLOWED_YES'); - $sEnableStimulus = $oMenu->GetChildText('enable_stimulus'); - if ($sEnableStimulus != null) - { - $sNewMenu = "new $sMenuClass('$sMenuId', $fRank, '$sEnableClass', $sEnableAction, $sEnablePermission, '$sEnableStimulus');"; - } - else - { - $sNewMenu = "new $sMenuClass('$sMenuId', $fRank, '$sEnableClass', $sEnableAction, $sEnablePermission);"; - } - } - else - { - $sNewMenu = "new $sMenuClass('$sMenuId', $fRank);"; - } + $sNewMenu = "new $sMenuClass('$sMenuId', $fRank {$sOptionalEnableParams});"; } $aPHPMenu = array("\$__comp_menus__['$sMenuId'] = $sNewMenu"); diff --git a/setup/itopdesignformat.class.inc.php b/setup/itopdesignformat.class.inc.php index dc798f44c..089b1657b 100644 --- a/setup/itopdesignformat.class.inc.php +++ b/setup/itopdesignformat.class.inc.php @@ -35,7 +35,7 @@ * } */ -define('ITOP_DESIGN_LATEST_VERSION', '1.4'); // iTop >= 2.4.0 +define('ITOP_DESIGN_LATEST_VERSION', '1.5'); // iTop >= 2.5.0 class iTopDesignFormat { @@ -67,6 +67,12 @@ class iTopDesignFormat '1.4' => array( 'previous' => '1.3', 'go_to_previous' => 'From14To13', + 'next' => '1.5', + 'go_to_next' => 'From14To15', + ), + '1.5' => array( + 'previous' => '1.4', + 'go_to_previous' => 'From15To14', 'next' => null, 'go_to_next' => null, ), @@ -172,8 +178,10 @@ class iTopDesignFormat } /** - * An alternative to getNodePath, that gives the id of nodes instead of the position within the children - */ + * An alternative to getNodePath, that gives the id of nodes instead of the position within the children + * @param $oNode + * @return string + */ public static function GetItopNodePath($oNode) { if ($oNode instanceof DOMDocument) return ''; @@ -245,7 +253,6 @@ class iTopDesignFormat * @param string $sFrom The source format version * @param string $sTo The desired format version * @param object $oFactory Full data model (not yet used, aimed at allowing conversion that could not be performed without knowing the whole data model) - * @return bool True on success */ protected function DoConvert($sFrom, $sTo, $oFactory = null) { @@ -299,6 +306,7 @@ class iTopDesignFormat /** * Upgrade the format from version 1.0 to 1.1 + * @param $oFactory * @return void (Errors are logged) */ protected function From10To11($oFactory) @@ -350,9 +358,10 @@ class iTopDesignFormat } } } - + /** * Downgrade the format from version 1.1 to 1.0 + * @param $oFactory * @return void (Errors are logged) */ protected function From11To10($oFactory) @@ -422,6 +431,7 @@ class iTopDesignFormat /** * Upgrade the format from version 1.1 to 1.2 + * @param $oFactory * @return void (Errors are logged) */ protected function From11To12($oFactory) @@ -430,6 +440,7 @@ class iTopDesignFormat /** * Downgrade the format from version 1.2 to 1.1 + * @param $oFactory * @return void (Errors are logged) */ protected function From12To11($oFactory) @@ -487,6 +498,7 @@ class iTopDesignFormat /** * Upgrade the format from version 1.2 to 1.3 + * @param $oFactory * @return void (Errors are logged) */ protected function From12To13($oFactory) @@ -495,6 +507,7 @@ class iTopDesignFormat /** * Downgrade the format from version 1.3 to 1.2 + * @param $oFactory * @return void (Errors are logged) */ protected function From13To12($oFactory) @@ -544,17 +557,19 @@ class iTopDesignFormat $oNode->setAttribute('_delta', 'must_exist'); } } - + /** * Upgrade the format from version 1.3 to 1.4 + * @param $oFactory * @return void (Errors are logged) */ protected function From13To14($oFactory) { } - + /** * Downgrade the format from version 1.4 to 1.3 + * @param $oFactory * @return void (Errors are logged) */ protected function From14To13($oFactory) @@ -585,8 +600,34 @@ class iTopDesignFormat $this->DeleteNode($oNode); } } - - + + /** + * Downgrade the format from version 1.5 to 1.4 + * @param $oFactory + * @return void (Errors are logged) + */ + protected function From15To14($oFactory) + { + $oXPath = new DOMXPath($this->oDocument); + + // Remove nodes on some menus + // + $sPath = "/itop_design/menus/menu[@xsi:type!='MenuGroup' and @xsi:type!='TemplateMenuNode']"; + $oNodeList = $oXPath->query("$sPath/enable_class | $sPath/enable_action | $sPath/enable_permission | $sPath/enable_stimulus"); + foreach ($oNodeList as $oNode) + { + $this->LogWarning('Node '.self::GetItopNodePath($oNode).' is irrelevant in this version, it will be ignored. Use enable_admin_only instead.'); + } + } + + /** + * Upgrade the format from version 1.4 to 1.5 + * @param $oFactory + * @return void (Errors are logged) + */ + protected function From14To15($oFactory) + { + } /** * Delete a node from the DOM and make sure to also remove the immediately following line break (DOMText), if any. diff --git a/synchro/synchrodatasource.class.inc.php b/synchro/synchrodatasource.class.inc.php index a427c34a7..f41336bc4 100644 --- a/synchro/synchrodatasource.class.inc.php +++ b/synchro/synchrodatasource.class.inc.php @@ -35,7 +35,7 @@ class SynchroDataSource extends cmdbAbstractObject { $aParams = array ( - "category" => "core/cmdb,view_in_gui", + "category" => "core/cmdb,view_in_gui,grant_by_profile", "key_type" => "autoincrement", "name_attcode" => array('name'), "state_attcode" => "", diff --git a/webservices/export-v2.php b/webservices/export-v2.php index 26a30a50c..885a946d9 100644 --- a/webservices/export-v2.php +++ b/webservices/export-v2.php @@ -718,6 +718,7 @@ try $sMode = utils::ReadParam('mode', ''); LoginWebPage::DoLogin(); // Check user rights and prompt if needed + ApplicationMenu::CheckMenuIdEnabled('ExportMenu'); ApplicationContext::SetUrlMakerClass('iTopStandardURLMaker');