From 4d4635c1230a442c4a6c5bb8ec5dffa817888974 Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Mon, 18 May 2015 05:55:06 +0100
Subject: [PATCH] Issue #2283637 by pfrenssen, dawehner, shivanshuag, znerol:
 Provide test coverage to prove that an AuthenticationProvider can initiate a
 session

---
 .../src/Tests/BasicAuthTestTrait.php          | 48 +++++++++++++++++--
 core/modules/simpletest/src/WebTestBase.php   |  2 +-
 .../Session/SessionAuthenticationTest.php     | 32 +++++++++++++
 .../session_test/session_test.routing.yml     | 12 +++++
 .../src/Controller/SessionTestController.php  | 17 +++++++
 5 files changed, 107 insertions(+), 4 deletions(-)

diff --git a/core/modules/basic_auth/src/Tests/BasicAuthTestTrait.php b/core/modules/basic_auth/src/Tests/BasicAuthTestTrait.php
index 7cd6d3012130..2d04672f69d8 100644
--- a/core/modules/basic_auth/src/Tests/BasicAuthTestTrait.php
+++ b/core/modules/basic_auth/src/Tests/BasicAuthTestTrait.php
@@ -28,10 +28,52 @@ trait BasicAuthTestTrait {
    *   The retrieved HTML string, also available as $this->getRawContent().
    */
   protected function basicAuthGet($path, $username, $password, array $options = []) {
-    // Set up Curl to use basic authentication with the test user's credentials.
-    $headers = ['Authorization: Basic ' . base64_encode("$username:$password")];
+    return $this->drupalGet($path, $options, $this->getBasicAuthHeaders($username, $password));
+  }
+
+  /**
+   * Executes a form submission using 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 string $username
+   *   The username to use for basic authentication.
+   * @param string $password
+   *   The password to use for basic authentication.
+   * @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, $username, $password, array $options = array(), $form_html_id = NULL, $extra_post = NULL) {
+    return $this->drupalPostForm($path, $edit, $submit, $options, $this->getBasicAuthHeaders($username, $password), $form_html_id, $extra_post);
+  }
 
-    return $this->drupalGet($path, $options, $headers);
+  /**
+   * Returns HTTP headers that can be used for basic authentication in Curl.
+   *
+   * @param string $username
+   *   The username to use for basic authentication.
+   * @param string $password
+   *   The password to use for basic authentication.
+   *
+   * @return array
+   *   An array of raw request headers as used by curl_setopt().
+   */
+  protected function getBasicAuthHeaders($username, $password) {
+    // Set up Curl to use basic authentication with the test user's credentials.
+    return ['Authorization: Basic ' . base64_encode("$username:$password")];
   }
 
 }
diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php
index 99cb227e6c6d..8e224c11bfbc 100644
--- a/core/modules/simpletest/src/WebTestBase.php
+++ b/core/modules/simpletest/src/WebTestBase.php
@@ -1369,7 +1369,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 121bc3450d30..1a67266809c0 100644
--- a/core/modules/system/src/Tests/Session/SessionAuthenticationTest.php
+++ b/core/modules/system/src/Tests/Session/SessionAuthenticationTest.php
@@ -78,4 +78,36 @@ public function testSessionFromBasicAuthenticationDoesNotLeak() {
     $this->assertResponse(401, 'A subsequent request to the same route without basic authentication is not authorized.');
   }
 
+  /**
+   * Tests if a session can be initiated through basic authentication.
+   */
+  public function testBasicAuthSession() {
+    // Set a session value on a request through basic auth.
+    $test_value = 'alpaca';
+    $response = $this->basicAuthGet('session-test/set-session/' . $test_value, $this->user->getUsername(), $this->user->pass_raw);
+    $this->assertSessionData($response, $test_value);
+    $this->assertResponse(200, 'The request to set a session value was successful.');
+
+    // Test that on a subsequent request the session value is still present.
+    $response = $this->basicAuthGet('session-test/get-session', $this->user->getUsername(), $this->user->pass_raw);
+    $this->assertSessionData($response, $test_value);
+    $this->assertResponse(200, 'The request to get a session value was successful.');
+  }
+
+  /**
+   * Checks the session data returned by the session test routes.
+   *
+   * @param string $response
+   *   A response object containing the session values and the user ID.
+   * @param string $expected
+   *   The expected session value.
+   */
+  protected function assertSessionData($response, $expected) {
+    $response = json_decode($response, TRUE);
+    $this->assertEqual(['test_value' => $expected], $response['session'], 'The session data matches the expected value.');
+
+    // Check that we are logged in as the correct user.
+    $this->assertEqual($this->user->id(), $response['user'], 'The correct user is logged in.');
+  }
+
 }
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 0cedf4f9bfe0..b2ef74f8b948 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 41fe7edc8dbd..b17d9a0684cc 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,21 @@ 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);
+    return new JsonResponse(['session' => $session->all(), 'user' => $this->currentUser()->id()]);
+  }
+
 }
-- 
GitLab