public function checkActionAccessByGroups(action $action, array $groups) { static $groupMapper; profiler::addStack('acl::check'); $actionAclGroups = $action->getAcl(); $actionAclGroups[] = $action->getAclGroupName(); $actionAclGroups[] = aclManager::ACL__GROUP_ROOT; $actionAclGroups = array_unique($actionAclGroups, SORT_ASC); $actionGroupsCacheKey = 'acl/groups/' . md5(implode(',', $actionAclGroups)); $actionGroups = cache::getCached($actionGroupsCacheKey); if (!$actionGroups) { if ($groupMapper === null) { $groupMapper = groupMapper::getInstance(); } $cursor = $groupMapper->getAllBy([groupMapper::FIELD__GROUP_ALIAS => ['$in' => $actionAclGroups]]); $actionGroups = $this->expandGroupsByCursor($cursor); cache::setCached($actionGroupsCacheKey, $actionGroups, 3600); } $groups = array_unique($groups, SORT_ASC); $userGroupsCacheKey = 'acl/groups/' . md5(implode(',', $groups)); $userGroups = cache::getCached($userGroupsCacheKey); if (!$userGroups) { if ($groupMapper === null) { $groupMapper = groupMapper::getInstance(); } $cursor = $groupMapper->getAllBy([groupMapper::FIELD__GROUP_ALIAS => ['$in' => $groups]]); $userGroups = $this->expandGroupsByCursor($cursor); cache::setCached($userGroupsCacheKey, $userGroups, 3600); } $found = array_intersect($userGroups, $actionGroups); if (count($found) > 0) { return self::success($found, self::ACL__OK); } else { return self::error(['message' => 'Forbidden'], self::ACL__FORBIDDEN); } }
/** * @param action $action * @param array $arguments * @param null|bool $withoutBase * * @param bool $stopApp * * @throws Stop * @throws webApplicationException */ public function dispatch(action $action, array $arguments = [], $withoutBase = null, $stopApp = false) { static $apiTypes; profiler::addStack('app::dispatch'); MPCMF_LL_DEBUG && self::log()->addDebug(__METHOD__ . '(' . json_encode(func_get_args(), 320) . ')'); if ($apiTypes === null) { $apiTypes = [action::TYPE__API_FOR_ITEM => true, action::TYPE__API_GLOBAL => true]; } $slim = Slim::getInstance(); $aclManager = aclManager::getInstance(); $request = $slim->request(); $isApiRequest = isset($apiTypes[$action->getType()]); $isJson = $request->get(self::REQUEST__JSON, false) || $isApiRequest; $jsonPretty = $request->get(self::REQUEST__JSON_PRETTY, false); $jsonTemplate = $jsonPretty ? 'json.pretty.tpl' : 'json.tpl'; if ($isApiRequest) { $aclResponse = $aclManager->checkActionAccessByToken($action, $request->get('access_token')); if (!$aclResponse['status']) { $slim->render($jsonTemplate, ['data' => $aclResponse]); $slim->stop(); } } else { $aclManagerResponse = $aclManager->checkActionAccess($action); if (!$aclManagerResponse['status']) { $currentUrl = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '/'; $forbiddenUrl = $this->getUrl('/authex/user/forbidden', ['redirectUrl' => base64_encode($currentUrl)]); $slim->redirect($forbiddenUrl); $slim->stop(); } } try { $result = call_user_func_array($action->getCallable(), $arguments); } catch (actionException $actionException) { throw new webApplicationException("Action exception: {$actionException->getMessage()}", $actionException->getCode(), $actionException); } if ($isApiRequest) { echo json_encode($result); $slim->stop(); } elseif ($isJson) { array_walk_recursive($result, function (&$item) { if ($item instanceof \Traversable) { $item = iterator_to_array($item); foreach ($item as &$itemValue) { if ($itemValue instanceof modelBase) { $itemValue = $itemValue->export(); } else { break; } } } elseif ($item instanceof modelBase) { $item = $item->export(); } }); $slim->render($jsonTemplate, ['data' => $result]); } else { try { $result['_entity'] = $action->getEntityActions()->getEntity(); $result['i18n'] = i18n::lang(); $result['_profiler'] = profiler::get(); $result['_acl'] = $aclManager; $result['_slim'] = $slim; $result['_route'] = $slim->router()->getCurrentRoute(); $result['_application'] = $this; } catch (entityException $entityException) { throw new webApplicationException("Web application route process exception: {$entityException->getMessage()}", $entityException->getCode(), $entityException); } catch (modulePartsHelperException $modulePartsHelperException) { throw new webApplicationException("Web application route process exception: {$modulePartsHelperException->getMessage()}", $modulePartsHelperException->getCode(), $modulePartsHelperException); } if ($withoutBase === null) { $withoutBase = (bool) $request->get(self::REQUEST__WITHOUT_BASE, false); } try { if (!$withoutBase && $action->useBase()) { $result['_template'] = $action->getTemplate(); $slim->render('index.tpl', $result); } else { $result['_template'] = ''; $slim->render($action->getTemplate(), $result); } } catch (Stop $stopException) { if (!$stopApp) { throw $stopException; } } } }