Compare commits

...

19 Commits
7.3.0 ... 7.3.3

Author SHA1 Message Date
Andrew Millington
c7f4998497 Update links 2019-03-29 18:19:35 +00:00
Andrew Millington
0a78236f17 Update changelog for version 7.3.3 2019-03-29 18:18:35 +00:00
Andrew Millington
a68f8001a4 Merge pull request #1006 from marc-mabe/fix-958-error_description
spec compliant 'error_description' but keep 'message' for BC
2019-03-29 16:28:33 +00:00
Marc Bennewitz
b88198a9a4 spec compliant 'error_description' but keep 'message' for BC 2019-03-29 16:00:26 +01:00
Andrew Millington
0227f14b7b Merge pull request #988 from lordrhodos/feature/test-cleanup
Cleanup: remove unused local variable $scopeEntity from ImplicitGrantTest
2019-01-22 20:59:33 +00:00
Patrick Rodacker
fad42a88fd removes unused local variable $scopeEntity from ImplicitGrantTest 2019-01-20 22:11:22 +01:00
Andrew Millington
2a16dbeb7f Merge pull request #981 from Sephster/support-php-7.3
Add support for PHP 7.3
2018-12-06 23:53:55 +00:00
sephster
faa350792a Add support for PHP 7.3 2018-12-06 23:46:28 +00:00
Andrew Millington
dc3181bbb0 Merge pull request #977 from spideyfusion/symfony-community-integration
Add Symfony community integration to README.md
2018-11-28 12:47:30 +00:00
Petar Obradović
1e3a7adb19 Add Symfony community integration to README.md 2018-11-28 12:24:16 +01:00
sephster
b71f382cd7 Update changelog 2018-11-21 21:42:43 +00:00
Andrew Millington
9783388523 Merge pull request #969 from ceeram/fix-bc-break
Fix bc breaking change
2018-11-21 21:38:37 +00:00
sephster
46493c461e Update changelog for 7.3.2 release 2018-11-21 21:29:55 +00:00
sephster
8b421818f2 Add blank line to better format 2018-11-21 21:26:54 +00:00
Marc Ypes
b09154af33 Add test to prove bc break 2018-11-16 13:29:47 +01:00
Marc Ypes
f1454cde36 Fix bc breaking change 2018-11-16 12:44:41 +01:00
Andrew Millington
f2cd3646ff Merge pull request #970 from Sephster/interface-revert
Revert Interface Change
2018-11-15 22:37:18 +00:00
sephster
7839a61170 Update changelog 2018-11-15 22:33:34 +00:00
sephster
443d7c485a Revert interface change so class can be extende 2018-11-15 22:22:08 +00:00
8 changed files with 97 additions and 36 deletions

View File

@@ -15,6 +15,7 @@ php:
- 7.0 - 7.0
- 7.1 - 7.1
- 7.2 - 7.2
- 7.3
install: install:
- composer update --no-interaction --prefer-dist $DEPENDENCIES - composer update --no-interaction --prefer-dist $DEPENDENCIES

View File

@@ -6,6 +6,23 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [Unreleased] ## [Unreleased]
## [7.3.3] - released 2019-03-29
### Added
- Added `error_description` to the error payload to improve standards compliance. The contents of this are copied from the existing `message` value. (PR #1006)
### Deprecated
- Error payload will not issue `message` value in the next major release (PR #1006)
## [7.3.2] - released 2018-11-21
### Fixed
- Revert setting keys on response type to be inside `getResponseType()` function instead of AuthorizationServer constructor (PR #969)
## [7.3.1] - released 2018-11-15
### Fixed
- Fix issue with previous release where interface had changed for the AuthorizationServer. Reverted to the previous interface while maintaining functionality changes (PR #970)
## [7.3.0] - released 2018-11-13 ## [7.3.0] - released 2018-11-13
### Changed ### Changed
@@ -422,7 +439,10 @@ Version 5 is a complete code rewrite.
- First major release - First major release
[Unreleased]: https://github.com/thephpleague/oauth2-server/compare/7.3.0...HEAD [Unreleased]: https://github.com/thephpleague/oauth2-server/compare/7.3.3...HEAD
[7.3.3]: https://github.com/thephpleague/oauth2-server/compare/7.3.2...7.3.3
[7.3.2]: https://github.com/thephpleague/oauth2-server/compare/7.3.1...7.3.2
[7.3.1]: https://github.com/thephpleague/oauth2-server/compare/7.3.0...7.3.1
[7.3.0]: https://github.com/thephpleague/oauth2-server/compare/7.2.0...7.3.0 [7.3.0]: https://github.com/thephpleague/oauth2-server/compare/7.2.0...7.3.0
[7.2.0]: https://github.com/thephpleague/oauth2-server/compare/7.1.1...7.2.0 [7.2.0]: https://github.com/thephpleague/oauth2-server/compare/7.1.1...7.2.0
[7.1.1]: https://github.com/thephpleague/oauth2-server/compare/7.1.0...7.1.1 [7.1.1]: https://github.com/thephpleague/oauth2-server/compare/7.1.0...7.1.1

View File

@@ -34,6 +34,7 @@ The following versions of PHP are supported:
* PHP 7.0 * PHP 7.0
* PHP 7.1 * PHP 7.1
* PHP 7.2 * PHP 7.2
* PHP 7.3
The `openssl` extension is also required. The `openssl` extension is also required.
@@ -69,6 +70,7 @@ We use [Travis CI](https://travis-ci.org/), [Scrutinizer](https://scrutinizer-ci
* [Laravel Passport](https://github.com/laravel/passport) * [Laravel Passport](https://github.com/laravel/passport)
* [OAuth 2 Server for CakePHP 3](https://github.com/uafrica/oauth-server) * [OAuth 2 Server for CakePHP 3](https://github.com/uafrica/oauth-server)
* [OAuth 2 Server for Expressive](https://github.com/zendframework/zend-expressive-authentication-oauth2) * [OAuth 2 Server for Expressive](https://github.com/zendframework/zend-expressive-authentication-oauth2)
* [Trikoder OAuth 2 Bundle (Symfony)](https://github.com/trikoder/oauth2-bundle)
## Changelog ## Changelog

View File

@@ -52,7 +52,7 @@ class AuthorizationServer implements EmitterAwareInterface
/** /**
* @var ResponseTypeInterface * @var ResponseTypeInterface
*/ */
protected $responseTypePrototype; protected $responseType;
/** /**
* @var ClientRepositoryInterface * @var ClientRepositoryInterface
@@ -87,7 +87,7 @@ class AuthorizationServer implements EmitterAwareInterface
* @param ScopeRepositoryInterface $scopeRepository * @param ScopeRepositoryInterface $scopeRepository
* @param CryptKey|string $privateKey * @param CryptKey|string $privateKey
* @param string|Key $encryptionKey * @param string|Key $encryptionKey
* @param null|ResponseTypeInterface $responseTypePrototype * @param null|ResponseTypeInterface $responseType
*/ */
public function __construct( public function __construct(
ClientRepositoryInterface $clientRepository, ClientRepositoryInterface $clientRepository,
@@ -95,7 +95,7 @@ class AuthorizationServer implements EmitterAwareInterface
ScopeRepositoryInterface $scopeRepository, ScopeRepositoryInterface $scopeRepository,
$privateKey, $privateKey,
$encryptionKey, $encryptionKey,
ResponseTypeInterface $responseTypePrototype = null ResponseTypeInterface $responseType = null
) { ) {
$this->clientRepository = $clientRepository; $this->clientRepository = $clientRepository;
$this->accessTokenRepository = $accessTokenRepository; $this->accessTokenRepository = $accessTokenRepository;
@@ -108,19 +108,13 @@ class AuthorizationServer implements EmitterAwareInterface
$this->privateKey = $privateKey; $this->privateKey = $privateKey;
$this->encryptionKey = $encryptionKey; $this->encryptionKey = $encryptionKey;
if ($responseTypePrototype === null) { if ($responseType === null) {
$responseTypePrototype = new BearerTokenResponse(); $responseType = new BearerTokenResponse();
} else { } else {
$responseTypePrototype = clone $responseTypePrototype; $responseType = clone $responseType;
} }
if ($responseTypePrototype instanceof AbstractResponseType) { $this->responseType = $responseType;
$responseTypePrototype->setPrivateKey($this->privateKey);
}
$responseTypePrototype->setEncryptionKey($this->encryptionKey);
$this->responseTypePrototype = $responseTypePrototype;
} }
/** /**
@@ -200,7 +194,7 @@ class AuthorizationServer implements EmitterAwareInterface
} }
$tokenResponse = $grantType->respondToAccessTokenRequest( $tokenResponse = $grantType->respondToAccessTokenRequest(
$request, $request,
$this->newResponseType(), $this->getResponseType(),
$this->grantTypeAccessTokenTTL[$grantType->getIdentifier()] $this->grantTypeAccessTokenTTL[$grantType->getIdentifier()]
); );
@@ -217,9 +211,17 @@ class AuthorizationServer implements EmitterAwareInterface
* *
* @return ResponseTypeInterface * @return ResponseTypeInterface
*/ */
protected function newResponseType() protected function getResponseType()
{ {
return clone $this->responseTypePrototype; $responseType = clone $this->responseType;
if ($responseType instanceof AbstractResponseType) {
$responseType->setPrivateKey($this->privateKey);
}
$responseType->setEncryptionKey($this->encryptionKey);
return $responseType;
} }
/** /**

View File

@@ -59,8 +59,8 @@ class OAuthServerException extends Exception
$this->hint = $hint; $this->hint = $hint;
$this->redirectUri = $redirectUri; $this->redirectUri = $redirectUri;
$this->payload = [ $this->payload = [
'error' => $errorType, 'error' => $errorType,
'message' => $message, 'error_description' => $message,
]; ];
if ($hint !== null) { if ($hint !== null) {
$this->payload['hint'] = $hint; $this->payload['hint'] = $hint;
@@ -74,7 +74,15 @@ class OAuthServerException extends Exception
*/ */
public function getPayload() public function getPayload()
{ {
return $this->payload; $payload = $this->payload;
// The "message" property is deprecated and replaced by "error_description"
// TODO: remove "message" property
if (isset($payload['error_description']) && !isset($payload['message'])) {
$payload['message'] = $payload['error_description'];
}
return $payload;
} }
/** /**

View File

@@ -91,7 +91,7 @@ class AuthorizationServerTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
} }
public function testNewDefaultResponseType() public function testGetResponseType()
{ {
$clientRepository = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepository = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
@@ -104,17 +104,50 @@ class AuthorizationServerTest extends TestCase
); );
$abstractGrantReflection = new \ReflectionClass($server); $abstractGrantReflection = new \ReflectionClass($server);
$method = $abstractGrantReflection->getMethod('newResponseType'); $method = $abstractGrantReflection->getMethod('getResponseType');
$method->setAccessible(true); $method->setAccessible(true);
$responseTypeA = $method->invoke($server); $this->assertInstanceOf(BearerTokenResponse::class, $method->invoke($server));
$responseTypeB = $method->invoke($server);
$this->assertInstanceOf(BearerTokenResponse::class, $responseTypeA);
$this->assertInstanceOf(BearerTokenResponse::class, $responseTypeB);
$this->assertNotSame($responseTypeA, $responseTypeB);
} }
public function testNewResponseTypeFromPrototype() public function testGetResponseTypeExtended()
{
$clientRepository = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$privateKey = 'file://' . __DIR__ . '/Stubs/private.key';
$encryptionKey = 'file://' . __DIR__ . '/Stubs/public.key';
$server = new class($clientRepository, $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(), $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(), $privateKey, $encryptionKey) extends AuthorizationServer {
protected function getResponseType()
{
$this->responseType = new class extends BearerTokenResponse {
/* @return null|CryptKey */
public function getPrivateKey()
{
return $this->privateKey;
}
public function getEncryptionKey()
{
return $this->encryptionKey;
}
};
return parent::getResponseType();
}
};
$abstractGrantReflection = new \ReflectionClass($server);
$method = $abstractGrantReflection->getMethod('getResponseType');
$method->setAccessible(true);
$responseType = $method->invoke($server);
$this->assertInstanceOf(BearerTokenResponse::class, $responseType);
// generated instances should have keys setup
$this->assertSame($privateKey, $responseType->getPrivateKey()->getKeyPath());
$this->assertSame($encryptionKey, $responseType->getEncryptionKey());
}
public function testMultipleRequestsGetDifferentResponseTypeInstances()
{ {
$privateKey = 'file://' . __DIR__ . '/Stubs/private.key'; $privateKey = 'file://' . __DIR__ . '/Stubs/private.key';
$encryptionKey = 'file://' . __DIR__ . '/Stubs/public.key'; $encryptionKey = 'file://' . __DIR__ . '/Stubs/public.key';
@@ -144,7 +177,7 @@ class AuthorizationServerTest extends TestCase
); );
$abstractGrantReflection = new \ReflectionClass($server); $abstractGrantReflection = new \ReflectionClass($server);
$method = $abstractGrantReflection->getMethod('newResponseType'); $method = $abstractGrantReflection->getMethod('getResponseType');
$method->setAccessible(true); $method->setAccessible(true);
$responseTypeA = $method->invoke($server); $responseTypeA = $method->invoke($server);

View File

@@ -285,7 +285,6 @@ class ImplicitGrantTest extends TestCase
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf(); $accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
$scopeEntity = new ScopeEntity();
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0); $scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
$grant = new ImplicitGrant(new \DateInterval('PT10M')); $grant = new ImplicitGrant(new \DateInterval('PT10M'));
@@ -313,7 +312,6 @@ class ImplicitGrantTest extends TestCase
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf(); $accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
$scopeEntity = new ScopeEntity();
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0); $scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
$grant = new ImplicitGrant(new \DateInterval('PT10M')); $grant = new ImplicitGrant(new \DateInterval('PT10M'));
@@ -339,7 +337,6 @@ class ImplicitGrantTest extends TestCase
$accessTokenRepositoryMock->expects($this->at(1))->method('persistNewAccessToken')->willReturnSelf(); $accessTokenRepositoryMock->expects($this->at(1))->method('persistNewAccessToken')->willReturnSelf();
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
$scopeEntity = new ScopeEntity();
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0); $scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
$grant = new ImplicitGrant(new \DateInterval('PT10M')); $grant = new ImplicitGrant(new \DateInterval('PT10M'));
@@ -368,7 +365,6 @@ class ImplicitGrantTest extends TestCase
$accessTokenRepositoryMock->method('persistNewAccessToken')->willThrowException(OAuthServerException::serverError('something bad happened')); $accessTokenRepositoryMock->method('persistNewAccessToken')->willThrowException(OAuthServerException::serverError('something bad happened'));
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
$scopeEntity = new ScopeEntity();
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0); $scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
$grant = new ImplicitGrant(new \DateInterval('PT10M')); $grant = new ImplicitGrant(new \DateInterval('PT10M'));
@@ -397,7 +393,6 @@ class ImplicitGrantTest extends TestCase
$accessTokenRepositoryMock->method('persistNewAccessToken')->willThrowException(UniqueTokenIdentifierConstraintViolationException::create()); $accessTokenRepositoryMock->method('persistNewAccessToken')->willThrowException(UniqueTokenIdentifierConstraintViolationException::create());
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
$scopeEntity = new ScopeEntity();
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0); $scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
$grant = new ImplicitGrant(new \DateInterval('PT10M')); $grant = new ImplicitGrant(new \DateInterval('PT10M'));

View File

@@ -104,7 +104,7 @@ class AuthorizationServerMiddlewareTest extends TestCase
$response = $exception->generateHttpResponse(new Response()); $response = $exception->generateHttpResponse(new Response());
$this->assertEquals(302, $response->getStatusCode()); $this->assertEquals(302, $response->getStatusCode());
$this->assertEquals('http://foo/bar?error=invalid_scope&message=The+requested+scope+is+invalid%2C+unknown%2C+or+malformed&hint=Check+the+%60test%60+scope', $this->assertEquals('http://foo/bar?error=invalid_scope&error_description=The+requested+scope+is+invalid%2C+unknown%2C+or+malformed&hint=Check+the+%60test%60+scope&message=The+requested+scope+is+invalid%2C+unknown%2C+or+malformed',
$response->getHeader('location')[0]); $response->getHeader('location')[0]);
} }
@@ -114,7 +114,7 @@ class AuthorizationServerMiddlewareTest extends TestCase
$response = $exception->generateHttpResponse(new Response(), true); $response = $exception->generateHttpResponse(new Response(), true);
$this->assertEquals(302, $response->getStatusCode()); $this->assertEquals(302, $response->getStatusCode());
$this->assertEquals('http://foo/bar#error=invalid_scope&message=The+requested+scope+is+invalid%2C+unknown%2C+or+malformed&hint=Check+the+%60test%60+scope', $this->assertEquals('http://foo/bar#error=invalid_scope&error_description=The+requested+scope+is+invalid%2C+unknown%2C+or+malformed&hint=Check+the+%60test%60+scope&message=The+requested+scope+is+invalid%2C+unknown%2C+or+malformed',
$response->getHeader('location')[0]); $response->getHeader('location')[0]);
} }
} }