Problem/Motivation

Before #2228393: Decouple session from cookie based user authentication went in, the SessionManager started a session if it detected an authenticated user upon save(), regardless of whether the user was authenticated using a session cookie or by another authentication provider (e.g. basic_auth).

This problem has been resolved by the aforementioned issue.

Proposed resolution

Provide test coverage that proves that no session is started only because the request has been authenticated by a third-party provider. Add appropriate test methods into Drupal\system\Tests\Session\SessionAuthenticationTest.

Test strategy:

  1. Use basicAuthGet on a route where basic auth is allowed and assert that there is no session cookie on the response.

Remaining tasks

Commit.

User interface changes

None.

API changes

None.

Beta phase evaluation

Reference: https://www.drupal.org/core/beta-changes
Issue category Task
Issue priority Normal
Unfrozen changes Unfrozen because it only extends test coverage

Comments

cpj’s picture

Title: A session is always started when using a different authentication provider than cookie (e.g. basci auth) » A session is always started when using a different authentication provider than cookie (e.g. basic auth)
andypost’s picture

Status: Active » Postponed
Parent issue: » #2228393: Decouple session from cookie based user authentication

This actually depends on that

xjm’s picture

Status: Postponed » Active

#2228393: Decouple session from cookie based user authentication is in; should this issue be repurposed for test coverage, or marked fixed?

andypost’s picture

znerol’s picture

Title: A session is always started when using a different authentication provider than cookie (e.g. basic auth) » Provide test coverage to prove that a third party authentication provider does not automatically start a session
Issue summary: View changes
Issue tags: +Novice
pfrenssen’s picture

Assigned: Unassigned » pfrenssen

This should be pretty easy, we already have all the necessary ingredients in SessionAuthenticationTest.

pfrenssen’s picture

Assigned: pfrenssen » Unassigned
Status: Active » Needs review
StatusFileSize
new1.84 KB

Something like this should do the trick. I'm testing both that cookie sets a cookie, and basic auth doesn't.

benjifisher’s picture

Issue tags: -Novice

I am removing the Novice Tag from this Issue because there are no Novice tasks left.

pfrenssen’s picture

StatusFileSize
new1.83 KB
new714 bytes

Fixed a little typo in my patch.

znerol’s picture

  1. +++ b/core/modules/system/src/Tests/Session/SessionAuthenticationTest.php
    @@ -78,4 +78,28 @@ public function testSessionFromBasicAuthenticationDoesNotLeak() {
    +   * Checks that no session cookie is saved when using basic authentication.
    ...
    +    // If we authenticate with a third party authentication system then no
    +    // session cookie should be set, the third party system is responsible for
    ...
    +    // On the other hand, authenticating using Cookie yields a cookie.
    

    Please only use the verb set, not save and not yield when describing the process of a cookie being passed from the server into the browser. This test is about the Set-Cookie HTTP response header.

  2. +++ b/core/modules/system/src/Tests/Session/SessionAuthenticationTest.php
    @@ -78,4 +78,28 @@ public function testSessionFromBasicAuthenticationDoesNotLeak() {
    +  public function testOnlyCookieGetsACookie() {
    

    What about testBasicAuthNoSession with the docstring: Tests that a session is not started automatically by basic authentication. (in analogy to what we've ended up in #2283637: Provide test coverage to prove that an AuthenticationProvider can initiate a session).

pfrenssen’s picture

Assigned: Unassigned » pfrenssen
Status: Needs review » Needs work

Good points, will address these today during my lunch break.

pfrenssen’s picture

Assigned: pfrenssen » Unassigned
Status: Needs work » Needs review
StatusFileSize
new1.83 KB
new1.48 KB

Updated the documentation with @znerol's suggestions.

pfrenssen’s picture

StatusFileSize
new1.83 KB
new1.36 KB

Also replaced "yield a cookie" with "set a cookie" in the assert messages.

The last submitted patch, 13: 2432911-13.patch, failed testing.

znerol’s picture

Issue summary: View changes
Status: Needs review » Reviewed & tested by the community

Thanks. Added the beta evaluation.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 14: 2432911-14.patch, failed testing.

pfrenssen’s picture

Status: Needs work » Needs review
StatusFileSize
new1.8 KB

Patch didn't apply any more since #2283637: Provide test coverage to prove that an AuthenticationProvider can initiate a session went in. Rerolled against latest HEAD.

Status: Needs review » Needs work

The last submitted patch, 18: 2432911-18.patch, failed testing.

pfrenssen’s picture

Interesting, seems we have a cookie :)

znerol’s picture

Funny, it looks like $this->cookies is bleeding over from the previous test.

pfrenssen’s picture

Assigned: Unassigned » pfrenssen

I'll have a look. If this is the case then this is a separate issue. I'll reorder the tests and open a followup to ensure that the cookies are properly initialized on every request.

pfrenssen’s picture

Assigned: pfrenssen » Unassigned
Status: Needs work » Needs review
StatusFileSize
new2.11 KB
new1.66 KB

This is a bit more robust. I'm now inspecting the request headers to see if the string "Set-Cookie" is present.

I looked into the cookie bleeding issue and this is indeed what is happening. In WebTestBase::curlHeaderCallback() the $this->cookies property is filled whenever a cookie is set on the request but these are never cleared to simulate the browser persisting the cookies inbetween requests. We should clear this whenever a new test starts.

pfrenssen’s picture

znerol’s picture

+++ b/core/modules/system/src/Tests/Session/SessionAuthenticationTest.php
@@ -110,4 +110,38 @@ protected function assertSessionData($response, $expected) {
+    return count(preg_grep('/^Set-Cookie: ([^=]+)=(.+)/', $this->headers));

As mentioned in the other issue, use $this->drupalGetHeader().

Edit: And then the helper method probably gets superflous, so you may inline it for better comprehension.

pfrenssen’s picture

Category: Bug report » Task
StatusFileSize
new1.86 KB
new1.72 KB

Used $this->drupalGetHeader() as suggested in #25.

Also changing this to a task, the bug is already fixed in HEAD.

znerol’s picture

+++ b/core/modules/system/src/Tests/Session/SessionAuthenticationTest.php
@@ -110,4 +110,28 @@ protected function assertSessionData($response, $expected) {
+    $this->assertFalse($this->drupalGetHeader('set-cookie', TRUE), 'No cookie is set on a route protected with basic authentication.');
...
+    $this->assertTrue($this->drupalGetHeader('set-cookie', TRUE), 'A cookie is set on a route protected with cookie authentication.');

Is there a redirect involved here? Otherwise it is not necessary to specify TRUE for the optional $all_requests parameter.

pfrenssen’s picture

The second one has a redirect. The first one doesn't but I kept the TRUE parameter for consistency. I'll get rid of it.

pfrenssen’s picture

StatusFileSize
new1.85 KB
new1.02 KB

Got rid of the needless TRUE.

znerol’s picture

Status: Needs review » Reviewed & tested by the community

This new test covers the problem. Thanks.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 30: 2432911-30.patch, failed testing.

almaudoh queued 30: 2432911-30.patch for re-testing.

pfrenssen’s picture

Status: Needs work » Reviewed & tested by the community
alexpott’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/system/src/Tests/Session/SessionAuthenticationTest.php
@@ -110,4 +110,28 @@ protected function assertSessionData($response, $expected) {
+    $this->assertFalse($this->drupalGetHeader('set-cookie'), 'No cookie is set on a route protected with basic authentication.');
...
+    $this->assertTrue($this->drupalGetHeader('set-cookie', TRUE), 'A cookie is set on a route protected with cookie authentication.');

Hmmm... I think we should be consistent here. Not sure I agree with the change in #30 since the tests are supposed to be opposite.

znerol’s picture

The normal case throughout our tests is to not specify $all_requests parameter (default is FALSE). If a redirect happens, then this will only examine the headers of the last request. In my understanding that parameter is a lot like a strict flag, which we only should disable if its really necessary.

It is necessary to relax the check in the second instance because the cookie is set in response to the POST request, and not during the subsequent redirect. IMHO we should not relax that check for the first assertion.

pfrenssen’s picture

I'm siding with Alex on this, because it doesn't look as if we are doing a regular positive-negative test here. Even though this is totally correct it just looks a bit suspicious to me.

As a middle ground, would it perhaps be a good idea to set $this->maximumRedirects to 0 to stop the redirection taking place?

alexpott’s picture

I dunno - in my opinion it makes sense to set the $all_requests to TRUE in both instances because what you are looking to test is that no request has set a cookie or that at least one has.

znerol’s picture

Ok, let's not make this more complex as nessecary and revert #30

pfrenssen’s picture

Status: Needs work » Needs review
StatusFileSize
new1.86 KB

OK! Re-uploading the one from #27.

znerol’s picture

Status: Needs review » Reviewed & tested by the community

Thanks.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed 72fb794 and pushed to 8.0.x. Thanks!

Thanks @pfrenssen and @znerol for sticking with this and adding the beta evaluation to the issue summary.

  • alexpott committed 72fb794 on 8.0.x
    Issue #2432911 by pfrenssen, znerol: Provide test coverage to prove that...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.