Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/Event/AuthorizationRequestResolveEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,13 @@ public function getUser(): UserInterface
return $this->user;
}

public function setUser(UserInterface $user): self
{
$this->user = $user;

return $this;
}

/**
* @return Scope[]
*/
Expand Down
71 changes: 71 additions & 0 deletions tests/Acceptance/AuthorizationEndpointTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,77 @@ public function testSuccessfulPKCEAuthCodeRequest(): void

$this->assertInstanceOf(AuthorizationCode::class, $authCode);
$this->assertSame(FixtureFactory::FIXTURE_PUBLIC_CLIENT, $authCode->getClient()->getIdentifier());
$this->assertSame(FixtureFactory::FIXTURE_USER, $authCode->getUserIdentifier());
}

public function testSuccessfulAuthCodeRequestWhenTheLoggedUserIsOverriddenInTheAuthorizationRequestResolveEvent(): void
{
$state = bin2hex(random_bytes(20));
$codeVerifier = bin2hex(random_bytes(64));
$codeChallengeMethod = 'S256';

$codeChallenge = strtr(
rtrim(base64_encode(hash('sha256', $codeVerifier, true)), '='),
'+/',
'-_'
);

$this->loginUser();

$this->client
->getContainer()
->get('event_dispatcher')
->addListener(OAuth2Events::AUTHORIZATION_REQUEST_RESOLVE, function (AuthorizationRequestResolveEvent $event) use ($state, $codeChallenge, $codeChallengeMethod): void {
$this->assertSame($state, $event->getState());
$this->assertSame($codeChallenge, $event->getCodeChallenge());
$this->assertSame($codeChallengeMethod, $event->getCodeChallengeMethod());

$event->setUser(FixtureFactory::createUser([], FixtureFactory::FIXTURE_USER_TWO));
$event->resolveAuthorization(AuthorizationRequestResolveEvent::AUTHORIZATION_APPROVED);
});

$this->client->request(
'GET',
'/authorize',
[
'client_id' => FixtureFactory::FIXTURE_PUBLIC_CLIENT,
'response_type' => 'code',
'scope' => '',
'state' => $state,
'code_challenge' => $codeChallenge,
'code_challenge_method' => $codeChallengeMethod,
]
);

$response = $this->client->getResponse();

$this->assertSame(302, $response->getStatusCode());
$redirectUri = $response->headers->get('Location');

$this->assertStringStartsWith(FixtureFactory::FIXTURE_CLIENT_FIRST_REDIRECT_URI, $redirectUri);
$query = [];
parse_str(parse_url($redirectUri, \PHP_URL_QUERY), $query);
$this->assertArrayHasKey('state', $query);
$this->assertSame($state, $query['state']);

$this->assertArrayHasKey('code', $query);
$payload = json_decode(TestHelper::decryptPayload($query['code']), true);

$this->assertArrayHasKey('code_challenge', $payload);
$this->assertArrayHasKey('code_challenge_method', $payload);
$this->assertSame($codeChallenge, $payload['code_challenge']);
$this->assertSame($codeChallengeMethod, $payload['code_challenge_method']);

/** @var AuthorizationCode|null $authCode */
$authCode = $this->client
->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository(AuthorizationCode::class)
->findOneBy(['identifier' => $payload['auth_code_id']]);

$this->assertInstanceOf(AuthorizationCode::class, $authCode);
$this->assertSame(FixtureFactory::FIXTURE_PUBLIC_CLIENT, $authCode->getClient()->getIdentifier());
$this->assertSame(FixtureFactory::FIXTURE_USER_TWO, $authCode->getUserIdentifier());
}

public function testAuthCodeRequestWithPublicClientWithoutCodeChallengeWhenTheChallengeIsRequiredForPublicClients(): void
Expand Down
5 changes: 3 additions & 2 deletions tests/Fixtures/FixtureFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,12 @@ final class FixtureFactory
public const FIXTURE_SCOPE_SECOND = 'rock';

public const FIXTURE_USER = 'user';
public const FIXTURE_USER_TWO = 'user_two';
public const FIXTURE_PASSWORD = 'password';

public static function createUser(array $roles = []): User
public static function createUser(array $roles = [], ?string $userIdentifier = null): User
{
$user = new User();
$user = new User($userIdentifier);
$user['roles'] = $roles;

return $user;
Expand Down
7 changes: 6 additions & 1 deletion tests/Fixtures/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@

class User extends \ArrayObject implements UserInterface
{
public function __construct(private readonly ?string $userIdentifier = null)
{
parent::__construct();
}

public function getRoles(): array
{
return $this['roles'] ?? [];
Expand All @@ -25,7 +30,7 @@ public function getSalt(): ?string

public function getUserIdentifier(): string
{
return FixtureFactory::FIXTURE_USER;
return $this->userIdentifier ?? FixtureFactory::FIXTURE_USER;
}

public function eraseCredentials(): void
Expand Down
6 changes: 6 additions & 0 deletions tests/TestKernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ public function registerContainerConfiguration(LoaderInterface $loader): void
FixtureFactory::FIXTURE_USER => [
'roles' => ['ROLE_USER'],
],
FixtureFactory::FIXTURE_USER_TWO => [
'roles' => ['ROLE_USER'],
],
],
],
],
Expand All @@ -148,6 +151,9 @@ public function registerContainerConfiguration(LoaderInterface $loader): void
FixtureFactory::FIXTURE_USER => [
'roles' => ['ROLE_USER'],
],
FixtureFactory::FIXTURE_USER_TWO => [
'roles' => ['ROLE_USER'],
],
],
],
],
Expand Down
Loading