597 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			PHP
		
	
	
			
		
		
	
	
			597 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			PHP
		
	
	
| <?php
 | |
| 
 | |
| namespace App\Controller\Component;
 | |
| 
 | |
| use Cake\Controller\Component;
 | |
| use App\Model\Entity\User;
 | |
| use Cake\Http\Exception\NotFoundException;
 | |
| use Cake\Http\Exception\MethodNotAllowedException;
 | |
| use Cake\Http\Exception\ForbiddenException;
 | |
| use Cake\ORM\TableRegistry;
 | |
| use Cake\Core\Configure;
 | |
| use Cake\Core\Configure\Engine\PhpConfig;
 | |
| use Cake\Utility\Inflector;
 | |
| use Cake\Routing\Router;
 | |
| 
 | |
| class ACLComponent extends Component
 | |
| {
 | |
| 
 | |
|     private $user = null;
 | |
|     protected $components = ['Navigation'];
 | |
| 
 | |
|     public function initialize(array $config): void
 | |
|     {
 | |
|         $this->request = $config['request'];
 | |
|         $this->Authentication = $config['Authentication'];
 | |
|     }
 | |
| 
 | |
|     // syntax:
 | |
|     // $__aclList[$controller][$action] = $permission_rules
 | |
|     // $controller == '*'                 -  any controller can have this action
 | |
|     // $action == []                 -  site admin only has access
 | |
|     // $action == '*'                     -  any role has access
 | |
|     // $action == array('OR' => [])  -  any role in the array has access
 | |
|     // $action == array('AND' => []) -  roles with all permissions in the array have access
 | |
|     // If we add any new functionality to MISP and we don't add it to this list, it will only be visible to site admins.
 | |
|     private $aclList = array(
 | |
|         '*' => [
 | |
|             'checkPermission' => ['*'],
 | |
|             'generateUUID' => ['*'],
 | |
|             'getRoleAccess' => ['*'],
 | |
|             'queryACL' => ['perm_admin']
 | |
|         ],
 | |
|         'Alignments' => [
 | |
|             'add' => ['perm_admin'],
 | |
|             'delete' => ['perm_admin'],
 | |
|             'index' => ['*'],
 | |
|             'view' => ['*']
 | |
|         ],
 | |
|         'AuditLogs' => [
 | |
|             'filtering' => ['perm_admin'],
 | |
|             'index' => ['perm_admin'],
 | |
|         ],
 | |
|         'AuthKeys' => [
 | |
|             'add' => ['*'],
 | |
|             'delete' => ['*'],
 | |
|             'index' => ['*']
 | |
|         ],
 | |
|         'Broods' => [
 | |
|             'add' => ['perm_admin'],
 | |
|             'delete' => ['perm_admin'],
 | |
|             'downloadIndividual' => ['perm_admin'],
 | |
|             'downloadOrg' => ['perm_admin'],
 | |
|             'downloadSharingGroup' => ['perm_admin'],
 | |
|             'edit' => ['perm_admin'],
 | |
|             'index' => ['perm_admin'],
 | |
|             'interconnectTools' => ['perm_admin'],
 | |
|             'previewIndex' => ['perm_admin'],
 | |
|             'testConnection' => ['perm_admin'],
 | |
|             'view' => ['perm_admin']
 | |
|         ],
 | |
|         'EncryptionKeys' => [
 | |
|             'view' => ['*'],
 | |
|             'add' => ['*'],
 | |
|             'edit' => ['*'],
 | |
|             'delete' => ['*'],
 | |
|             'index' => ['*']
 | |
|         ],
 | |
|         'Inbox' => [
 | |
|             'createEntry' => ['OR' => ['perm_admin', 'perm_sync']],
 | |
|             'delete' => ['perm_admin'],
 | |
|             'filtering' => ['perm_admin'],
 | |
|             'index' => ['perm_admin'],
 | |
|             'listProcessors' => ['OR' => ['perm_admin', 'perm_sync']],
 | |
|             'process' => ['perm_admin'],
 | |
|             'view' => ['perm_admin'],
 | |
|         ],
 | |
|         'Individuals' => [
 | |
|             'add' => ['perm_admin'],
 | |
|             'delete' => ['perm_admin'],
 | |
|             'edit' => ['perm_admin', 'perm_org_admin'],
 | |
|             'filtering' => ['*'],
 | |
|             'index' => ['*'],
 | |
|             'tag' => ['*'],
 | |
|             'untag' => ['*'],
 | |
|             'view' => ['*'],
 | |
|             'viewTags' => ['*']
 | |
|         ],
 | |
|         'Instance' => [
 | |
|             'home' => ['*'],
 | |
|             'migrate' => ['perm_admin'],
 | |
|             'migrationIndex' => ['perm_admin'],
 | |
|             'rollback' => ['perm_admin'],
 | |
|             'saveSetting' => ['perm_admin'],
 | |
|             'searchAll' => ['*'],
 | |
|             'settings' => ['perm_admin'],
 | |
|             'status' => ['*']
 | |
|         ],
 | |
|         'LocalTools' => [
 | |
|             'action' => ['perm_admin'],
 | |
|             'add' => ['perm_admin'],
 | |
|             'batchAction' => ['perm_admin'],
 | |
|             'broodTools' => ['perm_admin'],
 | |
|             'connectionRequest' => ['perm_admin'],
 | |
|             // 'connectLocal' => ['perm_admin'],
 | |
|             'delete' => ['perm_admin'],
 | |
|             'edit' => ['perm_admin'],
 | |
|             'exposedTools' => ['OR' => ['perm_admin', 'perm_sync']],
 | |
|             'index' => ['perm_admin'],
 | |
|             'connectorIndex' => ['perm_admin'],
 | |
|             'view' => ['perm_admin'],
 | |
|             'viewConnector' => ['perm_admin']
 | |
|         ],
 | |
|         'MailingLists' => [
 | |
|             "add" => ['perm_org_admin'],
 | |
|             "addIndividual" => ['perm_org_admin'],
 | |
|             "delete" => ['perm_org_admin'],
 | |
|             "edit" => ['perm_org_admin'],
 | |
|             "index" => ['*'],
 | |
|             "listIndividuals" => ['perm_org_admin'],
 | |
|             "removeIndividual" => ['perm_org_admin'],
 | |
|             "view" => ['*'],
 | |
|         ],
 | |
|         'MetaTemplateFields' => [
 | |
|             'index' => ['perm_admin']
 | |
|         ],
 | |
|         'MetaTemplates' => [
 | |
|             'createNewTemplate' => ['perm_admin'],
 | |
|             'delete' => ['perm_admin'],
 | |
|             'disable' => ['perm_admin'],
 | |
|             'enable' => ['perm_admin'],
 | |
|             'getMetaFieldsToUpdate' => ['perm_admin'],
 | |
|             'index' => ['perm_admin'],
 | |
|             'migrateOldMetaTemplateToNewestVersionForEntity' => ['perm_admin'],
 | |
|             'update' => ['perm_admin'],
 | |
|             'updateAllTemplates' => ['perm_admin'],
 | |
|             'toggle' => ['perm_admin'],
 | |
|             'view' => ['perm_admin'],
 | |
|         ],
 | |
|         'Organisations' => [
 | |
|             'add' => ['perm_admin'],
 | |
|             'delete' => ['perm_admin'],
 | |
|             'edit' => ['perm_admin'],
 | |
|             'filtering' => ['*'],
 | |
|             'index' => ['*'],
 | |
|             'tag' => ['perm_org_admin'],
 | |
|             'untag' => ['perm_org_admin'],
 | |
|             'view' => ['*'],
 | |
|             'viewTags' => ['*']
 | |
|         ],
 | |
|         'Outbox' => [
 | |
|             'createEntry' => ['perm_admin'],
 | |
|             'delete' => ['perm_admin'],
 | |
|             'filtering' => ['perm_admin'],
 | |
|             'index' => ['perm_admin'],
 | |
|             'listProcessors' => ['perm_admin'],
 | |
|             'process' => ['perm_admin'],
 | |
|             'view' => ['perm_admin']
 | |
|         ],
 | |
|         'Pages' => [
 | |
|             'display' => ['*']
 | |
|         ],
 | |
|         'PermissionLimitations' => [
 | |
|             "index" => ['*'],
 | |
|             "add" => ['perm_admin'],
 | |
|             "view" => ['*'],
 | |
|             "edit" => ['perm_admin'],
 | |
|             "delete" => ['perm_admin']
 | |
|         ],
 | |
|         'Roles' => [
 | |
|             'add' => ['perm_admin'],
 | |
|             'delete' =>  ['perm_admin'],
 | |
|             'edit' =>  ['perm_admin'],
 | |
|             'index' =>  ['*'],
 | |
|             'view' =>  ['*']
 | |
|         ],
 | |
|         'SharingGroups' => [
 | |
|             'add' => ['perm_org_admin'],
 | |
|             'addOrg' => ['perm_org_admin'],
 | |
|             'delete' => ['perm_org_admin'],
 | |
|             'edit' => ['perm_org_admin'],
 | |
|             'index' => ['*'],
 | |
|             'listOrgs' => ['*'],
 | |
|             'removeOrg' => ['perm_org_admin'],
 | |
|             'view' => ['*']
 | |
|         ],
 | |
|         'Users' => [
 | |
|             'add' => ['perm_org_admin'],
 | |
|             'delete' => ['perm_org_admin'],
 | |
|             'edit' => ['*'],
 | |
|             'index' => ['perm_org_admin'],
 | |
|             'login' => ['*'],
 | |
|             'logout' => ['*'],
 | |
|             'register' => ['*'],
 | |
|             'settings' => ['*'],
 | |
|             'toggle' => ['perm_org_admin'],
 | |
|             'view' => ['*']
 | |
|         ],
 | |
|         'UserSettings' => [
 | |
|             'index' => ['*'],
 | |
|             'view' => ['*'],
 | |
|             'add' => ['*'],
 | |
|             'edit' => ['*'],
 | |
|             'delete' => ['*'],
 | |
|             'getMySettingByName' => ['*'],
 | |
|             'setMySetting' => ['*'],
 | |
|             'saveSetting' => ['*'],
 | |
|             'getMyBookmarks' => ['*'],
 | |
|             'saveMyBookmark' => ['*'],
 | |
|             'deleteMyBookmark' => ['*']
 | |
|         ],
 | |
|         'Api' => [
 | |
|             'index' => ['*']
 | |
|         ]
 | |
|     );
 | |
| 
 | |
|     private function __checkLoggedActions($user, $controller, $action)
 | |
|     {
 | |
|         $loggedActions = array(
 | |
|             'servers' => array(
 | |
|                 'index' => array(
 | |
|                     'role' => array(
 | |
|                         'NOT' => array(
 | |
|                             'perm_site_admin'
 | |
|                         )
 | |
|                     ),
 | |
|                     'message' => __('This could be an indication of an attempted privilege escalation on older vulnerable versions of MISP (<2.4.115)')
 | |
|                 )
 | |
|             )
 | |
|         );
 | |
|         foreach ($loggedActions as $k => $v) {
 | |
|             $loggedActions[$k] = array_change_key_case($v);
 | |
|         }
 | |
|         $message = '';
 | |
|         if (!empty($loggedActions[$controller])) {
 | |
|             if (!empty($loggedActions[$controller][$action])) {
 | |
|                 $message = $loggedActions[$controller][$action]['message'];
 | |
|                 $hit = false;
 | |
|                 if (empty($loggedActions[$controller][$action]['role'])) {
 | |
|                     $hit = true;
 | |
|                 } else {
 | |
|                     $role_req = $loggedActions[$controller][$action]['role'];
 | |
|                     if (empty($role_req['OR']) && empty($role_req['AND']) && empty($role_req['NOT'])) {
 | |
|                         $role_req = array('OR' => $role_req);
 | |
|                     }
 | |
|                     if (!empty($role_req['NOT'])) {
 | |
|                         foreach ($role_req['NOT'] as $k => $v) {
 | |
|                             if (!$user['Role'][$v]) {
 | |
|                                 $hit = true;
 | |
|                                 continue;
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                     if (!$hit && !empty($role_req['AND'])) {
 | |
|                         $subhit = true;
 | |
|                         foreach ($role_req['AND'] as $k => $v) {
 | |
|                             $subhit = $subhit && $user['Role'][$v];
 | |
|                         }
 | |
|                         if ($subhit) {
 | |
|                             $hit = true;
 | |
|                         }
 | |
|                     }
 | |
|                     if (!$hit && !empty($role_req['OR'])) {
 | |
|                         foreach ($role_req['OR'] as $k => $v) {
 | |
|                             if ($user['Role'][$v]) {
 | |
|                                 $hit = true;
 | |
|                                 continue;
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                     if ($hit) {
 | |
|                         $this->Log = TableRegistry::get('Log');
 | |
|                         $this->Log->create();
 | |
|                         $this->Log->save(array(
 | |
|                                 'org' => 'SYSTEM',
 | |
|                                 'model' => 'User',
 | |
|                                 'model_id' => $user['id'],
 | |
|                                 'email' => $user['email'],
 | |
|                                 'action' => 'security',
 | |
|                                 'user_id' => $user['id'],
 | |
|                                 'title' => __('User triggered security alert by attempting to access /%s/%s. Reason why this endpoint is of interest: %s', $controller, $action, $message),
 | |
|                         ));
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public function setUser(User $user): void
 | |
|     {
 | |
|         $this->user = $user;
 | |
|     }
 | |
| 
 | |
|     public function getUser(): ?User
 | |
|     {
 | |
|         if (!empty($this->user)) {
 | |
|             return $this->user;
 | |
|         }
 | |
|         return null;
 | |
|     }
 | |
| 
 | |
|     public function canEditUser(User $currentUser, User $user): bool
 | |
|     {
 | |
|         if (empty($user) || empty($currentUser)) {
 | |
|             return false;
 | |
|         }
 | |
|         if (!$currentUser['role']['perm_admin']) {
 | |
|             if ($user['role']['perm_admin']) {
 | |
|                 return false; // org_admins cannot edit admins
 | |
|             }
 | |
|             if (!$currentUser['role']['perm_org_admin']) {
 | |
|                 return false;
 | |
|             } else {
 | |
|                 if ($currentUser['organisation_id'] !== $user['organisation_id']) {
 | |
|                     return false;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         return true;
 | |
|     }
 | |
| 
 | |
|     /*
 | |
|      *  By default nothing besides the login is public. If configured, override the list with the additional interfaces
 | |
|      */
 | |
|     public function setPublicInterfaces(): void
 | |
|     {
 | |
|         $this->Authentication->allowUnauthenticated(['login', 'register']);
 | |
|     }
 | |
| 
 | |
|     private function checkAccessInternal($controller, $action, $soft): bool
 | |
|     {
 | |
|         if (empty($this->user)) {
 | |
|             // we have to be in a publically allowed scope otherwise the Auth component will kick us out anyway.
 | |
|             return true;
 | |
|         }
 | |
|         if (!empty($this->user->role->perm_admin)) {
 | |
|             return true;
 | |
|         }
 | |
|         //$this->__checkLoggedActions($user, $controller, $action);
 | |
|         if (isset($this->aclList['*'][$action])) {
 | |
|             if ($this->evaluateAccessLeaf('*', $action)) {
 | |
|                 return true;
 | |
|             }
 | |
|         }
 | |
|         if (!isset($this->aclList[$controller])) {
 | |
|             return $this->__error(404, __('Invalid controller.'), $soft);
 | |
|         }
 | |
|         return $this->evaluateAccessLeaf($controller, $action);
 | |
|     }
 | |
| 
 | |
|     private function evaluateAccessLeaf(string $controller, string $action): bool
 | |
|     {
 | |
|         if (isset($this->aclList[$controller][$action]) && !empty($this->aclList[$controller][$action])) {
 | |
|             if (in_array('*', $this->aclList[$controller][$action])) {
 | |
|                 return true;
 | |
|             }
 | |
|             if (isset($this->aclList[$controller][$action]['OR'])) {
 | |
|                 foreach ($this->aclList[$controller][$action]['OR'] as $permission) {
 | |
|                     if ($this->user['role'][$permission]) {
 | |
|                         return true;
 | |
|                     }
 | |
|                 }
 | |
|             } elseif (isset($this->aclList[$controller][$action]['AND'])) {
 | |
|                 $allConditionsMet = true;
 | |
|                 foreach ($this->aclList[$controller][$action]['AND'] as $permission) {
 | |
|                     if (!$this->user['role'][$permission]) {
 | |
|                         $allConditionsMet = false;
 | |
|                     }
 | |
|                 }
 | |
|                 if ($allConditionsMet) {
 | |
|                     return true;
 | |
|                 }
 | |
|             } else {
 | |
|                 foreach ($this->aclList[$controller][$action] as $permission) {
 | |
|                     if ($this->user['role'][$permission]) {
 | |
|                         return true;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     public function checkAccessUrl($url, $soft = false): bool
 | |
|     {
 | |
|         $urlParts = explode('/', $url);
 | |
|         if ($urlParts[1] === 'open') {
 | |
|             return in_array($urlParts[2], Configure::read('Cerebrate.open'));
 | |
|         } else {
 | |
|             return $this->checkAccessInternal(Inflector::camelize($urlParts[1]), $urlParts[2], $soft);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // The check works like this:
 | |
|     // If the user is a site admin, return true
 | |
|     // If the requested action has an OR-d list, iterate through the list. If any of the permissions are set for the user, return true
 | |
|     // If the requested action has an AND-ed list, iterate through the list. If any of the permissions for the user are not set, turn the check to false. Otherwise return true.
 | |
|     // If the requested action has a permission, check if the user's role has it flagged. If yes, return true
 | |
|     // If we fall through all of the checks, return an exception.
 | |
|     public function checkAccess(bool $soft = false): bool
 | |
|     {
 | |
|         $controller = $this->request->getParam('controller');
 | |
|         $action = $this->request->getParam('action');
 | |
|         if ($this->checkAccessInternal($controller, $action, $soft) === true) {
 | |
|             return true;
 | |
|         }
 | |
|         return $this->__error(403, 'You do not have permission to use this functionality.', $soft);
 | |
|     }
 | |
| 
 | |
|     private function __error($code, $message, $soft = false)
 | |
|     {
 | |
|         if ($soft) {
 | |
|             return false;
 | |
|         }
 | |
|         switch ($code) {
 | |
|             case 404:
 | |
|                 throw new NotFoundException($message);
 | |
|                 break;
 | |
|             case 403:
 | |
|                 throw new MethodNotAllowedException($message);
 | |
|             default:
 | |
|                 throw new InternalErrorException('Unknown error: ' . $message);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     private function __findAllFunctions()
 | |
|     {
 | |
|         $functionFinder = '/public.function[\s\n]+(\S+)[\s\n]*\(/';
 | |
|         $files = scandir(ROOT . '/src/Controller/');
 | |
|         foreach ($files as $k => $file) {
 | |
|             if (substr($file, -14) !== 'Controller.php') {
 | |
|                 unset($files[$k]);
 | |
|             }
 | |
|         }
 | |
|         $results = [];
 | |
|         foreach ($files as $file) {
 | |
|             $controllerName = lcfirst(str_replace('Controller.php', "", $file));
 | |
|             if ($controllerName === 'app') {
 | |
|                 $controllerName = '*';
 | |
|             }
 | |
|             $functionArray = [];
 | |
|             $fileContents = file_get_contents(APP . 'Controller' . DS . $file);
 | |
|             $fileContents = preg_replace('/\/\*[^\*]+?\*\//', '', $fileContents);
 | |
|             preg_match_all($functionFinder, $fileContents, $functionArray);
 | |
|             foreach ($functionArray[1] as $function) {
 | |
|                 if (substr($function, 0, 1) !== '_' && $function !== 'beforeFilter' && $function !== 'afterFilter') {
 | |
|                     $results[$controllerName][] = $function;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         return $results;
 | |
|     }
 | |
| 
 | |
|     public function printAllFunctionNames($content = false)
 | |
|     {
 | |
|         $results = $this->__findAllFunctions();
 | |
|         ksort($results);
 | |
|         return $results;
 | |
|     }
 | |
| 
 | |
|     public function findMissingFunctionNames($content = false)
 | |
|     {
 | |
|         $results = $this->__findAllFunctions();
 | |
|         $missing = [];
 | |
|         foreach ($results as $controller => $functions) {
 | |
|             $controller = Inflector::camelize($controller);
 | |
|             foreach ($functions as $function) {
 | |
|                 if (in_array($function, ['beforeFilter', 'beforeRender', 'initialize', 'afterFilter'])) {
 | |
|                     continue;
 | |
|                 }
 | |
|                 if (!isset($this->aclList[$controller])
 | |
|                 || !in_array($function, array_keys($this->aclList[$controller]))) {
 | |
|                     $missing[$controller][] = $function;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         return $missing;
 | |
|     }
 | |
| 
 | |
|     public function getRoleAccess($role = false, $url_mode = true)
 | |
|     {
 | |
|         return $this->__checkRoleAccess($role, $url_mode);
 | |
|     }
 | |
| 
 | |
|     public function printRoleAccess($content = false)
 | |
|     {
 | |
|         $results = [];
 | |
|         $this->Role = TableRegistry::get('Roles');
 | |
|         $conditions = [];
 | |
|         if (is_numeric($content)) {
 | |
|             $conditions = array('id' => $content);
 | |
|         }
 | |
|         $roles = $this->Role->find('all', array(
 | |
|             'recursive' => -1,
 | |
|             'conditions' => $conditions
 | |
|         ));
 | |
|         if (empty($roles)) {
 | |
|             throw new NotFoundException('Role not found.');
 | |
|         }
 | |
|         foreach ($roles as $role) {
 | |
|             $urls = $this->__checkRoleAccess($role['Role']);
 | |
|             $results[$role['Role']['id']] = array('name' => $role['Role']['name'], 'urls' => $urls);
 | |
|         }
 | |
|         return $results;
 | |
|     }
 | |
| 
 | |
|     private function __formatControllerAction(array $results, string $controller, string $action, $url_mode = true): array
 | |
|     {
 | |
|         if ($url_mode) {
 | |
|             $results[] = DS . $controller . DS . $action . DS . '*';
 | |
|         } else {
 | |
|             $results[$controller][] = $action;
 | |
|         }
 | |
|         return $results;
 | |
|     }
 | |
| 
 | |
|     private function __checkRoleAccess($role = false, $url_mode = true)
 | |
|     {
 | |
|         $results = [];
 | |
|         if ($role === false) {
 | |
|             $role = $this->getUser()['role'];
 | |
|         }
 | |
|         foreach ($this->aclList as $controller => $actions) {
 | |
|             foreach ($actions as $action => $permissions) {
 | |
|                 if ($role['perm_admin']) {
 | |
|                     $results = $this->__formatControllerAction($results, $controller, $action, $url_mode);
 | |
|                 } elseif (in_array('*', $permissions)) {
 | |
|                     $results = $this->__formatControllerAction($results, $controller, $action, $url_mode);
 | |
|                 } elseif (isset($permissions['OR'])) {
 | |
|                     $access = false;
 | |
|                     foreach ($permissions['OR'] as $permission) {
 | |
|                         if ($role[$permission]) {
 | |
|                             $access = true;
 | |
|                         }
 | |
|                     }
 | |
|                     if ($access) {
 | |
|                         $results = $this->__formatControllerAction($results, $controller, $action, $url_mode);
 | |
|                     }
 | |
|                 } elseif (isset($permissions['AND'])) {
 | |
|                     $access = true;
 | |
|                     foreach ($permissions['AND'] as $permission) {
 | |
|                         if ($role[$permission]) {
 | |
|                             $access = false;
 | |
|                         }
 | |
|                     }
 | |
|                     if ($access) {
 | |
|                         $results = $this->__formatControllerAction($results, $controller, $action, $url_mode);
 | |
|                     }
 | |
|                 } elseif (isset($permissions[0]) && $role[$permissions[0]]) {
 | |
|                     $results = $this->__formatControllerAction($results, $controller, $action, $url_mode);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         return $results;
 | |
|     }
 | |
| 
 | |
|     public function getMenu()
 | |
|     {
 | |
|         $menu = $this->Navigation->getSideMenu();
 | |
|         foreach ($menu as $group => $subMenu) {
 | |
|             if ($group == '__bookmarks') {
 | |
|                 continue;
 | |
|             }
 | |
|             foreach ($subMenu as $subMenuElementName => $subMenuElement) {
 | |
|                 if (!empty($subMenuElement['url']) && !$this->checkAccessUrl($subMenuElement['url'], true) === true) {
 | |
|                     unset($menu[$group][$subMenuElementName]);
 | |
|                     continue;
 | |
|                 }
 | |
|                 if (!empty($subMenuElement['children'])) {
 | |
|                     foreach ($subMenuElement['children'] as $menuItem => $menuItemData) {
 | |
|                         if (!empty($menuItemData['url']) && !$this->checkAccessUrl($menuItemData['url'], true) === true) {
 | |
|                             unset($menu[$group][$subMenuElementName]['children'][$menuItem]);
 | |
|                             continue;
 | |
|                         }
 | |
|                     }
 | |
|                     if (empty($menu[$group][$subMenuElementName]['children'])) {
 | |
|                         unset($subMenu[$subMenuElementName]);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             if (empty($menu[$group])) {
 | |
|                 unset($menu[$group]);
 | |
|             }
 | |
|         }
 | |
|         return $menu;
 | |
|     }
 | |
| }
 |