Skip to content

Commit

Permalink
Fixed array state for symfony/http-foundation >= 6.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ozahorulia committed Jun 4, 2024
1 parent 163315d commit fb6b7cb
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 17 deletions.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
"php": "^8.1",
"symfony/deprecation-contracts": "^3.0",
"symfony/framework-bundle": "^5.4 || ^6.3 || ^7.0",
"symfony/http-foundation": "^5.4 || ^6.3 || ^7.0",
"symfony/security-bundle": "^5.4 || ^6.3 || ^7.0",
"symfony/options-resolver": "^5.4 || ^6.3 || ^7.0",
"symfony/form": "^5.4 || ^6.3 || ^7.0",
Expand Down
2 changes: 1 addition & 1 deletion src/Security/OAuthUtils.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public function getAuthorizationUrl(Request $request, string $name, ?string $red
}

if ($request->query->has('state')) {
$this->addQueryParameterToState($request->query->get('state'), $resourceOwner);
$this->addQueryParameterToState($request->query->all()['state'] ?? [], $resourceOwner);
}

return $resourceOwner->getAuthorizationUrl($redirectUrl, $extraParameters);
Expand Down
62 changes: 46 additions & 16 deletions tests/Security/OAuthUtilsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,12 @@ public function testGetAuthorizationUrlWithConnectAndUserToken(): void
);
}

public function testGetAuthorizationUrlWithStateQueryParameters(): void
/**
* @dataProvider provideAuthorizationUrlsWithState
*/
public function testGetAuthorizationUrlWithStateQueryParameters(string $url, string $urlWithState, string $redirect): void
{
$parameters = ['foo' => 'bar', 'foobar' => 'foobaz'];
$state = new State($parameters);

$url = 'http://localhost:8080/login/check-instagram';
$redirect = 'https://api.instagram.com/oauth/authorize?redirect='.rawurlencode($url);

$request = $this->getRequest($url.'?state='.$state->encode());
$request = $this->getRequest($urlWithState);
$resource = $this->getMockBuilder(ResourceOwnerInterface::class)->getMock();

$utils = new OAuthUtils($this->getHttpUtils($url), $this->getAuthorizationChecker(false, $this->grantRule), $this->createFirewallMapMock(), true, $this->grantRule);
Expand Down Expand Up @@ -131,14 +128,12 @@ public function testGetAuthorizationUrlWithAuthenticatedFullyRule(): void
$this->assertNull($request->attributes->get('service'));
}

public function testGetServiceAuthUrlWithStateQueryParameters(): void
/**
* @dataProvider provideServiceAuthUrlsWithState
*/
public function testGetServiceAuthUrlWithStateQueryParameters(string $url, string $expectedResult): void
{
$parameters = ['foo' => 'bar', 'foobar' => 'foobaz'];
$state = new State($parameters);

$url = 'http://localhost:8080/service/instagram';

$request = $this->getRequest($url.'?state='.$state->encode());
$request = $this->getRequest($url);
$resource = $this->getMockBuilder(ResourceOwnerInterface::class)->getMock();
$resource
->expects($this->any())
Expand Down Expand Up @@ -166,7 +161,7 @@ public function testGetServiceAuthUrlWithStateQueryParameters(): void
->withConsecutive(['foo', 'bar'], ['foobar', 'foobaz']);

$this->assertEquals(
$url,
$expectedResult,
$utils->getServiceAuthUrl($request, $resource)
);
}
Expand Down Expand Up @@ -261,6 +256,41 @@ public function provideInvalidData(): iterable
yield 'missing "oauth_signature_method"' => [['oauth_consumer_key' => '', 'oauth_timestamp' => '', 'oauth_nonce' => '', 'oauth_version' => '']];
}

public function provideServiceAuthUrlsWithState(): iterable
{
$parameters = ['foo' => 'bar', 'foobar' => 'foobaz'];
$state = new State($parameters);

$url = 'http://localhost:8080/service/instagram';

yield 'state as an encoded string' => [$url.'?state='.$state->encode(), $url];

$stateAsArray = [];
foreach ($parameters as $key => $value) {
$stateAsArray[] = sprintf('state[%s]=%s', $key, rawurlencode($value));
}

yield 'state as an array' => [$url.'?'.implode('&', $stateAsArray), $url];
}

public function provideAuthorizationUrlsWithState(): iterable
{
$parameters = ['foo' => 'bar', 'foobar' => 'foobaz'];
$state = new State($parameters);

$url = 'http://localhost:8080/login/check-instagram';
$redirect = 'https://api.instagram.com/oauth/authorize?redirect='.rawurlencode($url);

yield 'state as an encoded string' => [$url, $url.'?state='.$state->encode(), $redirect];

$stateAsArray = [];
foreach ($parameters as $key => $value) {
$stateAsArray[] = sprintf('state[%s]=%s', $key, rawurlencode($value));
}

yield 'state as an array' => [$url, $url.'?'.implode('&', $stateAsArray), $redirect];
}

private function getRequest(string $url): Request
{
return Request::create($url, 'get', [], [], [], ['SERVER_PORT' => 8080]);
Expand Down

0 comments on commit fb6b7cb

Please sign in to comment.