diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php index 557dfd1..3971134 100644 --- a/core/lib/Drupal/Core/DrupalKernel.php +++ b/core/lib/Drupal/Core/DrupalKernel.php @@ -912,9 +912,7 @@ protected function persistServices(ContainerInterface $container, array $persist } /** - * Force a container rebuild. - * - * @return \Symfony\Component\DependencyInjection\ContainerInterface + * {@inheritdoc} */ public function rebuildContainer() { // Empty module properties and for them to be reloaded from scratch. diff --git a/core/lib/Drupal/Core/DrupalKernelInterface.php b/core/lib/Drupal/Core/DrupalKernelInterface.php index ab17b77..e7da727 100644 --- a/core/lib/Drupal/Core/DrupalKernelInterface.php +++ b/core/lib/Drupal/Core/DrupalKernelInterface.php @@ -50,6 +50,14 @@ public function discoverServiceProviders(); public function getServiceProviders($origin); /** + * Force a container rebuild. + * + * @return \Symfony\Component\DependencyInjection\ContainerInterface + * The rebuilt container. + */ + public function rebuildContainer(); + + /** * Gets the current container. * * @return \Symfony\Component\DependencyInjection\ContainerInterface diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php index 2987411..770e93a 100644 --- a/core/modules/simpletest/src/WebTestBase.php +++ b/core/modules/simpletest/src/WebTestBase.php @@ -1496,7 +1496,7 @@ protected function isInChildSite() { * An array containing additional HTTP request headers, each formatted as * "name: value". * - * @return + * @return string * The retrieved HTML string, also available as $this->getRawContent() */ protected function drupalGet($path, array $options = array(), array $headers = array()) { diff --git a/core/modules/system/src/Tests/Session/SessionAuthenticationTest.php b/core/modules/system/src/Tests/Session/SessionAuthenticationTest.php index 121bc34..1462f4f 100644 --- a/core/modules/system/src/Tests/Session/SessionAuthenticationTest.php +++ b/core/modules/system/src/Tests/Session/SessionAuthenticationTest.php @@ -7,6 +7,8 @@ namespace Drupal\system\Tests\Session; +use Drupal\Component\Serialization\Yaml; +use Drupal\Core\DependencyInjection\YamlFileLoader; use Drupal\Core\Url; use Drupal\basic_auth\Tests\BasicAuthTestTrait; use Drupal\simpletest\WebTestBase; @@ -78,4 +80,103 @@ public function testSessionFromBasicAuthenticationDoesNotLeak() { $this->assertResponse(401, 'A subsequent request to the same route without basic authentication is not authorized.'); } + /** + * Tests logging in using basic authentication. + */ + public function testLoginWithBasicAuthCredentials() { + $this->basicAuthPostForm('', ['name' => $this->user->getUsername(), 'pass' => $this->user->pass_raw], t('Log in')); + // Basic auth is used for the login form, which results in a working + // authentication, so the access checking is denied. + $this->assertResponse(403); + + // Basic auth doesn't open up a session, so the user is not logged in. + $this->drupalGet($this->user->urlInfo()); + $this->assertResponse(403); + + // Let's send some basic_auth authentication headers, but that particular + // route does not have basic_auth authentications. + $this->basicAuthGet($this->user->urlInfo()); + $this->assertResponse(403); + + // Now change the default global authentication providers to also include + // cookie, which means that those routes don't need basic_auth as part of + // the router. + /** @var \Drupal\Core\DrupalKernelInterface $kernel */ + $kernel = \Drupal::service('kernel'); + $path = $kernel->getSitePath(); + $filepath = $path . '/services.yml'; + $data = Yaml::decode(file_get_contents($filepath)); + $data['services']['authentication'] = [ + 'class' => 'Drupal\Core\Authentication\AuthenticationManager', + 'arguments' => [['cookie' => TRUE, 'basic_auth' => TRUE]], + 'tags' => [ + [ + 'name' => 'service_collector', + 'tag' => 'authentication_provider', + 'call' => 'addProvider' + ] + ] + ]; + file_put_contents($filepath, Yaml::encode($data)); + YamlFileLoader::reset(); + $kernel->rebuildContainer(); + + $this->basicAuthGet($this->user->urlInfo()); + $this->assertResponse(200); + } + + /** + * Tests HTTP requests with basic authentication. + */ + public function testRequestWithBasicAuthCredentials() { + $result = $this->basicAuthGet('session-test/get-session'); + $this->assertResponse(200); + $data = json_decode($result); + $this->assertEqual([], $data->session); + $this->assertEqual($this->user->id(), $data->user); + } + + /** + * Executes a form submission. + * + * This uses the same format as WebTestBase::drupalPostForm(), but uses basic + * authentication. + * + * @param string $path + * Location of the post form. + * @param array $edit + * Field data in an associative array. + * @param string $submit + * Value of the submit button whose click is to be emulated. + * @param array $options + * Options to be forwarded to the url generator. + * @param string $form_html_id + * (optional) HTML ID of the form to be submitted. + * @param string $extra_post + * (optional) A string of additional data to append to the POST submission. + * + * @return string + * The retrieved HTML string. + * + * @see \Drupal\simpletest\WebTestBase::drupalPostForm() + */ + protected function basicAuthPostForm($path, $edit, $submit, array $options = array(), $form_html_id = NULL, $extra_post = NULL) { + return $this->drupalPostForm($path, $edit, $submit, $options, $this->getBasicAuthHeaders(), $form_html_id, $extra_post); + } + + /** + * Returns headers to use basic authentication in Curl. + * + * This uses the test user's credentials. + * + * @return array + * An array of raw request headers as used by curl_setopt(). + */ + protected function getBasicAuthHeaders() { + return [ + 'Accept: */*', + 'Authorization: Basic ' . base64_encode($this->user->getUsername() . ':' . $this->user->pass_raw), + ]; + } + } diff --git a/core/modules/system/tests/modules/session_test/session_test.routing.yml b/core/modules/system/tests/modules/session_test/session_test.routing.yml index 0cedf4f..b2ef74f 100644 --- a/core/modules/system/tests/modules/session_test/session_test.routing.yml +++ b/core/modules/system/tests/modules/session_test/session_test.routing.yml @@ -107,3 +107,15 @@ session_test.get_session_no_auth: _controller: '\Drupal\session_test\Controller\SessionTestController::getSession' requirements: _access: 'TRUE' + +session_test.set_session: + path: '/session-test/set-session/{test_value}' + defaults: + _title: 'Set a session value using basic authentication' + _controller: '\Drupal\session_test\Controller\SessionTestController::setSession' + options: + _auth: ['basic_auth'] + converters: + test_value: '\s+' + requirements: + _permission: 'administer site configuration' diff --git a/core/modules/system/tests/modules/session_test/src/Controller/SessionTestController.php b/core/modules/system/tests/modules/session_test/src/Controller/SessionTestController.php index 41fe7ed..e63cbee 100644 --- a/core/modules/system/tests/modules/session_test/src/Controller/SessionTestController.php +++ b/core/modules/system/tests/modules/session_test/src/Controller/SessionTestController.php @@ -175,4 +175,22 @@ public function getSession(Request $request) { return new JsonResponse(['session' => $request->getSession()->all(), 'user' => $this->currentUser()->id()]); } + /** + * Sets a test value on the session. + * + * @param \Symfony\Component\HttpFoundation\Request $request + * The request object. + * @param string $test_value + * A value to set on the session. + * + * @return \Symfony\Component\HttpFoundation\JsonResponse + * A response object containing the session values and the user ID. + */ + public function setSession(Request $request, $test_value) { + $session = $request->getSession(); + $session->set('test_value', $test_value); + $session->save(); + return new JsonResponse(['session' => $session->all(), 'user' => $this->currentUser()->id()]); + } + }