diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php index be9821d..eec36c9 100644 --- a/core/lib/Drupal/Core/DrupalKernel.php +++ b/core/lib/Drupal/Core/DrupalKernel.php @@ -896,9 +896,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..ca94511 100644 --- a/core/lib/Drupal/Core/DrupalKernelInterface.php +++ b/core/lib/Drupal/Core/DrupalKernelInterface.php @@ -50,6 +50,13 @@ public function discoverServiceProviders(); public function getServiceProviders($origin); /** + * Force a container rebuild. + * + * @return \Symfony\Component\DependencyInjection\ContainerInterface + */ + 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 c4f5cee..6726d77 100644 --- a/core/modules/simpletest/src/WebTestBase.php +++ b/core/modules/simpletest/src/WebTestBase.php @@ -1488,15 +1488,17 @@ protected function isInChildSite() { * @param $headers * An array containing additional HTTP request headers, each formatted as * "name: value". + * @param array $curl_options + * (optional) Additional curl options. * * @return * The retrieved HTML string, also available as $this->getRawContent() */ - protected function drupalGet($path, array $options = array(), array $headers = array()) { + protected function drupalGet($path, array $options = array(), array $headers = array(), array $curl_options = array()) { // We re-using a CURL connection here. If that connection still has certain // options set, it might change the GET into a POST. Make sure we clear out // previous options. - $out = $this->curlExec(array(CURLOPT_HTTPGET => TRUE, CURLOPT_URL => $this->buildUrl($path, $options), CURLOPT_NOBODY => FALSE, CURLOPT_HTTPHEADER => $headers)); + $out = $this->curlExec(array(CURLOPT_HTTPGET => TRUE, CURLOPT_URL => $this->buildUrl($path, $options), CURLOPT_NOBODY => FALSE, CURLOPT_HTTPHEADER => $headers) + $curl_options); // Ensure that any changes to variables in the other thread are picked up. $this->refreshVariables(); @@ -1636,8 +1638,10 @@ protected function drupalGetAJAX($path, array $options = array(), array $headers * is done by drupalPostAjaxForm(). This string is literally appended to the * POST data, so it must already be urlencoded and contain a leading "&" * (e.g., "&extra_var1=hello+world&extra_var2=you%26me"). + * @param array $curl_options + * (optional) Additional curl options. */ - protected function drupalPostForm($path, $edit, $submit, array $options = array(), array $headers = array(), $form_html_id = NULL, $extra_post = NULL) { + protected function drupalPostForm($path, $edit, $submit, array $options = array(), array $headers = array(), $form_html_id = NULL, $extra_post = NULL, $curl_options = []) { $submit_matches = FALSE; $ajax = is_array($submit); if (isset($path)) { @@ -1689,7 +1693,7 @@ protected function drupalPostForm($path, $edit, $submit, array $options = array( else { $post = $this->serializePostValues($post) . $extra_post; } - $out = $this->curlExec(array(CURLOPT_URL => $action, CURLOPT_POST => TRUE, CURLOPT_POSTFIELDS => $post, CURLOPT_HTTPHEADER => $headers)); + $out = $this->curlExec(array(CURLOPT_URL => $action, CURLOPT_POST => TRUE, CURLOPT_POSTFIELDS => $post, CURLOPT_HTTPHEADER => $headers) + $curl_options); // Ensure that any changes to variables in the other thread are picked // up. $this->refreshVariables(); @@ -1982,6 +1986,8 @@ protected function drupalProcessAjaxResponse($content, array $ajax_response, arr * @param array $options * (optional) Options to be forwarded to the url generator. The 'absolute' * option will automatically be enabled. + * @param array $curl_options + * (optional) Additional curl options. * * @return * The content returned from the call to curl_exec(). @@ -1989,7 +1995,7 @@ protected function drupalProcessAjaxResponse($content, array $ajax_response, arr * @see WebTestBase::getAjaxPageStatePostData() * @see WebTestBase::curlExec() */ - protected function drupalPost($path, $accept, array $post, $options = array()) { + protected function drupalPost($path, $accept, array $post, $options = array(), array $curl_options = array()) { return $this->curlExec(array( CURLOPT_URL => $this->buildUrl($path, $options), CURLOPT_POST => TRUE, @@ -1998,7 +2004,7 @@ protected function drupalPost($path, $accept, array $post, $options = array()) { 'Accept: ' . $accept, 'Content-Type: application/x-www-form-urlencoded', ), - )); + ) + $curl_options); } /** diff --git a/core/modules/system/src/Tests/Session/MultipleAuthenticationSessionTest.php b/core/modules/system/src/Tests/Session/MultipleAuthenticationSessionTest.php new file mode 100644 index 0000000..398ed2e --- /dev/null +++ b/core/modules/system/src/Tests/Session/MultipleAuthenticationSessionTest.php @@ -0,0 +1,90 @@ +drupalCreateUser(); + $this->drupalPostForm('', ['name' => $user->getUsername(), 'pass' => $user->pass_raw], t('Log in'), [], [], NULL, NULL, [ + CURLOPT_HTTPAUTH => CURLAUTH_BASIC, + CURLOPT_USERPWD => $user->getUsername() . ':' . $user->pass_raw, + ]); + // 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($user->urlInfo()); + $this->assertResponse(403); + + // Let's send some basic_auth authentication headers, but that particular + // route does not have basic_auth authentications. + $this->drupalGet($user->urlInfo(), [], [], [ + CURLOPT_HTTPAUTH => CURLAUTH_BASIC, + CURLOPT_USERPWD => $user->getUsername() . ':' . $user->pass_raw, + ]); + $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->drupalGet($user->urlInfo(), [], [], [ + CURLOPT_HTTPAUTH => CURLAUTH_BASIC, + CURLOPT_USERPWD => $user->getUsername() . ':' . $user->pass_raw, + ]); + $this->assertResponse(200); + } + + public function testRequestWithBasicAuthCredentials() { + $admin = $this->drupalCreateUser(['administer site configuration']); + $result = $this->drupalGet('session-test/get-session', [], [], [ + CURLOPT_HTTPAUTH => CURLAUTH_BASIC, + CURLOPT_USERPWD => $admin->getUsername() . ':' . $admin->pass_raw, + ]); + $this->assertResponse(200); + $data = json_decode($result); + $this->assertEqual([], $data->session); + $this->assertEqual($admin->id(), $data->user); + } + +} 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 8b9393e..c638efc 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 @@ -83,3 +83,13 @@ session_test.trace_handler: _controller: '\Drupal\session_test\Controller\SessionTestController::traceHandler' requirements: _access: 'TRUE' + + +session_test.get_session: + path: '/session-test/get-session' + defaults: + _controller: '\Drupal\session_test\Controller\SessionTestController::getSession' + options: + _auth: ['basic_auth'] + 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 1ae9a79..ccf3945 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 @@ -149,4 +149,8 @@ public function traceHandler() { return new JsonResponse($trace); } + public function getSession(Request $request) { + return new JsonResponse(['session' => $request->getSession()->all(), 'user' => $this->currentUser()->id()]); + } + }