Pull merge.
[yaffs-website] / web / core / modules / system / tests / src / Functional / Session / SessionAuthenticationTest.php
1 <?php
2
3 namespace Drupal\Tests\system\Functional\Session;
4
5 use Drupal\Core\Url;
6 use Drupal\Tests\basic_auth\Traits\BasicAuthTestTrait;
7 use Drupal\Tests\BrowserTestBase;
8
9 /**
10  * Tests if sessions are correctly handled when a user authenticates.
11  *
12  * @group Session
13  */
14 class SessionAuthenticationTest extends BrowserTestBase {
15
16   use BasicAuthTestTrait;
17
18   /**
19    * A test user.
20    *
21    * @var \Drupal\user\Entity\User
22    */
23   protected $user;
24
25   /**
26    * {@inheritdoc}
27    */
28   public static $modules = ['basic_auth', 'session_test'];
29
30   /**
31    * {@inheritdoc}
32    */
33   protected function setUp() {
34     parent::setUp();
35
36     // Create a test administrator user.
37     $this->user = $this->drupalCreateUser(['administer site configuration']);
38   }
39
40   /**
41    * Check that a basic authentication session does not leak.
42    *
43    * Regression test for a bug that caused a session initiated by basic
44    * authentication to persist over subsequent unauthorized requests.
45    */
46   public function testSessionFromBasicAuthenticationDoesNotLeak() {
47     // This route is authorized through basic_auth only, not cookie.
48     $protected_url = Url::fromRoute('session_test.get_session_basic_auth');
49
50     // This route is not protected.
51     $unprotected_url = Url::fromRoute('session_test.get_session_no_auth');
52
53     // Test that the route is not accessible as an anonymous user.
54     $this->drupalGet($protected_url);
55     $session = $this->getSession();
56     $this->assertResponse(401, 'An anonymous user cannot access a route protected with basic authentication.');
57
58     // We should be able to access the route with basic authentication.
59     $this->basicAuthGet($protected_url, $this->user->getAccountName(), $this->user->passRaw);
60     $this->assertResponse(200, 'A route protected with basic authentication can be accessed by an authenticated user.');
61
62     // Check that the correct user is logged in.
63     $this->assertEqual($this->user->id(), json_decode($session->getPage()->getContent())->user, 'The correct user is authenticated on a route with basic authentication.');
64     $session->restart();
65
66     // If we now try to access a page without basic authentication then we
67     // should no longer be logged in.
68     $this->drupalGet($unprotected_url);
69     $this->assertResponse(200, 'An unprotected route can be accessed without basic authentication.');
70     $this->assertFalse(json_decode($session->getPage()->getContent())->user, 'The user is no longer authenticated after visiting a page without basic authentication.');
71
72     // If we access the protected page again without basic authentication we
73     // should get 401 Unauthorized.
74     $this->drupalGet($protected_url);
75     $this->assertResponse(401, 'A subsequent request to the same route without basic authentication is not authorized.');
76   }
77
78   /**
79    * Tests if a session can be initiated through basic authentication.
80    */
81   public function testBasicAuthSession() {
82     // Set a session value on a request through basic auth.
83     $test_value = 'alpaca';
84     $response = $this->basicAuthGet('session-test/set-session/' . $test_value, $this->user->getUsername(), $this->user->pass_raw);
85     $this->assertSessionData($response, $test_value);
86     $this->assertResponse(200, 'The request to set a session value was successful.');
87
88     // Test that on a subsequent request the session value is still present.
89     $response = $this->basicAuthGet('session-test/get-session', $this->user->getUsername(), $this->user->pass_raw);
90     $this->assertSessionData($response, $test_value);
91     $this->assertResponse(200, 'The request to get a session value was successful.');
92   }
93
94   /**
95    * Checks the session data returned by the session test routes.
96    *
97    * @param string $response
98    *   A response object containing the session values and the user ID.
99    * @param string $expected
100    *   The expected session value.
101    */
102   protected function assertSessionData($response, $expected) {
103     $response = json_decode($response, TRUE);
104     $this->assertEqual(['test_value' => $expected], $response['session'], 'The session data matches the expected value.');
105
106     // Check that we are logged in as the correct user.
107     $this->assertEqual($this->user->id(), $response['user'], 'The correct user is logged in.');
108   }
109
110   /**
111    * Tests that a session is not started automatically by basic authentication.
112    */
113   public function testBasicAuthNoSession() {
114     // A route that is authorized through basic_auth only, not cookie.
115     $no_cookie_url = Url::fromRoute('session_test.get_session_basic_auth');
116
117     // A route that is authorized with standard cookie authentication.
118     $cookie_url = 'user/login';
119
120     // If we authenticate with a third party authentication system then no
121     // session cookie should be set, the third party system is responsible for
122     // sustaining the session.
123     $this->basicAuthGet($no_cookie_url, $this->user->getAccountName(), $this->user->passRaw);
124     $this->assertResponse(200, 'The user is successfully authenticated using basic authentication.');
125     $this->assertEmpty($this->getSessionCookies());
126     // Mink stores some information in the session that breaks the next check if
127     // not reset.
128     $this->getSession()->restart();
129
130     // On the other hand, authenticating using Cookie sets a cookie.
131     $this->drupalGet($cookie_url);
132     $this->assertEmpty($this->getSessionCookies());
133     $edit = ['name' => $this->user->getAccountName(), 'pass' => $this->user->passRaw];
134     $this->drupalPostForm($cookie_url, $edit, t('Log in'));
135     $this->assertNotEmpty($this->getSessionCookies());
136   }
137
138 }