diff --git a/core/modules/system/src/Tests/Session/MultipleAuthenticationSessionTest.php b/core/modules/system/src/Tests/Session/MultipleAuthenticationSessionTest.php index 712bb4c..628ca37 100644 --- a/core/modules/system/src/Tests/Session/MultipleAuthenticationSessionTest.php +++ b/core/modules/system/src/Tests/Session/MultipleAuthenticationSessionTest.php @@ -7,92 +7,94 @@ namespace Drupal\system\Tests\Session; -use Drupal\user\Entity\Role; -use Drupal\user\RoleInterface; -use Drupal\simpletest\WebTestBase; use Drupal\Core\Url; -use Drupal\Component\Utility\SafeMarkup; +use Drupal\simpletest\WebTestBase; /** - * Tests whether multiple authentication providers can both set the session. + * Tests interactions between multiple authentication sessions. * * @group Session */ class MultipleAuthenticationSessionTest extends WebTestBase { /** - * {@inheritdoc} + * A test user. + * + * @var \Drupal\user\Entity\User */ - public static $modules = array('basic_auth', 'router_test'); + protected $user; /** * {@inheritdoc} */ - protected $dumpHeaders = TRUE; + public static $modules = ['basic_auth', 'session_test']; /** - * Check that authentication provider does not leak on sessions. - * Here using Basic Auth as authentication provider. + * {@inheritdoc} */ - public function testSessionFromBasicAuthDoesNotLeak() { - $user = $this->drupalCreateUser(); + protected function setUp() { + parent::setUp(); + + // Create a test administrator user. + $this->user = $this->drupalCreateUser(array('administer site configuration')); + } - // This page is authorized though basic_auth only, not cookie. - $url = Url::fromRoute('router_test.11'); + /** + * Check that a basic authentication session does not leak. + * + * Regression test for a bug that caused a session initiated by basic + * authentication to persist over subsequent unauthorized requests. + * + * @see https://www.drupal.org/node/2468873 + */ + public function testSessionFromBasicAuthenticationDoesNotLeak() { + // This page is authorized through basic_auth only, not cookie. + $url = Url::fromRoute('session_test.get_session'); - // Anonymous users cannot access unauthorized page. + // Test that the route is not accessible as an anonymous user. $this->drupalGet($url); - $this->assertResponse(401, "Anonymous users cannot access unauthorized page."); + $this->assertResponse(401, 'An anonymous user cannot access a route protected with basic authentication.'); - // Admin users can access unauthorized page. - $this->basicAuthGet($url, $user->getUsername(), $user->pass_raw); - $this->assertResponse(200, "Admin users can access unauthorized page using Basic Auth."); + // We should be able to access the route with basic authentication. + $this->basicAuthGet($url); + $this->assertResponse(200, 'A route protected with basic authentication can be accessed by an authenticated user.'); - // Anonymous users cannot access unauthorized page. + // If we now try to access the page again without basic authentication then + // we should no longer be authorized. $this->drupalGet($url); - $this->assertResponse(401, "Anonymous users cannot access unauthorized page."); + $this->assertResponse(401, 'A subsequent request to the same route without basic authentication is not authorized.'); } /** - * Does HTTP basic auth request. - * - * We do not use \Drupal\simpletest\WebTestBase::drupalGet because we need to - * set curl settings for basic authentication. + * Retrieves a Drupal path or an absolute path using basic authentication. * * @param \Drupal\Core\Url|string $path - * Drupal path or URL to load into internal browser - * @param string $username - * The user name to authenticate with. - * @param string $password - * The password. + * Drupal path or URL to load into the internal browser. + * @param array $options + * Options to be forwarded to the url generator. + * @param array $headers + * An array containing additional HTTP request headers, each formatted as + * "name: value". * * @return string - * Curl output. + * The retrieved HTML string, also available as $this->getRawContent(). */ - protected function basicAuthGet($path, $username, $password) { - if ($path instanceof Url) { - $path = $path->setAbsolute()->toString(); - } - - $out = $this->curlExec( - array( - CURLOPT_HTTPGET => TRUE, - CURLOPT_URL => $path, - CURLOPT_NOBODY => FALSE, - CURLOPT_HTTPAUTH => CURLAUTH_BASIC, - CURLOPT_VERBOSE => 1, - CURLOPT_USERPWD => $username . ':' . $password, - ) - ); - - $verbose = 'GET request to: ' . $path . - '
Ending URL: ' . $this->getUrl(); - if ($this->dumpHeaders) { - $verbose .= '
Headers:
' . SafeMarkup::checkPlain(var_export(array_map('trim', $this->headers), TRUE)) . '
'; - } - $verbose .= '
' . $out; - $this->verbose($verbose); - - return $out; + protected function basicAuthGet($path, array $options = array(), array $headers = array()) { + // Set up Curl to use basic authentication with the test user's credentials. + $this->additionalCurlOptions = [ + CURLOPT_HTTPAUTH => CURLAUTH_BASIC, + CURLOPT_USERPWD => $this->user->getUsername() . ':' . $this->user->pass_raw, + ]; + + $output = $this->drupalGet($path, $options, $headers); + + // Reset the Curl options. + $this->additionalCurlOptions = [ + CURLOPT_HTTPAUTH => NULL, + CURLOPT_USERPWD => NULL, + ]; + + return $output; } + } 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 fce0fc9..6dbf85c 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 @@ -89,3 +89,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: + _title: 'Get session information using basic authentication' + _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 4437743..c87ef63 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 @@ -162,4 +162,15 @@ public function traceHandler() { return new JsonResponse($trace); } + /** + * @param \Symfony\Component\HttpFoundation\Request $request + * The request object. + * + * @return \Symfony\Component\HttpFoundation\JsonResponse + * A response object containing the session values and the user ID. + */ + public function getSession(Request $request) { + return new JsonResponse(['session' => $request->getSession()->all(), 'user' => $this->currentUser()->id()]); + } + }