You are here

public function AuthCodeFunctionalTest::testClientAuthCodeGrantWithPkce in Simple OAuth (OAuth2) & OpenID Connect 8.4

Same name and namespace in other branches
  1. 5.x tests/src/Functional/AuthCodeFunctionalTest.php \Drupal\Tests\simple_oauth\Functional\AuthCodeFunctionalTest::testClientAuthCodeGrantWithPkce()

Test the AuthCode grant with PKCE.

File

tests/src/Functional/AuthCodeFunctionalTest.php, line 244

Class

AuthCodeFunctionalTest
The auth code test.

Namespace

Drupal\Tests\simple_oauth\Functional

Code

public function testClientAuthCodeGrantWithPkce() {
  $this->client
    ->set('pkce', TRUE);
  $this->client
    ->set('confidential', FALSE);
  $this->client
    ->save();

  // For PKCE flow we need a code verifier and a code challenge.
  // @see https://tools.ietf.org/html/rfc7636 for details.
  $code_verifier = self::base64urlencode(random_bytes(64));
  $code_challenge = self::base64urlencode(hash('sha256', $code_verifier, TRUE));
  $valid_params = [
    'response_type' => 'code',
    'client_id' => $this->client
      ->uuid(),
    'code_challenge' => $code_challenge,
    'code_challenge_method' => 'S256',
  ];

  // 1. Anonymous request redirect to log in.
  $this
    ->drupalGet($this->authorizeUrl
    ->toString(), [
    'query' => $valid_params,
  ]);
  $assert_session = $this
    ->assertSession();
  $assert_session
    ->buttonExists('Log in');

  // 2. Logged in user gets the grant form.
  $this
    ->drupalLogin($this->user);
  $this
    ->drupalGet($this->authorizeUrl
    ->toString(), [
    'query' => $valid_params,
  ]);
  $this
    ->assertGrantForm();

  // 3. Grant access by submitting the form.
  $this
    ->drupalPostForm(NULL, [], 'Grant');

  // Store the code for the second part of the flow.
  $code = $this
    ->getAndValidateCodeFromResponse();

  // Request the access and refresh token.
  $valid_payload = [
    'grant_type' => 'authorization_code',
    'client_id' => $this->client
      ->uuid(),
    'code_verifier' => $code_verifier,
    'scope' => $this->scope . ' ' . $this->extraRole
      ->id(),
    'code' => $code,
    'redirect_uri' => $this->redirectUri,
  ];
  $response = $this
    ->post($this->url, $valid_payload);
  $this
    ->assertValidTokenResponse($response, TRUE);
}