View source
<?php
namespace Drupal\Tests\simple_oauth\Functional;
use Drupal\Core\Url;
use Drupal\user\Entity\Role;
use Drupal\user\RoleInterface;
class AuthCodeFunctionalTest extends TokenBearerFunctionalTestBase {
protected $defaultTheme = 'stark';
protected $authorizeUrl;
protected $redirectUri;
protected $extraRole;
public static $modules = [
'simple_oauth_test',
];
protected function setUp() {
parent::setUp();
$this->redirectUri = Url::fromRoute('oauth2_token.test_token', [], [
'absolute' => TRUE,
])
->toString();
$this->client
->set('redirect', $this->redirectUri);
$this->client
->set('description', $this
->getRandomGenerator()
->paragraphs());
$this->client
->save();
$this->authorizeUrl = Url::fromRoute('oauth2_token.authorize');
$this
->grantPermissions(Role::load(RoleInterface::AUTHENTICATED_ID), [
'grant simple_oauth codes',
]);
$additional_scope = $this
->getRandomGenerator()
->name(8, TRUE);
Role::create([
'id' => $additional_scope,
'label' => $this
->getRandomGenerator()
->word(5),
'is_admin' => FALSE,
])
->save();
$this->scope = $this->scope . ' ' . $additional_scope;
$this->extraRole = Role::create([
'id' => $this
->getRandomGenerator()
->name(8, TRUE),
'label' => $this
->getRandomGenerator()
->word(5),
'is_admin' => FALSE,
]);
$this->extraRole
->save();
}
public function testAuthCodeGrant() {
$valid_params = [
'response_type' => 'code',
'client_id' => $this->client
->uuid(),
'client_secret' => $this->clientSecret,
];
$this
->drupalGet($this->authorizeUrl
->toString(), [
'query' => $valid_params,
]);
$assert_session = $this
->assertSession();
$assert_session
->buttonExists('Log in');
$this
->drupalLogin($this->user);
$this
->drupalGet($this->authorizeUrl
->toString(), [
'query' => $valid_params,
]);
$this
->assertGrantForm();
$this
->drupalPostForm($this->authorizeUrl, [], 'Grant', [
'query' => $valid_params,
]);
$code = $this
->getAndValidateCodeFromResponse();
$response = $this
->postGrantedCodeWithScopes($code, $this->scope);
$this
->assertValidTokenResponse($response, TRUE);
}
public function testNon3rdPartyClientAuthCodeGrant() {
$this->client
->set('third_party', FALSE);
$this->client
->save();
$valid_params = [
'response_type' => 'code',
'client_id' => $this->client
->uuid(),
'client_secret' => $this->clientSecret,
];
$this
->drupalGet($this->authorizeUrl
->toString(), [
'query' => $valid_params,
]);
$assert_session = $this
->assertSession();
$assert_session
->buttonExists('Log in');
$this
->drupalLogin($this->user);
$this
->drupalGet($this->authorizeUrl
->toString(), [
'query' => $valid_params,
]);
$code = $this
->getAndValidateCodeFromResponse();
$response = $this
->postGrantedCodeWithScopes($code, $this->scope . ' ' . $this->extraRole
->id());
$this
->assertValidTokenResponse($response, TRUE);
}
public function testRememberClient() {
$valid_params = [
'response_type' => 'code',
'client_id' => $this->client
->uuid(),
'client_secret' => $this->clientSecret,
];
$this
->drupalGet($this->authorizeUrl
->toString(), [
'query' => $valid_params,
]);
$assert_session = $this
->assertSession();
$assert_session
->buttonExists('Log in');
$this
->drupalLogin($this->user);
$this
->drupalGet($this->authorizeUrl
->toString(), [
'query' => $valid_params,
]);
$this
->assertGrantForm();
$this
->drupalPostForm(NULL, [], 'Grant');
$code = $this
->getAndValidateCodeFromResponse();
$response = $this
->postGrantedCodeWithScopes($code, $this->scope);
$this
->assertValidTokenResponse($response, TRUE);
$this
->drupalGet($this->authorizeUrl
->toString(), [
'query' => $valid_params,
]);
$code = $this
->getAndValidateCodeFromResponse();
$response = $this
->postGrantedCodeWithScopes($code, $this->scope);
$this
->assertValidTokenResponse($response, TRUE);
$valid_params['scope'] = $this->extraRole
->id();
$this
->drupalGet($this->authorizeUrl
->toString(), [
'query' => $valid_params,
]);
$this
->assertGrantForm();
$this
->assertSession()
->pageTextContains($this->extraRole
->label());
$this
->drupalPostForm(NULL, [], 'Grant');
$code = $this
->getAndValidateCodeFromResponse();
$response = $this
->postGrantedCodeWithScopes($code, $this->scope . ' ' . $this->extraRole
->id());
$this
->assertValidTokenResponse($response, TRUE);
$valid_params['scope'] = $this->extraRole
->id();
$this
->drupalGet($this->authorizeUrl
->toString(), [
'query' => $valid_params,
]);
$code = $this
->getAndValidateCodeFromResponse();
$response = $this
->postGrantedCodeWithScopes($code, $this->scope . ' ' . $this->extraRole
->id());
$this
->assertValidTokenResponse($response, TRUE);
$this
->config('simple_oauth.settings')
->set('remember_clients', FALSE)
->save();
$this
->drupalGet($this->authorizeUrl
->toString(), [
'query' => $valid_params,
]);
$this
->assertGrantForm();
}
public function testClientAuthCodeGrantWithPkce() {
$this->client
->set('pkce', TRUE);
$this->client
->set('confidential', FALSE);
$this->client
->save();
$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',
];
$this
->drupalGet($this->authorizeUrl
->toString(), [
'query' => $valid_params,
]);
$assert_session = $this
->assertSession();
$assert_session
->buttonExists('Log in');
$this
->drupalLogin($this->user);
$this
->drupalGet($this->authorizeUrl
->toString(), [
'query' => $valid_params,
]);
$this
->assertGrantForm();
$this
->drupalPostForm(NULL, [], 'Grant');
$code = $this
->getAndValidateCodeFromResponse();
$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);
}
protected function assertGrantForm() {
$assert_session = $this
->assertSession();
$assert_session
->statusCodeEquals(200);
$assert_session
->titleEquals('Grant Access to Client | Drupal');
$assert_session
->buttonExists('Grant');
$assert_session
->responseContains('Permissions');
}
protected function getAndValidateCodeFromResponse() {
$assert_session = $this
->assertSession();
$session = $this
->getSession();
$assert_session
->statusCodeEquals(200);
$parsed_url = parse_url($session
->getCurrentUrl());
$parsed_query = \GuzzleHttp\Psr7\parse_query($parsed_url['query']);
$this
->assertArrayHasKey('code', $parsed_query);
return $parsed_query['code'];
}
protected function postGrantedCodeWithScopes($code, $scopes) {
$valid_payload = [
'grant_type' => 'authorization_code',
'client_id' => $this->client
->uuid(),
'client_secret' => $this->clientSecret,
'code' => $code,
'scope' => $scopes,
'redirect_uri' => $this->redirectUri,
];
return $this
->post($this->url, $valid_payload);
}
}