diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Controller/ViewsUIController.php b/core/modules/views_ui/lib/Drupal/views_ui/Controller/ViewsUIController.php index c9887f9..c5ebad1 100644 --- a/core/modules/views_ui/lib/Drupal/views_ui/Controller/ViewsUIController.php +++ b/core/modules/views_ui/lib/Drupal/views_ui/Controller/ViewsUIController.php @@ -21,6 +21,8 @@ use Symfony\Component\HttpFoundation\RedirectResponse; use Drupal\Core\Ajax\AjaxResponse; use Drupal\Core\Ajax\ReplaceCommand; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; /** * Returns responses for Views UI routes. @@ -49,6 +51,13 @@ class ViewsUIController implements ControllerInterface { protected $tempStore; /** + * The URL generator to use. + * + * @var \Symfony\Component\Routing\Generator\UrlGeneratorInterface + */ + protected $urlGenerator; + + /** * Constructs a new \Drupal\views_ui\Controller\ViewsUIController object. * * @param \Drupal\Core\Entity\EntityManager $entity_manager @@ -57,11 +66,14 @@ class ViewsUIController implements ControllerInterface { * The Views data cache object. * @param \Drupal\user\TempStoreFactory $temp_store_factory * The factory for the temp store object. + * @param \Symfony\Component\Routing\Generator\UrlGeneratorInterface + * The URL generator. */ - public function __construct(EntityManager $entity_manager, ViewsData $views_data, TempStoreFactory $temp_store_factory) { + public function __construct(EntityManager $entity_manager, ViewsData $views_data, TempStoreFactory $temp_store_factory, UrlGeneratorInterface $url_generator) { $this->entityManager = $entity_manager; $this->viewsData = $views_data; $this->tempStore = $temp_store_factory->get('views'); + $this->urlGenerator = $url_generator; } /** @@ -71,7 +83,8 @@ public static function create(ContainerInterface $container) { return new static( $container->get('plugin.manager.entity'), $container->get('views.views_data'), - $container->get('user.tempstore') + $container->get('user.tempstore'), + $container->get('url_generator') ); } @@ -164,12 +177,21 @@ public function reportPlugins() { * The view being acted upon. * @param string $op * The operation to perform, e.g., 'enable' or 'disable'. + * @param \Symfony\Component\HttpFoundation\Request $request + * The current request. * * @return \Drupal\Core\Ajax\AjaxResponse|\Symfony\Component\HttpFoundation\RedirectResponse * Either returns a rebuilt listing page as an AJAX response, or redirects * back to the listing page. + * + * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException */ public function ajaxOperation(ViewStorageInterface $view, $op, Request $request) { + if (!drupal_valid_token($request->query->get('token'), $op)) { + // Throw an access denied exception if the token is invalid or missing. + throw new AccessDeniedHttpException(); + } + // Perform the operation. $view->$op()->save(); @@ -182,8 +204,7 @@ public function ajaxOperation(ViewStorageInterface $view, $op, Request $request) } // Otherwise, redirect back to the page. - // @todo Remove url() wrapper once http://drupal.org/node/1668866 is in. - return new RedirectResponse(url('admin/structure/views', array('absolute' => TRUE))); + return new RedirectResponse($this->urlGenerator->generate('views_ui.list')); } /** diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Tests/DefaultViewsTest.php b/core/modules/views_ui/lib/Drupal/views_ui/Tests/DefaultViewsTest.php index f25e865..ed147ab 100644 --- a/core/modules/views_ui/lib/Drupal/views_ui/Tests/DefaultViewsTest.php +++ b/core/modules/views_ui/lib/Drupal/views_ui/Tests/DefaultViewsTest.php @@ -155,6 +155,10 @@ function testSplitListing() { $arguments[':status'] = 'views-list-section enabled'; $elements = $this->xpath($xpath, $arguments); $this->assertIdentical(count($elements), 1, 'After enabling a view, it is found in the enabled views table.'); + + // Attempt to disable the view by path directly, with no token. + $this->drupalGet('admin/structure/views/view/test_view_status/disable'); + $this->assertResponse(403); } /** diff --git a/core/modules/views_ui/lib/Drupal/views_ui/ViewListController.php b/core/modules/views_ui/lib/Drupal/views_ui/ViewListController.php index 909aad0..756361f 100644 --- a/core/modules/views_ui/lib/Drupal/views_ui/ViewListController.php +++ b/core/modules/views_ui/lib/Drupal/views_ui/ViewListController.php @@ -151,6 +151,7 @@ public function getOperations(EntityInterface $entity) { foreach (array('enable', 'disable') as $op) { if (isset($operations[$op])) { $operations[$op]['ajax'] = TRUE; + $operations[$op]['query']['token'] = drupal_get_token($op); } }