Skip to content

Commit acc1c66

Browse files
committed
feature #263 Allow user override on auth request resolve event (X-Coder264)
This PR was merged into the 1.x-dev branch. Discussion ---------- Allow user override on auth request resolve event The ability to override the user on the `AuthorizationRequestResolveEvent` event was removed in #196 without any reason IMO. We are using this for admin impersonation purposes. We are trying to update from v0.8 to v1 but this is blocking us from doing so. So I'm sending this pull request so that overriding the user becomes possible again. Commits ------- 2487d50 Allow user override on auth request resolve event
2 parents 7e43c4f + 2487d50 commit acc1c66

File tree

5 files changed

+93
-3
lines changed

5 files changed

+93
-3
lines changed

src/Event/AuthorizationRequestResolveEvent.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,13 @@ public function getUser(): UserInterface
9999
return $this->user;
100100
}
101101

102+
public function setUser(UserInterface $user): self
103+
{
104+
$this->user = $user;
105+
106+
return $this;
107+
}
108+
102109
/**
103110
* @return Scope[]
104111
*/

tests/Acceptance/AuthorizationEndpointTest.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,77 @@ public function testSuccessfulPKCEAuthCodeRequest(): void
138138

139139
$this->assertInstanceOf(AuthorizationCode::class, $authCode);
140140
$this->assertSame(FixtureFactory::FIXTURE_PUBLIC_CLIENT, $authCode->getClient()->getIdentifier());
141+
$this->assertSame(FixtureFactory::FIXTURE_USER, $authCode->getUserIdentifier());
142+
}
143+
144+
public function testSuccessfulAuthCodeRequestWhenTheLoggedUserIsOverriddenInTheAuthorizationRequestResolveEvent(): void
145+
{
146+
$state = bin2hex(random_bytes(20));
147+
$codeVerifier = bin2hex(random_bytes(64));
148+
$codeChallengeMethod = 'S256';
149+
150+
$codeChallenge = strtr(
151+
rtrim(base64_encode(hash('sha256', $codeVerifier, true)), '='),
152+
'+/',
153+
'-_'
154+
);
155+
156+
$this->loginUser();
157+
158+
$this->client
159+
->getContainer()
160+
->get('event_dispatcher')
161+
->addListener(OAuth2Events::AUTHORIZATION_REQUEST_RESOLVE, function (AuthorizationRequestResolveEvent $event) use ($state, $codeChallenge, $codeChallengeMethod): void {
162+
$this->assertSame($state, $event->getState());
163+
$this->assertSame($codeChallenge, $event->getCodeChallenge());
164+
$this->assertSame($codeChallengeMethod, $event->getCodeChallengeMethod());
165+
166+
$event->setUser(FixtureFactory::createUser([], FixtureFactory::FIXTURE_USER_TWO));
167+
$event->resolveAuthorization(AuthorizationRequestResolveEvent::AUTHORIZATION_APPROVED);
168+
});
169+
170+
$this->client->request(
171+
'GET',
172+
'/authorize',
173+
[
174+
'client_id' => FixtureFactory::FIXTURE_PUBLIC_CLIENT,
175+
'response_type' => 'code',
176+
'scope' => '',
177+
'state' => $state,
178+
'code_challenge' => $codeChallenge,
179+
'code_challenge_method' => $codeChallengeMethod,
180+
]
181+
);
182+
183+
$response = $this->client->getResponse();
184+
185+
$this->assertSame(302, $response->getStatusCode());
186+
$redirectUri = $response->headers->get('Location');
187+
188+
$this->assertStringStartsWith(FixtureFactory::FIXTURE_CLIENT_FIRST_REDIRECT_URI, $redirectUri);
189+
$query = [];
190+
parse_str(parse_url($redirectUri, \PHP_URL_QUERY), $query);
191+
$this->assertArrayHasKey('state', $query);
192+
$this->assertSame($state, $query['state']);
193+
194+
$this->assertArrayHasKey('code', $query);
195+
$payload = json_decode(TestHelper::decryptPayload($query['code']), true);
196+
197+
$this->assertArrayHasKey('code_challenge', $payload);
198+
$this->assertArrayHasKey('code_challenge_method', $payload);
199+
$this->assertSame($codeChallenge, $payload['code_challenge']);
200+
$this->assertSame($codeChallengeMethod, $payload['code_challenge_method']);
201+
202+
/** @var AuthorizationCode|null $authCode */
203+
$authCode = $this->client
204+
->getContainer()
205+
->get('doctrine.orm.entity_manager')
206+
->getRepository(AuthorizationCode::class)
207+
->findOneBy(['identifier' => $payload['auth_code_id']]);
208+
209+
$this->assertInstanceOf(AuthorizationCode::class, $authCode);
210+
$this->assertSame(FixtureFactory::FIXTURE_PUBLIC_CLIENT, $authCode->getClient()->getIdentifier());
211+
$this->assertSame(FixtureFactory::FIXTURE_USER_TWO, $authCode->getUserIdentifier());
141212
}
142213

143214
public function testAuthCodeRequestWithPublicClientWithoutCodeChallengeWhenTheChallengeIsRequiredForPublicClients(): void

tests/Fixtures/FixtureFactory.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,12 @@ final class FixtureFactory
6161
public const FIXTURE_SCOPE_SECOND = 'rock';
6262

6363
public const FIXTURE_USER = 'user';
64+
public const FIXTURE_USER_TWO = 'user_two';
6465
public const FIXTURE_PASSWORD = 'password';
6566

66-
public static function createUser(array $roles = []): User
67+
public static function createUser(array $roles = [], ?string $userIdentifier = null): User
6768
{
68-
$user = new User();
69+
$user = new User($userIdentifier);
6970
$user['roles'] = $roles;
7071

7172
return $user;

tests/Fixtures/User.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88

99
class User extends \ArrayObject implements UserInterface
1010
{
11+
public function __construct(private readonly ?string $userIdentifier = null)
12+
{
13+
parent::__construct();
14+
}
15+
1116
public function getRoles(): array
1217
{
1318
return $this['roles'] ?? [];
@@ -25,7 +30,7 @@ public function getSalt(): ?string
2530

2631
public function getUserIdentifier(): string
2732
{
28-
return FixtureFactory::FIXTURE_USER;
33+
return $this->userIdentifier ?? FixtureFactory::FIXTURE_USER;
2934
}
3035

3136
public function eraseCredentials(): void

tests/TestKernel.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ public function registerContainerConfiguration(LoaderInterface $loader): void
139139
FixtureFactory::FIXTURE_USER => [
140140
'roles' => ['ROLE_USER'],
141141
],
142+
FixtureFactory::FIXTURE_USER_TWO => [
143+
'roles' => ['ROLE_USER'],
144+
],
142145
],
143146
],
144147
],
@@ -148,6 +151,9 @@ public function registerContainerConfiguration(LoaderInterface $loader): void
148151
FixtureFactory::FIXTURE_USER => [
149152
'roles' => ['ROLE_USER'],
150153
],
154+
FixtureFactory::FIXTURE_USER_TWO => [
155+
'roles' => ['ROLE_USER'],
156+
],
151157
],
152158
],
153159
],

0 commit comments

Comments
 (0)