diff --git a/application/config/navigation.php b/application/config/navigation.php index 485f8a3d9..7f1b29932 100644 --- a/application/config/navigation.php +++ b/application/config/navigation.php @@ -15,7 +15,8 @@ $config['navigation_header'] = array( 'link' => base_url('vilesci'), 'icon' => '', 'description' => 'Vilesci', - 'sort' => 2 + 'sort' => 2, + 'requiredPermissions' => 'basis/vilesci:r' ), 'cis' => array( 'link' => CIS_ROOT, @@ -57,7 +58,8 @@ $config['navigation_menu']['Vilesci/index'] = array( 'icon' => 'info', 'description' => 'Infocenter', 'expand' => true, - 'sort' => 2 + 'sort' => 2, + 'requiredPermissions' => 'infocenter:r' ), ) ), @@ -73,14 +75,16 @@ $config['navigation_menu']['Vilesci/index'] = array( 'icon' => '', 'description' => 'Vilesci', 'expand' => true, - 'sort' => 1 + 'sort' => 1, + 'requiredPermissions' => 'basis/vilesci:r' ), 'extensions' => array( 'link' => site_url('system/extensions/Manager'), 'icon' => 'cubes', 'description' => 'Extensions Manager', 'expand' => true, - 'sort' => 2 + 'sort' => 2, + 'requiredPermissions' => 'admin:r' ) ) ) diff --git a/application/libraries/NavigationLib.php b/application/libraries/NavigationLib.php index ceeddca52..1b15943ea 100644 --- a/application/libraries/NavigationLib.php +++ b/application/libraries/NavigationLib.php @@ -19,6 +19,8 @@ class NavigationLib const NAVIGATION_PAGE_PARAM = 'navigation_page'; // Navigation page parameter name + const PERMISSION_NAVIGATION_METHOD = 'NavigationWidget'; // Name for fake method to be checked by the PermissionLib + private $_ci; // Code igniter instance private $_navigationPage; // unique id for this navigation widget @@ -67,7 +69,7 @@ class NavigationLib public function oneLevel( $description, $link = '#', $children = null, $icon = '', $expand = false, $subscriptDescription = null, $subscriptLinkClass = null, $subscriptLinkValue = null, $target = '', - $sort = null) + $sort = null, $requiredPermissions = null) { return array( 'description' => $description, @@ -79,7 +81,8 @@ class NavigationLib 'subscriptDescription' => $subscriptDescription, 'subscriptLinkClass' => $subscriptLinkClass, 'subscriptLinkValue' => $subscriptLinkValue, - 'sort' => $sort + 'sort' => $sort, + 'requiredPermissions' => $requiredPermissions ); } @@ -208,7 +211,7 @@ class NavigationLib { $navigationArray = array(); - if (isset($navigationPage)) + if (isset($navigationPage)) // if the current page name is given { // Load Header Entries of Core $configArray = $this->_ci->config->item($configName); @@ -219,6 +222,7 @@ class NavigationLib if (hasData($extensions)) { $extensionArray = array(); + foreach ($extensions->retval as $ext) { $filename = APPPATH.'config/'.ExtensionsLib::EXTENSIONS_DIR_NAME.'/'.$ext->name.'/'.self::CONFIG_NAVIGATION_FILENAME; @@ -226,6 +230,7 @@ class NavigationLib { unset($config); include($filename); + if (isset($config[$configName]) && is_array($config[$configName])) { $extensionArray = array_merge_recursive( @@ -236,6 +241,7 @@ class NavigationLib } } } + $navigationArray = array_merge_recursive($navigationArray, $extensionArray); } @@ -246,7 +252,9 @@ class NavigationLib } } - $this->_sortArray($navigationArray); + $this->_rmNotAllowedEntries($navigationArray); // remove not allowed menu entries + + $this->_sortNavigationArray($navigationArray); // sort menu entries return $navigationArray; } @@ -319,9 +327,9 @@ class NavigationLib /** * Sorts using the sort element present in the array */ - private function _sortArray(&$array) + private function _sortNavigationArray(&$navigationArray) { - uasort($array, function($a, $b) { + uasort($navigationArray, function($a, $b) { // If the element sort is not present then the default value is 999 $sortA = 999; @@ -335,13 +343,55 @@ class NavigationLib }); // Sort also the children - foreach ($array as $key => $value) + foreach ($navigationArray as $menuName => $singleMenu) { - if (isset($value['children']) && is_array($value['children']) && count($value['children']) > 0) + if (isset($singleMenu['children']) && !isEmptyArray($singleMenu['children'])) { - // NOTE: keep this way to give the element by reference, $value has a different reference! + // NOTE: keep this way to give the element by reference, $singleMenu has a different reference! // otherwise the children will not be sorted - $this->_sortArray($array[$key]['children']); // recursive call + $this->_sortNavigationArray($navigationArray[$menuName]['children']); // recursive call + } + } + } + + /** + * Remove menu entries that the logged user is not allow to use + */ + private function _rmNotAllowedEntries(&$navigationArray) + { + $this->_ci->load->library('PermissionLib'); // Load permission library + + if (isset($navigationArray)) // to avoid error in the foreach + { + // Loops through the navigation array + foreach ($navigationArray as $menuName => $singleMenu) + { + // If the property requiredPermissions is present is checked + if (isset($singleMenu['requiredPermissions'])) + { + // Checks if the logged uses has at least one of required permissions + $isAllowed = $this->_ci->permissionlib->hasAtLeastOne( + $singleMenu['requiredPermissions'], + self::PERMISSION_NAVIGATION_METHOD + ); + + // If the user is not allowed then this menu entry and its children (sub menus) are removed and not displayed + if (!$isAllowed) + { + unset($navigationArray[$menuName]); + } + } + // Otherwise this menu entry is displayed + + // If the menu entry was NOT removed, then checks if it has children (sub menus) to check them for permissions + // NOTE: used $navigationArray[$menuName] because could be removed by the previous unset command + // therefore $singleMenu is still set + if (isset($navigationArray[$menuName]) && isset($singleMenu['children']) && !isEmptyArray($singleMenu['children'])) + { + // NOTE: keep this way to give the element by reference, $value has a different reference! + // otherwise the children will not be checked correctly + $this->_rmNotAllowedEntries($navigationArray[$menuName]['children']); // recursive call + } } } } diff --git a/application/libraries/PermissionLib.php b/application/libraries/PermissionLib.php index fa7363710..980598d9b 100644 --- a/application/libraries/PermissionLib.php +++ b/application/libraries/PermissionLib.php @@ -129,7 +129,7 @@ class PermissionLib if (is_cli()) return true; // Checks if the parameter $requiredPermissions is set, is an array and contains at least one element - if (isset($requiredPermissions) && is_array($requiredPermissions) && count($requiredPermissions) > 0) + if (isset($requiredPermissions) && !isEmptyArray($requiredPermissions)) { // Checks if the given $requiredPermissions parameter contains the called method of the controller if (isset($requiredPermissions[$calledMethod])) @@ -209,6 +209,7 @@ class PermissionLib * Checks if at least one of the permissions given as parameter (requiredPermissions) belongs to the authenticated user * It checks the given permissions against a given method (controller method name) and a given permission type (R and/or W) * If the $permissionType is not given then it is assumed that is already present inside requiredPermissions + * Wrapper method for isEntitled, it uses method to build an associative array of permissions having as key the method itself */ public function hasAtLeastOne($requiredPermissions, $method, $permissionType = null) {