/** * Set the 'X-Frame-Options' headers to prevent click-jacking, unless * specifically disabled. Backend only! * * @param Request $request * @param Response $response */ protected function setFrameOptions(Request $request, Response $response) { if (Zone::isBackend($request) && $this->app['config']->get('general/headers/x_frame_options')) { $response->headers->set('X-Frame-Options', 'SAMEORIGIN'); $response->headers->set('Frame-Options', 'SAMEORIGIN'); } }
/** * Normal boot functions. * * @param GetResponseEvent $event * * @return Response|null */ public function onBoot(GetResponseEvent $event) { if (Zone::isBackend($event->getRequest())) { $this->setVersionChangeNotice(); } // Twig globals $this->setGlobals(false); $this->setGlobals(true); // Only cache if the config passes checks if ($this->app['config']->checkConfig() === false) { return null; } // Final thing we do, if we're still standing, is to save our // configuration to cache if (!$this->app['config']->get('general/caching/config')) { return null; } $cacheFs = $this->app['filesystem']->getFilesystem('cache'); try { $this->app['config']->cacheConfig($cacheFs, '', false); } catch (IOException $e) { $response = $this->app['controller.exception']->genericException($e); $event->setResponse($response); } }
/** * Render the not found page if on frontend and http exception * * @param GetResponseForExceptionEvent $event */ public function onKernelException(GetResponseForExceptionEvent $event) { $exception = $event->getException(); if (!$exception instanceof HttpExceptionInterface || Zone::isBackend($event->getRequest())) { return; } if ($exception->getStatusCode() !== Response::HTTP_NOT_FOUND) { return; } // If $notFoundPage is referencing a template, render it and be done. if ($this->render->hasTemplate($this->notFoundPage)) { try { $this->renderNotFound($event, $this->notFoundPage, []); } catch (TwigErrorLoader $e) { // Template not found, fall though to see if we can render a // record, failing that let the exception handler take over } } // Next try for referencing DB content. $content = $this->storage->getContent($this->notFoundPage, ['returnsingle' => true]); if (!$content instanceof Content || empty($content->id)) { return; } $template = $this->templateChooser->record($content); $this->renderNotFound($event, $template, $content->getTemplateContext()); }
/** * @covers \Bolt\Controller\Zone::get * @covers \Bolt\Controller\Zone::isBackend */ public function testControllerZone() { $app = $this->getApp(); $this->setRequest(Request::create('/bolt')); $request = $this->getRequest(); $kernel = $this->getMock('Symfony\\Component\\HttpKernel\\HttpKernelInterface'); $app['dispatcher']->dispatch(KernelEvents::REQUEST, new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST)); $this->assertEquals('backend', Zone::get($request)); $this->assertTrue(Zone::isBackend($request)); }
/** * Render the not found page if on frontend and http exception * * @param GetResponseForExceptionEvent $event */ public function onKernelException(GetResponseForExceptionEvent $event) { if (!$event->getException() instanceof HttpExceptionInterface || Zone::isBackend($event->getRequest())) { return; } $content = $this->storage->getContent($this->notFoundPage, ['returnsingle' => true]); if (!$content instanceof Content || empty($content->id)) { return; } $template = $this->templateChooser->record($content); $response = $this->render->render($template, $content->getTemplateContext()); $event->setResponse($response); }
/** * Handle errors thrown in the application. * * @param GetResponseForExceptionEvent $event */ public function onKernelException(GetResponseForExceptionEvent $event) { $exception = $event->getException(); // Log the error message $message = $exception->getMessage(); $this->logger->critical($message, ['event' => 'exception', 'exception' => $exception]); if ($exception instanceof HttpExceptionInterface && !Zone::isBackend($event->getRequest())) { $message = "The page could not be found, and there is no 'notfound' set in 'config.yml'. Sorry about that."; } $context = ['class' => get_class($exception), 'message' => $message, 'code' => $exception->getCode(), 'trace' => $this->getSafeTrace($exception)]; // Note: This uses the template from app/theme_defaults. Not app/view/twig. $response = $this->render->render('error.twig', ['context' => $context]); $event->setResponse($response); }
/** * Route for kernel exception handling. * * @param GetResponseForExceptionEvent $event * * @return Response */ public function kernelException(GetResponseForExceptionEvent $event) { if ($this->app === null) { throw new \RuntimeException('Exception controller being used outside of request cycle.'); } $exception = $event->getException(); $message = $exception->getMessage(); if ($exception instanceof HttpExceptionInterface && !Zone::isBackend($event->getRequest())) { $message = "The page could not be found, and there is no 'notfound' set in 'config.yml'. Sorry about that."; } $context = $this->getContextArray($exception); $context['type'] = 'general'; $context['message'] = $message; $html = $this->app['twig']->render('@bolt/exception/general.twig', $context); $response = new Response($html, Response::HTTP_OK); $response->headers->set('X-Debug-Exception-Handled', time()); return $response; }
/** * Render the not found page if on frontend and http exception * * @param GetResponseForExceptionEvent $event */ public function onKernelException(GetResponseForExceptionEvent $event) { if (!$event->getException() instanceof HttpExceptionInterface || Zone::isBackend($event->getRequest())) { return; } // If $notFoundPage is referencing a template, render it and be done. if ($this->render->hasTemplate($this->notFoundPage)) { $response = $this->render->render($this->notFoundPage); $event->setResponse($response); return; } // Next try for referencing DB content. $content = $this->storage->getContent($this->notFoundPage, ['returnsingle' => true]); if (!$content instanceof Content || empty($content->id)) { return; } $template = $this->templateChooser->record($content); $response = $this->render->render($template, [], $content->getTemplateContext()); $event->setResponse($response); }
public function onRequest(GetResponseEvent $event) { if (!Zone::isBackend($event->getRequest())) { return; } foreach ($this->config->getRolesAdmin() as $role) { if ($this->users->isAllowed($role)) { return; } } throw new AccessDeniedException('Logged in user does not have the correct rights to use this class.'); }
/** * Parse textquery into useable arguments. * * This is tightly coupled to $this->getContent() * * @see $this->decodeContentQuery() * * @param $textquery * @param array $decoded a pre-set decoded array to fill * @param array $metaParameters meta parameters * @param array $ctypeParameters contenttype parameters */ private function parseTextQuery($textquery, array &$decoded, array &$metaParameters, array &$ctypeParameters) { // Our default callback $decoded['queries_callback'] = [$this, 'executeGetContentQueries']; // Some special cases, like 'entry/1' or 'page/about' need to be caught before further processing. if (preg_match('#^/?([a-z0-9_-]+)/([0-9]+)$#i', $textquery, $match)) { // like 'entry/12' or '/page/12345' $decoded['contenttypes'] = $this->decodeContentTypesFromText($match[1]); $decoded['return_single'] = true; // if allow_numeric_slug option is set on contenttype, interpret number as slug instead of id $contenttype = $this->getContentType($decoded['contenttypes'][0]); $field = $contenttype['allow_numeric_slugs'] === true ? 'slug' : 'id'; $ctypeParameters[$field] = $match[2]; } elseif (preg_match('#^/?([a-z0-9_(\\),-]+)/search(/([0-9]+))?$#i', $textquery, $match)) { // like 'page/search or '(entry,page)/search' $decoded['contenttypes'] = $this->decodeContentTypesFromText($match[1]); $metaParameters['order'] = [$this, 'compareSearchWeights']; if (count($match) >= 3) { $metaParameters['limit'] = $match[3]; } $decoded['queries_callback'] = [$this, 'executeGetContentSearch']; } elseif (preg_match('#^/?([a-z0-9_-]+)/([a-z0-9_-]+)$#i', $textquery, $match)) { // like 'page/lorem-ipsum-dolor' or '/page/home' $decoded['contenttypes'] = $this->decodeContentTypesFromText($match[1]); $decoded['return_single'] = true; $ctypeParameters['slug'] = $match[2]; } elseif (preg_match('#^/?([a-z0-9_-]+)/(latest|first)/([0-9]+)$#i', $textquery, $match)) { // like 'page/latest/5' $decoded['contenttypes'] = $this->decodeContentTypesFromText($match[1]); if (!isset($metaParameters['order']) || $metaParameters['order'] === false) { $metaParameters['order'] = 'datepublish ' . ($match[2] == 'latest' ? 'DESC' : 'ASC'); } if (!isset($metaParameters['limit'])) { $metaParameters['limit'] = $match[3]; } } elseif (preg_match('#^/?([a-z0-9_-]+)/random/([0-9]+)$#i', $textquery, $match)) { // like 'page/random/4' $decoded['contenttypes'] = $this->decodeContentTypesFromText($match[1]); $dboptions = $this->app['config']->get('general/database'); $metaParameters['order'] = $dboptions['randomfunction']; // 'RAND()' or 'RANDOM()' if (!isset($metaParameters['limit'])) { $metaParameters['limit'] = $match[2]; } } else { $decoded['contenttypes'] = $this->decodeContentTypesFromText($textquery); if (isset($ctypeParameters['id']) && is_numeric($ctypeParameters['id'])) { $decoded['return_single'] = true; } } // When using from the frontend, we assume (by default) that we only want published items, // unless something else is specified explicitly $request = $this->app['request_stack']->getCurrentRequest(); $isBackend = $request ? Zone::isBackend($request) : false; if (!$isBackend && empty($ctypeParameters['status'])) { $ctypeParameters['status'] = 'published'; } if (isset($metaParameters['returnsingle'])) { $decoded['return_single'] = $metaParameters['returnsingle']; unset($metaParameters['returnsingle']); } }