getServiceLocator()->get(ActionProtector::SERVICE_ID); $actionProtector->setHeaders(); } /** * Whenever or not the current user has access to a specific action * using functional and data access control * * @param string $controllerClass * @param string $action * @param array $parameters * @return boolean * @throws common_exception_Error */ protected function hasAccess($controllerClass, $action, $parameters = []) { $user = $this->getSession()->getUser(); return AclProxy::hasAccess($user, $controllerClass, $action, $parameters); } /** * @deprecated Use $this->hasWriteAccessByContext() */ protected function hasWriteAccessToAction(string $action, ?User $user = null): bool { $context = new AclContext([ AclContext::PARAM_CONTROLLER => static::class, AclContext::PARAM_ACTION => $action, AclContext::PARAM_USER => $user, ]); return $this->hasWriteAccessByContext($context); } protected function hasReadAccessByContext(AclContext $context): bool { return $this->getActionAccessControl()->contextHasReadAccess($context); } protected function hasWriteAccessByContext(AclContext $context): bool { return $this->getActionAccessControl()->contextHasWriteAccess($context); } protected function getUserRoles(): array { return $this->getSession()->getUser()->getRoles(); } /** * * @see Module::setView() * @param string $path * view identifier * @param string $extensionID * use the views in the specified extension instead of the current extension */ public function setView($path, $extensionID = null) { $this->setRendererView(Template::getTemplate($path, $extensionID)); } /** * Retrieve the data from the url and make the base initialization * * @return void * @throws common_ext_ExtensionException */ protected function defaultData() { $context = Context::getInstance(); $this->setData('extension', $context->getExtensionName()); $this->setData('module', $context->getModuleName()); $this->setData('action', $context->getActionName()); if ($this->hasRequestParameter('uri')) { // inform the client of new classUri $this->setData('uri', $this->getRequestParameter('uri')); } if ($this->hasRequestParameter('classUri')) { // inform the client of new classUri $this->setData('uri', $this->getRequestParameter('classUri')); } if ($this->getRequestParameter('message')) { $this->setData('message', $this->getRequestParameter('message')); } if ($this->getRequestParameter('errorMessage')) { $this->setData('errorMessage', $this->getRequestParameter('errorMessage')); } $this->setData('client_timeout', $this->getClientTimeout()); $this->setData('client_config_url', $this->getClientConfigUrl()); } /** * Function to return an user readable error * Does not work with ajax Requests yet * * @param string $description error to show * @param boolean $returnLink whenever or not to add a return link * @param int $httpStatus * @throws common_Exception */ protected function returnError($description, $returnLink = true, $httpStatus = null) { if ($this->isXmlHttpRequest()) { $this->logWarning('Called ' . __FUNCTION__ . ' in an unsupported AJAX context'); throw new common_Exception($description); } $this->setData('message', $description); $this->setData('returnLink', $returnLink); if (parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST) == parse_url(ROOT_URL, PHP_URL_HOST)) { $this->setData('returnUrl', htmlentities($_SERVER['HTTP_REFERER'],ENT_QUOTES)); }else{ $this->setData('returnUrl', false); } if ($httpStatus !== null && file_exists(Template::getTemplate("error/error${httpStatus}.tpl"))) { $this->setView("error/error${httpStatus}.tpl", 'tao'); } else { $this->setView('error/user_error.tpl', 'tao'); } } /** * Returns the absolute path to the specified template * * @param string $identifier * @param string $extensionID * @return string * @throws common_exception_Error * @throws common_ext_ExtensionException */ protected static function getTemplatePath($identifier, $extensionID = null) { if ($extensionID === true) { $extensionID = 'tao'; common_Logger::d('Deprecated use of setView() using a boolean'); } if ($extensionID === null) { $extensionID = Context::getInstance()->getExtensionName(); } $ext = common_ext_ExtensionsManager::singleton()->getExtensionById($extensionID); return $ext->getConstant('DIR_VIEWS') . 'templates' . DIRECTORY_SEPARATOR . $identifier; } /** * Helps you to add the URL of the client side config file * * @param array $extraParameters additional parameters to append to the URL * @return string the URL */ protected function getClientConfigUrl($extraParameters = []) { return JavaScript::getClientConfigUrl($extraParameters); } /** * Get the client timeout value from the config. * * @return int the timeout value in seconds * @throws common_ext_ExtensionException */ protected function getClientTimeout() { $ext = $this->getServiceManager()->get(common_ext_ExtensionsManager::SERVICE_ID)->getExtensionById('tao'); $config = $ext->getConfig('js'); if ($config !== null && isset($config['timeout'])) { return (int)$config['timeout']; } return 30; } /** * Return json response. * * @param array|\JsonSerializable $data * @param int $httpStatus * * @deprecated use \oat\tao\model\http\HttpJsonResponseTrait::setSuccessJsonResponse for standard response * @deprecated use \oat\tao\model\http\HttpJsonResponseTrait::setErrorJsonResponse for standard response */ protected function returnJson($data, $httpStatus = 200) { header(HTTPToolkit::statusCodeHeader($httpStatus)); Context::getInstance()->getResponse()->setContentHeader('application/json'); $this->response = $this->getPsrResponse()->withBody(stream_for(json_encode($data))); } /** * Returns a report * * @param common_report_Report $report */ protected function returnReport(common_report_Report $report) { $data = $report->getData(); $successes = $report->getSuccesses(); // if report has no data, try to get it from the sub report while ($data === null && count($successes) > 0) { $firstSubReport = current($successes); $data = $firstSubReport->getData(); $successes = $firstSubReport->getSuccesses(); } if ($data !== null && $data instanceof core_kernel_classes_Resource) { $this->setData('selectNode', tao_helpers_Uri::encode($data->getUri())); } $this->setData('report', $report); $this->setView('report.tpl', 'tao'); } /** * Get the current session * * @return common_session_Session * @throws common_exception_Error */ protected function getSession() { return common_session_SessionManager::getSession(); } /** * Get the service Manager * * @deprecated Use $this->propagate or $this->registerService to access ServiceManager functionalities * @deprecated To get the service dependencies manager, use $this->getServiceLocator * * @return ServiceManager */ protected function getServiceManager() { try { $serviceManager = $this->getOriginalServiceManager(); } catch (InvalidServiceManagerException $e) { $serviceManager = ServiceManager::getServiceManager(); } return $serviceManager; } /** * @return ServiceLocatorInterface * @security("hide"); */ public function getServiceLocator() { return $this->getOriginalServiceLocator(); } /** * @param ServiceLocatorInterface $serviceLocator * @return mixed * @security("hide"); */ public function setServiceLocator(ServiceLocatorInterface $serviceLocator) { return $this->setOriginalServiceLocator($serviceLocator); } /** * Validate a CSRF token, based on the CSRF header. * * @throws common_exception_Unauthorized */ protected function validateCsrf() { if (!$this->getPsrRequest()->hasHeader(TokenService::CSRF_TOKEN_HEADER)) { $this->logCsrfFailure(sprintf('Missing %s header.', TokenService::CSRF_TOKEN_HEADER)); } $csrfTokenHeader = $this->getPsrRequest()->getHeader(TokenService::CSRF_TOKEN_HEADER); $csrfToken = current($csrfTokenHeader); /** @var TokenService $tokenService */ $tokenService = $this->getServiceLocator()->get(TokenService::SERVICE_ID); $newToken = null; try { if ($tokenService->validateToken($csrfToken)) { $newToken = $tokenService->createToken()->getValue(); } } catch (common_exception_Unauthorized $e) { $this->logCsrfFailure($e->getMessage(), $csrfToken); } $this->response = $this->getPsrResponse()->withHeader(TokenService::CSRF_TOKEN_HEADER, $newToken); } /** * Logs a CSRF validation error * * @param string $exceptionMessage * @param null $token * @throws common_exception_Unauthorized */ private function logCsrfFailure($exceptionMessage, $token = null) { try { $userIdentifier = $this->getSession()->getUser()->getIdentifier(); } catch (common_exception_Error $e) { $this->logError('Unable to retrieve session! ' . $e->getMessage()); throw new common_exception_Unauthorized($exceptionMessage); } $requestMethod = $this->getPsrRequest()->getMethod(); $requestUri = $this->getPsrRequest()->getUri(); $requestHeaders = $this->getHeaders(); $this->logWarning( '[CSRF] - Failed to validate CSRF token. The following exception occurred: ' . $exceptionMessage ); $this->logWarning( "[CSRF] \n" . "CSRF validation information: \n" . 'Provided token: ' . ($token ?: 'none') . " \n" . 'User identifier: ' . $userIdentifier . " \n" . 'Request: [' . $requestMethod . '] ' . $requestUri . " \n" . "Request Headers : \n" . urldecode(http_build_query($requestHeaders, '', "\n")) ); throw new common_exception_Unauthorized($exceptionMessage); } /** * Ensure the template is rendered as part of the response * {@inheritDoc} * @see \oat\tao\model\http\Controller::getPsrResponse() */ public function getPsrResponse() { $response = parent::getPsrResponse(); return $this->hasView() ? $response->withBody(stream_for($this->getRenderer()->render())) : $response; } private function getActionAccessControl(): ActionAccessControl { return $this->getServiceLocator()->get(ActionAccessControl::SERVICE_ID); } }