diff --git a/src/Entities/Interfaces/ClientEntityInterface.php b/src/Entities/Interfaces/ClientEntityInterface.php index 4ed17162..7fde09d9 100644 --- a/src/Entities/Interfaces/ClientEntityInterface.php +++ b/src/Entities/Interfaces/ClientEntityInterface.php @@ -40,9 +40,11 @@ interface ClientEntityInterface public function setRedirectUri($redirectUri); /** - * Returns the registered redirect URI. + * Returns the registered redirect URI (as a string). * - * @return string + * Alternatively return an indexed array of redirect URIs. + * + * @return string|string[] */ public function getRedirectUri(); } diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index 14a46e35..f68913d8 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -173,8 +173,18 @@ abstract class AbstractGrant implements GrantTypeInterface // If a redirect URI is provided ensure it matches what is pre-registered $redirectUri = $this->getRequestParameter('redirect_uri', $request, null); - if ($redirectUri !== null && (strcmp($client->getRedirectUri(), $redirectUri) !== 0)) { - throw OAuthServerException::invalidClient(); + if ($redirectUri !== null) { + if ( + is_string($client->getRedirectUri()) + && (strcmp($client->getRedirectUri(), $redirectUri) !== 0) + ) { + throw OAuthServerException::invalidClient(); + } elseif ( + is_array($client->getRedirectUri()) + && in_array($redirectUri, $client->getRedirectUri()) === false + ) { + throw OAuthServerException::invalidClient(); + } } return $client; diff --git a/tests/Grant/AbstractGrantTest.php b/tests/Grant/AbstractGrantTest.php index 1161ebc4..cdde8764 100644 --- a/tests/Grant/AbstractGrantTest.php +++ b/tests/Grant/AbstractGrantTest.php @@ -185,6 +185,34 @@ class AbstractGrantTest extends \PHPUnit_Framework_TestCase $validateClientMethod->invoke($grantMock, $serverRequest, true, true); } + /** + * @expectedException \League\OAuth2\Server\Exception\OAuthServerException + */ + public function testValidateClientInvalidRedirectUriArray() + { + $client = new ClientEntity(); + $client->setRedirectUri(['http://foo/bar']); + $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); + $clientRepositoryMock->method('getClientEntity')->willReturn($client); + + /** @var AbstractGrant $grantMock */ + $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); + $grantMock->setClientRepository($clientRepositoryMock); + + $abstractGrantReflection = new \ReflectionClass($grantMock); + + $serverRequest = new ServerRequest(); + $serverRequest = $serverRequest->withParsedBody([ + 'client_id' => 'foo', + 'redirect_uri' => 'http://bar/foo', + ]); + + $validateClientMethod = $abstractGrantReflection->getMethod('validateClient'); + $validateClientMethod->setAccessible(true); + + $validateClientMethod->invoke($grantMock, $serverRequest, true, true); + } + /** * @expectedException \League\OAuth2\Server\Exception\OAuthServerException */