diff --git a/composer.lock b/composer.lock
index 3dfa8906c414ebdfc848a1985ce70891bd38d82e..84b33dbd027bbe62af59600038af37270b091722 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,6 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "hash": "7d101b08e5ae002d827cd42ae9a4e344",
"content-hash": "60f7057617c6d995bf9946d0b12f0b5d",
"packages": [
{
@@ -48,7 +47,7 @@
"cors",
"stack"
],
- "time": "2016-08-01 12:05:04"
+ "time": "2016-08-01T12:05:04+00:00"
},
{
"name": "composer/installers",
@@ -143,7 +142,7 @@
"zend",
"zikula"
],
- "time": "2015-02-18 17:17:01"
+ "time": "2015-02-18T17:17:01+00:00"
},
{
"name": "composer/semver",
@@ -204,7 +203,7 @@
"validation",
"versioning"
],
- "time": "2015-09-21 09:42:36"
+ "time": "2015-09-21T09:42:36+00:00"
},
{
"name": "doctrine/annotations",
@@ -272,7 +271,7 @@
"docblock",
"parser"
],
- "time": "2015-08-31 12:32:49"
+ "time": "2015-08-31T12:32:49+00:00"
},
{
"name": "doctrine/cache",
@@ -342,7 +341,7 @@
"cache",
"caching"
],
- "time": "2015-08-31 12:36:41"
+ "time": "2015-08-31T12:36:41+00:00"
},
{
"name": "doctrine/collections",
@@ -408,7 +407,7 @@
"collections",
"iterator"
],
- "time": "2015-04-14 22:21:58"
+ "time": "2015-04-14T22:21:58+00:00"
},
{
"name": "doctrine/common",
@@ -481,7 +480,7 @@
"persistence",
"spl"
],
- "time": "2015-08-31 13:00:22"
+ "time": "2015-08-31T13:00:22+00:00"
},
{
"name": "doctrine/inflector",
@@ -548,7 +547,7 @@
"singularize",
"string"
],
- "time": "2014-12-20 21:24:13"
+ "time": "2014-12-20T21:24:13+00:00"
},
{
"name": "doctrine/lexer",
@@ -602,7 +601,7 @@
"lexer",
"parser"
],
- "time": "2014-09-09 13:34:57"
+ "time": "2014-09-09T13:34:57+00:00"
},
{
"name": "easyrdf/easyrdf",
@@ -664,7 +663,7 @@
"rdfa",
"sparql"
],
- "time": "2015-02-27 09:45:49"
+ "time": "2015-02-27T09:45:49+00:00"
},
{
"name": "egulias/email-validator",
@@ -717,7 +716,7 @@
"validation",
"validator"
],
- "time": "2015-06-22 21:07:51"
+ "time": "2015-06-22T21:07:51+00:00"
},
{
"name": "guzzlehttp/guzzle",
@@ -779,7 +778,7 @@
"rest",
"web service"
],
- "time": "2016-07-15 17:22:37"
+ "time": "2016-07-15T17:22:37+00:00"
},
{
"name": "guzzlehttp/promises",
@@ -830,7 +829,7 @@
"keywords": [
"promise"
],
- "time": "2016-05-18 16:56:05"
+ "time": "2016-05-18T16:56:05+00:00"
},
{
"name": "guzzlehttp/psr7",
@@ -888,7 +887,7 @@
"stream",
"uri"
],
- "time": "2016-06-24 23:00:38"
+ "time": "2016-06-24T23:00:38+00:00"
},
{
"name": "ircmaxell/password-compat",
@@ -930,7 +929,7 @@
"hashing",
"password"
],
- "time": "2014-11-20 16:49:30"
+ "time": "2014-11-20T16:49:30+00:00"
},
{
"name": "masterminds/html5",
@@ -995,7 +994,7 @@
"serializer",
"xml"
],
- "time": "2016-05-10 14:11:45"
+ "time": "2016-05-10T14:11:45+00:00"
},
{
"name": "paragonie/random_compat",
@@ -1043,7 +1042,7 @@
"pseudorandom",
"random"
],
- "time": "2015-12-01 02:52:15"
+ "time": "2015-12-01T02:52:15+00:00"
},
{
"name": "psr/http-message",
@@ -1092,7 +1091,7 @@
"request",
"response"
],
- "time": "2015-05-04 20:22:00"
+ "time": "2015-05-04T20:22:00+00:00"
},
{
"name": "psr/log",
@@ -1130,7 +1129,7 @@
"psr",
"psr-3"
],
- "time": "2012-12-21 11:40:51"
+ "time": "2012-12-21T11:40:51+00:00"
},
{
"name": "stack/builder",
@@ -1179,7 +1178,7 @@
"keywords": [
"stack"
],
- "time": "2016-06-02 06:58:42"
+ "time": "2016-06-02T06:58:42+00:00"
},
{
"name": "symfony-cmf/routing",
@@ -1238,7 +1237,7 @@
"database",
"routing"
],
- "time": "2016-03-31 09:11:39"
+ "time": "2016-03-31T09:11:39+00:00"
},
{
"name": "symfony/class-loader",
@@ -1291,7 +1290,7 @@
],
"description": "Symfony ClassLoader Component",
"homepage": "https://symfony.com",
- "time": "2017-01-10 14:03:07"
+ "time": "2017-01-10T14:03:07+00:00"
},
{
"name": "symfony/console",
@@ -1352,7 +1351,7 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
- "time": "2017-01-08 20:43:03"
+ "time": "2017-01-08T20:43:03+00:00"
},
{
"name": "symfony/debug",
@@ -1409,7 +1408,7 @@
],
"description": "Symfony Debug Component",
"homepage": "https://symfony.com",
- "time": "2017-01-02 20:30:24"
+ "time": "2017-01-02T20:30:24+00:00"
},
{
"name": "symfony/dependency-injection",
@@ -1472,7 +1471,7 @@
],
"description": "Symfony DependencyInjection Component",
"homepage": "https://symfony.com",
- "time": "2017-01-10 14:27:01"
+ "time": "2017-01-10T14:27:01+00:00"
},
{
"name": "symfony/event-dispatcher",
@@ -1532,7 +1531,7 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
- "time": "2017-01-02 20:30:24"
+ "time": "2017-01-02T20:30:24+00:00"
},
{
"name": "symfony/http-foundation",
@@ -1587,7 +1586,7 @@
],
"description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com",
- "time": "2017-01-08 20:43:03"
+ "time": "2017-01-08T20:43:03+00:00"
},
{
"name": "symfony/http-kernel",
@@ -1669,7 +1668,7 @@
],
"description": "Symfony HttpKernel Component",
"homepage": "https://symfony.com",
- "time": "2017-01-12 20:27:24"
+ "time": "2017-01-12T20:27:24+00:00"
},
{
"name": "symfony/polyfill-apcu",
@@ -1722,7 +1721,7 @@
"portable",
"shim"
],
- "time": "2016-11-14 01:06:16"
+ "time": "2016-11-14T01:06:16+00:00"
},
{
"name": "symfony/polyfill-iconv",
@@ -1781,7 +1780,7 @@
"portable",
"shim"
],
- "time": "2016-11-14 01:06:16"
+ "time": "2016-11-14T01:06:16+00:00"
},
{
"name": "symfony/polyfill-mbstring",
@@ -1840,7 +1839,7 @@
"portable",
"shim"
],
- "time": "2016-11-14 01:06:16"
+ "time": "2016-11-14T01:06:16+00:00"
},
{
"name": "symfony/polyfill-php54",
@@ -1898,7 +1897,7 @@
"portable",
"shim"
],
- "time": "2016-11-14 01:06:16"
+ "time": "2016-11-14T01:06:16+00:00"
},
{
"name": "symfony/polyfill-php55",
@@ -1954,7 +1953,7 @@
"portable",
"shim"
],
- "time": "2016-11-14 01:06:16"
+ "time": "2016-11-14T01:06:16+00:00"
},
{
"name": "symfony/process",
@@ -2003,7 +2002,7 @@
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
- "time": "2017-01-02 20:30:24"
+ "time": "2017-01-02T20:30:24+00:00"
},
{
"name": "symfony/psr-http-message-bridge",
@@ -2057,7 +2056,7 @@
"http-message",
"psr-7"
],
- "time": "2015-05-29 17:57:12"
+ "time": "2015-05-29T17:57:12+00:00"
},
{
"name": "symfony/routing",
@@ -2132,7 +2131,7 @@
"uri",
"url"
],
- "time": "2017-01-02 20:30:24"
+ "time": "2017-01-02T20:30:24+00:00"
},
{
"name": "symfony/serializer",
@@ -2196,7 +2195,7 @@
],
"description": "Symfony Serializer Component",
"homepage": "https://symfony.com",
- "time": "2017-01-02 20:30:24"
+ "time": "2017-01-02T20:30:24+00:00"
},
{
"name": "symfony/translation",
@@ -2260,7 +2259,7 @@
],
"description": "Symfony Translation Component",
"homepage": "https://symfony.com",
- "time": "2017-01-02 20:30:24"
+ "time": "2017-01-02T20:30:24+00:00"
},
{
"name": "symfony/validator",
@@ -2333,7 +2332,7 @@
],
"description": "Symfony Validator Component",
"homepage": "https://symfony.com",
- "time": "2017-01-12 19:24:25"
+ "time": "2017-01-12T19:24:25+00:00"
},
{
"name": "symfony/yaml",
@@ -2382,7 +2381,7 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
- "time": "2017-01-03 13:49:52"
+ "time": "2017-01-03T13:49:52+00:00"
},
{
"name": "twig/twig",
@@ -2443,7 +2442,7 @@
"keywords": [
"templating"
],
- "time": "2016-01-25 21:22:18"
+ "time": "2016-01-25T21:22:18+00:00"
},
{
"name": "wikimedia/composer-merge-plugin",
@@ -2492,7 +2491,7 @@
}
],
"description": "Composer plugin to merge multiple composer.json files",
- "time": "2016-03-08 17:11:37"
+ "time": "2016-03-08T17:11:37+00:00"
},
{
"name": "zendframework/zend-diactoros",
@@ -2542,7 +2541,7 @@
"psr",
"psr-7"
],
- "time": "2015-08-10 20:04:20"
+ "time": "2015-08-10T20:04:20+00:00"
},
{
"name": "zendframework/zend-escaper",
@@ -2586,7 +2585,7 @@
"escaper",
"zf2"
],
- "time": "2015-06-03 14:05:37"
+ "time": "2015-06-03T14:05:37+00:00"
},
{
"name": "zendframework/zend-feed",
@@ -2645,7 +2644,7 @@
"feed",
"zf2"
],
- "time": "2015-08-04 21:39:18"
+ "time": "2015-08-04T21:39:18+00:00"
},
{
"name": "zendframework/zend-hydrator",
@@ -2701,7 +2700,7 @@
"hydrator",
"zf2"
],
- "time": "2015-09-17 14:06:43"
+ "time": "2015-09-17T14:06:43+00:00"
},
{
"name": "zendframework/zend-stdlib",
@@ -2759,7 +2758,7 @@
"stdlib",
"zf2"
],
- "time": "2015-09-25 04:06:33"
+ "time": "2015-09-25T04:06:33+00:00"
}
],
"packages-dev": [
@@ -2819,7 +2818,7 @@
"testing",
"web"
],
- "time": "2016-03-05 08:26:18"
+ "time": "2016-03-05T08:26:18+00:00"
},
{
"name": "behat/mink-browserkit-driver",
@@ -2875,7 +2874,7 @@
"browser",
"testing"
],
- "time": "2016-03-05 08:59:47"
+ "time": "2016-03-05T08:59:47+00:00"
},
{
"name": "behat/mink-goutte-driver",
@@ -2930,7 +2929,7 @@
"headless",
"testing"
],
- "time": "2016-03-05 09:04:22"
+ "time": "2016-03-05T09:04:22+00:00"
},
{
"name": "doctrine/instantiator",
@@ -2984,7 +2983,7 @@
"constructor",
"instantiate"
],
- "time": "2015-06-14 21:17:01"
+ "time": "2015-06-14T21:17:01+00:00"
},
{
"name": "fabpot/goutte",
@@ -3033,7 +3032,7 @@
"keywords": [
"scraper"
],
- "time": "2015-11-05 12:58:44"
+ "time": "2015-11-05T12:58:44+00:00"
},
{
"name": "jcalderonzumba/gastonjs",
@@ -3090,7 +3089,7 @@
"headless",
"phantomjs"
],
- "time": "2016-01-18 09:21:03"
+ "time": "2016-01-18T09:21:03+00:00"
},
{
"name": "jcalderonzumba/mink-phantomjs-driver",
@@ -3151,7 +3150,7 @@
"phantomjs",
"testing"
],
- "time": "2015-12-04 13:55:02"
+ "time": "2015-12-04T13:55:02+00:00"
},
{
"name": "mikey179/vfsStream",
@@ -3197,7 +3196,7 @@
],
"description": "Virtual file system to mock the real file system in unit tests.",
"homepage": "http://vfs.bovigo.org/",
- "time": "2015-10-06 16:59:57"
+ "time": "2015-10-06T16:59:57+00:00"
},
{
"name": "phpdocumentor/reflection-docblock",
@@ -3246,7 +3245,7 @@
"email": "mike.vanriel@naenius.com"
}
],
- "time": "2015-02-03 12:10:50"
+ "time": "2015-02-03T12:10:50+00:00"
},
{
"name": "phpspec/prophecy",
@@ -3306,7 +3305,7 @@
"spy",
"stub"
],
- "time": "2015-08-13 10:07:40"
+ "time": "2015-08-13T10:07:40+00:00"
},
{
"name": "phpunit/php-code-coverage",
@@ -3368,7 +3367,7 @@
"testing",
"xunit"
],
- "time": "2015-10-06 15:47:00"
+ "time": "2015-10-06T15:47:00+00:00"
},
{
"name": "phpunit/php-file-iterator",
@@ -3415,7 +3414,7 @@
"filesystem",
"iterator"
],
- "time": "2015-06-21 13:08:43"
+ "time": "2015-06-21T13:08:43+00:00"
},
{
"name": "phpunit/php-text-template",
@@ -3456,7 +3455,7 @@
"keywords": [
"template"
],
- "time": "2015-06-21 13:50:34"
+ "time": "2015-06-21T13:50:34+00:00"
},
{
"name": "phpunit/php-timer",
@@ -3497,7 +3496,7 @@
"keywords": [
"timer"
],
- "time": "2015-06-21 08:01:12"
+ "time": "2015-06-21T08:01:12+00:00"
},
{
"name": "phpunit/php-token-stream",
@@ -3546,20 +3545,20 @@
"keywords": [
"tokenizer"
],
- "time": "2015-09-15 10:49:45"
+ "time": "2015-09-15T10:49:45+00:00"
},
{
"name": "phpunit/phpunit",
- "version": "4.8.27",
+ "version": "4.8.28",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "c062dddcb68e44b563f66ee319ddae2b5a322a90"
+ "reference": "558a3a0d28b4cb7e4a593a4fbd2220e787076225"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c062dddcb68e44b563f66ee319ddae2b5a322a90",
- "reference": "c062dddcb68e44b563f66ee319ddae2b5a322a90",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/558a3a0d28b4cb7e4a593a4fbd2220e787076225",
+ "reference": "558a3a0d28b4cb7e4a593a4fbd2220e787076225",
"shasum": ""
},
"require": {
@@ -3618,7 +3617,7 @@
"testing",
"xunit"
],
- "time": "2016-07-21 06:48:14"
+ "time": "2016-11-14T06:25:28+00:00"
},
{
"name": "phpunit/phpunit-mock-objects",
@@ -3674,7 +3673,7 @@
"mock",
"xunit"
],
- "time": "2015-10-02 06:51:40"
+ "time": "2015-10-02T06:51:40+00:00"
},
{
"name": "sebastian/comparator",
@@ -3738,7 +3737,7 @@
"compare",
"equality"
],
- "time": "2015-07-26 15:48:44"
+ "time": "2015-07-26T15:48:44+00:00"
},
{
"name": "sebastian/diff",
@@ -3790,7 +3789,7 @@
"keywords": [
"diff"
],
- "time": "2015-02-22 15:13:53"
+ "time": "2015-02-22T15:13:53+00:00"
},
{
"name": "sebastian/environment",
@@ -3840,7 +3839,7 @@
"environment",
"hhvm"
],
- "time": "2015-08-03 06:14:51"
+ "time": "2015-08-03T06:14:51+00:00"
},
{
"name": "sebastian/exporter",
@@ -3906,7 +3905,7 @@
"export",
"exporter"
],
- "time": "2015-06-21 07:55:53"
+ "time": "2015-06-21T07:55:53+00:00"
},
{
"name": "sebastian/global-state",
@@ -3957,7 +3956,7 @@
"keywords": [
"global state"
],
- "time": "2014-10-06 09:23:50"
+ "time": "2014-10-06T09:23:50+00:00"
},
{
"name": "sebastian/recursion-context",
@@ -4010,7 +4009,7 @@
],
"description": "Provides functionality to recursively process PHP variables",
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
- "time": "2015-06-21 08:04:50"
+ "time": "2015-06-21T08:04:50+00:00"
},
{
"name": "sebastian/version",
@@ -4045,7 +4044,7 @@
],
"description": "Library that helps with managing the version number of Git-hosted PHP projects",
"homepage": "https://github.com/sebastianbergmann/version",
- "time": "2015-06-21 13:59:46"
+ "time": "2015-06-21T13:59:46+00:00"
},
{
"name": "symfony/browser-kit",
@@ -4102,7 +4101,7 @@
],
"description": "Symfony BrowserKit Component",
"homepage": "https://symfony.com",
- "time": "2017-01-02 20:30:24"
+ "time": "2017-01-02T20:30:24+00:00"
},
{
"name": "symfony/css-selector",
@@ -4155,7 +4154,7 @@
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
- "time": "2017-01-02 20:30:24"
+ "time": "2017-01-02T20:30:24+00:00"
},
{
"name": "symfony/dom-crawler",
@@ -4211,7 +4210,7 @@
],
"description": "Symfony DomCrawler Component",
"homepage": "https://symfony.com",
- "time": "2017-01-02 20:30:24"
+ "time": "2017-01-02T20:30:24+00:00"
}
],
"aliases": [],
diff --git a/core/composer.json b/core/composer.json
index b9a3fad8b077311ff669efea1c5369eda3d2a214..6782469d6df37224bfb7bddd4bb5f6b993042e59 100644
--- a/core/composer.json
+++ b/core/composer.json
@@ -40,7 +40,7 @@
"jcalderonzumba/gastonjs": "~1.0.2",
"jcalderonzumba/mink-phantomjs-driver": "~0.3.1",
"mikey179/vfsStream": "~1.2",
- "phpunit/phpunit": "~4.8",
+ "phpunit/phpunit": ">=4.8.28 <5",
"symfony/css-selector": "~2.8"
},
"replace": {
diff --git a/core/modules/editor/editor.module b/core/modules/editor/editor.module
index 010177974405a17f28308318969acce97c570b56..f48c51b80fd2c0b34d18b661ac99ff112c5b3d4a 100644
--- a/core/modules/editor/editor.module
+++ b/core/modules/editor/editor.module
@@ -519,8 +519,8 @@ function editor_file_download($uri) {
if ($file->isPermanent()) {
$referencing_entity_is_accessible = FALSE;
$references = empty($usage_list['editor']) ? [] : $usage_list['editor'];
- foreach ($references as $entity_type => $entity_ids) {
- $referencing_entities = entity_load_multiple($entity_type, $entity_ids);
+ foreach ($references as $entity_type => $entity_ids_usage_count) {
+ $referencing_entities = entity_load_multiple($entity_type, array_keys($entity_ids_usage_count));
/** @var \Drupal\Core\Entity\EntityInterface $referencing_entity */
foreach ($referencing_entities as $referencing_entity) {
if ($referencing_entity->access('view', NULL, TRUE)->isAllowed()) {
diff --git a/core/modules/editor/src/Tests/EditorPrivateFileReferenceFilterTest.php b/core/modules/editor/src/Tests/EditorPrivateFileReferenceFilterTest.php
index 5f689b3f0d1759d9023efebc76481adc3d0b908c..354ceede0b35a1b76b5ca736fe8fb3e448fb9617 100644
--- a/core/modules/editor/src/Tests/EditorPrivateFileReferenceFilterTest.php
+++ b/core/modules/editor/src/Tests/EditorPrivateFileReferenceFilterTest.php
@@ -68,9 +68,18 @@ function testEditorPrivateFileReferenceFilter() {
$file->setPermanent();
$file->save();
+ // Create some nodes to ensure file usage count does not match the ID's
+ // of the nodes we are going to check.
+ for ($i = 0; $i < 5; $i++) {
+ $this->drupalCreateNode([
+ 'type' => 'page',
+ 'uid' => $author->id(),
+ ]);
+ }
+
// Create a node with its body field properly pointing to the just-created
// file.
- $node = $this->drupalCreateNode([
+ $published_node = $this->drupalCreateNode([
'type' => 'page',
'body' => [
'value' => '',
@@ -79,19 +88,44 @@ function testEditorPrivateFileReferenceFilter() {
'uid' => $author->id(),
]);
+ // Create an unpublished node with its body field properly pointing to the
+ // just-created file.
+ $unpublished_node = $this->drupalCreateNode([
+ 'type' => 'page',
+ 'status' => NODE_NOT_PUBLISHED,
+ 'body' => [
+ 'value' => '',
+ 'format' => 'private_images',
+ ],
+ 'uid' => $author->id(),
+ ]);
+
// Do the actual test. The image should be visible for anonymous users,
- // because they can view the referencing entity.
- $this->drupalGet($node->toUrl());
+ // because they can view the published node. Even though they can't view
+ // the unpublished node.
+ $this->drupalGet($published_node->toUrl());
$this->assertSession()->statusCodeEquals(200);
+ $this->drupalGet($unpublished_node->toUrl());
+ $this->assertSession()->statusCodeEquals(403);
$this->drupalGet($src);
$this->assertSession()->statusCodeEquals(200);
+ // When the published node is also unpublished, the image should also
+ // become inaccessible to anonymous users.
+ $published_node->setPublished(FALSE)->save();
+
+ $this->drupalGet($published_node->toUrl());
+ $this->assertSession()->statusCodeEquals(403);
+ $this->drupalGet($src);
+ $this->assertSession()->statusCodeEquals(403);
+
// Disallow anonymous users to view the entity, which then should also
// disallow them to view the image.
+ $published_node->setPublished(TRUE)->save();
Role::load(RoleInterface::ANONYMOUS_ID)
->revokePermission('access content')
->save();
- $this->drupalGet($node->toUrl());
+ $this->drupalGet($published_node->toUrl());
$this->assertSession()->statusCodeEquals(403);
$this->drupalGet($src);
$this->assertSession()->statusCodeEquals(403);
diff --git a/core/modules/search/search.routing.yml b/core/modules/search/search.routing.yml
index ec273f166882e00e6f159d77c33482b74ecc4b5d..98969a6e21c7fa4bc0e71531560aceba79de3f7f 100644
--- a/core/modules/search/search.routing.yml
+++ b/core/modules/search/search.routing.yml
@@ -37,6 +37,7 @@ entity.search_page.enable:
op: 'enable'
requirements:
_entity_access: 'search_page.update'
+ _csrf_token: 'TRUE'
entity.search_page.disable:
path: '/admin/config/search/pages/manage/{search_page}/disable'
@@ -45,6 +46,7 @@ entity.search_page.disable:
op: 'disable'
requirements:
_entity_access: 'search_page.disable'
+ _csrf_token: 'TRUE'
entity.search_page.set_default:
path: '/admin/config/search/pages/manage/{search_page}/set-default'
@@ -52,6 +54,7 @@ entity.search_page.set_default:
_controller: '\Drupal\search\Controller\SearchController::setAsDefault'
requirements:
_entity_access: 'search_page.update'
+ _csrf_token: 'TRUE'
entity.search_page.delete_form:
path: '/admin/config/search/pages/manage/{search_page}/delete'
diff --git a/core/modules/search/src/Form/SearchBlockForm.php b/core/modules/search/src/Form/SearchBlockForm.php
index cd198fd7944df4e5c2396695c620f1ca6b792030..0e623a8778757a779d81e44f24b2dc7b20857d78 100644
--- a/core/modules/search/src/Form/SearchBlockForm.php
+++ b/core/modules/search/src/Form/SearchBlockForm.php
@@ -75,6 +75,16 @@ public function getFormId() {
public function buildForm(array $form, FormStateInterface $form_state) {
// Set up the form to submit using GET to the correct search page.
$entity_id = $this->searchPageRepository->getDefaultSearchPage();
+
+ $form = [];
+
+ // SearchPageRepository::getDefaultSearchPage() depends on search.settings.
+ // The dependency needs to be added before the conditional return, otherwise
+ // the block would get cached without the necessary cacheablity metadata in
+ // case there is no default search page and would not be invalidated if that
+ // changes.
+ $this->renderer->addCacheableDependency($form, $this->configFactory->get('search.settings'));
+
if (!$entity_id) {
$form['message'] = array(
'#markup' => $this->t('Search is currently disabled'),
@@ -103,9 +113,6 @@ public function buildForm(array $form, FormStateInterface $form_state) {
'#name' => '',
);
- // SearchPageRepository::getDefaultSearchPage() depends on search.settings.
- $this->renderer->addCacheableDependency($form, $this->configFactory->get('search.settings'));
-
return $form;
}
diff --git a/core/modules/search/src/Tests/SearchConfigSettingsFormTest.php b/core/modules/search/src/Tests/SearchConfigSettingsFormTest.php
index 9ca87d61987f40ef15fa4a9013c231bd6fe82083..fe93f90687c464c273a72659b40be53dc8a36909 100644
--- a/core/modules/search/src/Tests/SearchConfigSettingsFormTest.php
+++ b/core/modules/search/src/Tests/SearchConfigSettingsFormTest.php
@@ -154,8 +154,7 @@ function testSearchModuleDisabling() {
// Test each plugin if it's enabled as the only search plugin.
foreach ($entities as $entity_id => $entity) {
- // Set this as default.
- $this->drupalGet("admin/config/search/pages/manage/$entity_id/set-default");
+ $this->setDefaultThroughUi($entity_id);
// Run a search from the correct search URL.
$info = $plugin_info[$entity_id];
@@ -187,13 +186,16 @@ function testSearchModuleDisabling() {
$entity->disable()->save();
}
+ // Set the node search as default.
+ $this->setDefaultThroughUi('node_search');
+
// Test with all search plugins enabled. When you go to the search
// page or run search, all plugins should be shown.
foreach ($entities as $entity) {
$entity->enable()->save();
}
- // Set the node search as default.
- $this->drupalGet('admin/config/search/pages/manage/node_search/set-default');
+
+ \Drupal::service('router.builder')->rebuild();
$paths = array(
array('path' => 'search/node', 'options' => array('query' => array('keys' => 'pizza'))),
@@ -316,6 +318,19 @@ public function testMultipleSearchPages() {
$this->verifySearchPageOperations($first_id, FALSE, FALSE, FALSE, FALSE);
}
+ /**
+ * Tests that the enable/disable/default routes are protected from CSRF.
+ */
+ public function testRouteProtection() {
+ // Ensure that the enable and disable routes are protected.
+ $this->drupalGet('admin/config/search/pages/manage/node_search/enable');
+ $this->assertResponse(403);
+ $this->drupalGet('admin/config/search/pages/manage/node_search/disable');
+ $this->assertResponse(403);
+ $this->drupalGet('admin/config/search/pages/manage/node_search/set-default');
+ $this->assertResponse(403);
+ }
+
/**
* Checks that the search page operations match expectations.
*
@@ -373,4 +388,17 @@ protected function assertDefaultSearch($expected, $message = '', $group = 'Other
$this->assertIdentical($search_page_repository->getDefaultSearchPage(), $expected, $message, $group);
}
+ /**
+ * Sets a search page as the default in the UI.
+ *
+ * @param string $entity_id
+ * The search page entity ID to enable.
+ */
+ protected function setDefaultThroughUi($entity_id) {
+ $this->drupalGet('admin/config/search/pages');
+ preg_match('|href="([^"]+' . $entity_id . '/set-default[^"]+)"|', $this->getRawContent(), $matches);
+
+ $this->drupalGet($this->getAbsoluteUrl($matches[1]));
+ }
+
}
diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php
index f54dcf79e71ff52321f69f13352e4ca639fa780e..547de13a417746b74d42c63349e981e6cb25f383 100644
--- a/core/modules/simpletest/src/WebTestBase.php
+++ b/core/modules/simpletest/src/WebTestBase.php
@@ -1301,7 +1301,7 @@ protected function drupalGet($path, array $options = array(), array $headers = a
}
if ($path instanceof Url) {
- $path = $path->toString();
+ $path = $path->setAbsolute()->toString(TRUE)->getGeneratedUrl();
}
$verbose = 'GET request to: ' . $path .
@@ -2588,7 +2588,7 @@ protected function buildUrl($path, array $options = array()) {
$url_options = $path->getOptions();
$options = $url_options + $options;
$path->setOptions($options);
- return $path->setAbsolute()->toString();
+ return $path->setAbsolute()->toString(TRUE)->getGeneratedUrl();
}
// The URL generator service is not necessarily available yet; e.g., in
// interactive installer tests.