mirror of
https://github.com/elyby/oauth2-server.git
synced 2025-05-31 14:12:07 +05:30
Compare commits
19 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
c7f4998497 | ||
|
0a78236f17 | ||
|
a68f8001a4 | ||
|
b88198a9a4 | ||
|
0227f14b7b | ||
|
fad42a88fd | ||
|
2a16dbeb7f | ||
|
faa350792a | ||
|
dc3181bbb0 | ||
|
1e3a7adb19 | ||
|
b71f382cd7 | ||
|
9783388523 | ||
|
46493c461e | ||
|
8b421818f2 | ||
|
b09154af33 | ||
|
f1454cde36 | ||
|
f2cd3646ff | ||
|
7839a61170 | ||
|
443d7c485a |
@@ -15,6 +15,7 @@ php:
|
||||
- 7.0
|
||||
- 7.1
|
||||
- 7.2
|
||||
- 7.3
|
||||
|
||||
install:
|
||||
- composer update --no-interaction --prefer-dist $DEPENDENCIES
|
||||
|
22
CHANGELOG.md
22
CHANGELOG.md
@@ -6,6 +6,23 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
||||
|
||||
## [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
|
||||
|
||||
### Changed
|
||||
@@ -422,7 +439,10 @@ Version 5 is a complete code rewrite.
|
||||
|
||||
- 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.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
|
||||
|
@@ -34,6 +34,7 @@ The following versions of PHP are supported:
|
||||
* PHP 7.0
|
||||
* PHP 7.1
|
||||
* PHP 7.2
|
||||
* PHP 7.3
|
||||
|
||||
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)
|
||||
* [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)
|
||||
* [Trikoder OAuth 2 Bundle (Symfony)](https://github.com/trikoder/oauth2-bundle)
|
||||
|
||||
## Changelog
|
||||
|
||||
|
@@ -52,7 +52,7 @@ class AuthorizationServer implements EmitterAwareInterface
|
||||
/**
|
||||
* @var ResponseTypeInterface
|
||||
*/
|
||||
protected $responseTypePrototype;
|
||||
protected $responseType;
|
||||
|
||||
/**
|
||||
* @var ClientRepositoryInterface
|
||||
@@ -87,7 +87,7 @@ class AuthorizationServer implements EmitterAwareInterface
|
||||
* @param ScopeRepositoryInterface $scopeRepository
|
||||
* @param CryptKey|string $privateKey
|
||||
* @param string|Key $encryptionKey
|
||||
* @param null|ResponseTypeInterface $responseTypePrototype
|
||||
* @param null|ResponseTypeInterface $responseType
|
||||
*/
|
||||
public function __construct(
|
||||
ClientRepositoryInterface $clientRepository,
|
||||
@@ -95,7 +95,7 @@ class AuthorizationServer implements EmitterAwareInterface
|
||||
ScopeRepositoryInterface $scopeRepository,
|
||||
$privateKey,
|
||||
$encryptionKey,
|
||||
ResponseTypeInterface $responseTypePrototype = null
|
||||
ResponseTypeInterface $responseType = null
|
||||
) {
|
||||
$this->clientRepository = $clientRepository;
|
||||
$this->accessTokenRepository = $accessTokenRepository;
|
||||
@@ -108,19 +108,13 @@ class AuthorizationServer implements EmitterAwareInterface
|
||||
$this->privateKey = $privateKey;
|
||||
$this->encryptionKey = $encryptionKey;
|
||||
|
||||
if ($responseTypePrototype === null) {
|
||||
$responseTypePrototype = new BearerTokenResponse();
|
||||
if ($responseType === null) {
|
||||
$responseType = new BearerTokenResponse();
|
||||
} else {
|
||||
$responseTypePrototype = clone $responseTypePrototype;
|
||||
$responseType = clone $responseType;
|
||||
}
|
||||
|
||||
if ($responseTypePrototype instanceof AbstractResponseType) {
|
||||
$responseTypePrototype->setPrivateKey($this->privateKey);
|
||||
}
|
||||
|
||||
$responseTypePrototype->setEncryptionKey($this->encryptionKey);
|
||||
|
||||
$this->responseTypePrototype = $responseTypePrototype;
|
||||
$this->responseType = $responseType;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -200,7 +194,7 @@ class AuthorizationServer implements EmitterAwareInterface
|
||||
}
|
||||
$tokenResponse = $grantType->respondToAccessTokenRequest(
|
||||
$request,
|
||||
$this->newResponseType(),
|
||||
$this->getResponseType(),
|
||||
$this->grantTypeAccessTokenTTL[$grantType->getIdentifier()]
|
||||
);
|
||||
|
||||
@@ -217,9 +211,17 @@ class AuthorizationServer implements EmitterAwareInterface
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -59,8 +59,8 @@ class OAuthServerException extends Exception
|
||||
$this->hint = $hint;
|
||||
$this->redirectUri = $redirectUri;
|
||||
$this->payload = [
|
||||
'error' => $errorType,
|
||||
'message' => $message,
|
||||
'error' => $errorType,
|
||||
'error_description' => $message,
|
||||
];
|
||||
if ($hint !== null) {
|
||||
$this->payload['hint'] = $hint;
|
||||
@@ -74,7 +74,15 @@ class OAuthServerException extends Exception
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -91,7 +91,7 @@ class AuthorizationServerTest extends TestCase
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
}
|
||||
|
||||
public function testNewDefaultResponseType()
|
||||
public function testGetResponseType()
|
||||
{
|
||||
$clientRepository = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
|
||||
|
||||
@@ -104,17 +104,50 @@ class AuthorizationServerTest extends TestCase
|
||||
);
|
||||
|
||||
$abstractGrantReflection = new \ReflectionClass($server);
|
||||
$method = $abstractGrantReflection->getMethod('newResponseType');
|
||||
$method = $abstractGrantReflection->getMethod('getResponseType');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$responseTypeA = $method->invoke($server);
|
||||
$responseTypeB = $method->invoke($server);
|
||||
$this->assertInstanceOf(BearerTokenResponse::class, $responseTypeA);
|
||||
$this->assertInstanceOf(BearerTokenResponse::class, $responseTypeB);
|
||||
$this->assertNotSame($responseTypeA, $responseTypeB);
|
||||
$this->assertInstanceOf(BearerTokenResponse::class, $method->invoke($server));
|
||||
}
|
||||
|
||||
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';
|
||||
$encryptionKey = 'file://' . __DIR__ . '/Stubs/public.key';
|
||||
@@ -144,7 +177,7 @@ class AuthorizationServerTest extends TestCase
|
||||
);
|
||||
|
||||
$abstractGrantReflection = new \ReflectionClass($server);
|
||||
$method = $abstractGrantReflection->getMethod('newResponseType');
|
||||
$method = $abstractGrantReflection->getMethod('getResponseType');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$responseTypeA = $method->invoke($server);
|
||||
|
@@ -285,7 +285,6 @@ class ImplicitGrantTest extends TestCase
|
||||
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
|
||||
|
||||
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
|
||||
$scopeEntity = new ScopeEntity();
|
||||
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
|
||||
|
||||
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
|
||||
@@ -313,7 +312,6 @@ class ImplicitGrantTest extends TestCase
|
||||
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
|
||||
|
||||
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
|
||||
$scopeEntity = new ScopeEntity();
|
||||
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
|
||||
|
||||
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
|
||||
@@ -339,7 +337,6 @@ class ImplicitGrantTest extends TestCase
|
||||
$accessTokenRepositoryMock->expects($this->at(1))->method('persistNewAccessToken')->willReturnSelf();
|
||||
|
||||
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
|
||||
$scopeEntity = new ScopeEntity();
|
||||
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
|
||||
|
||||
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
|
||||
@@ -368,7 +365,6 @@ class ImplicitGrantTest extends TestCase
|
||||
$accessTokenRepositoryMock->method('persistNewAccessToken')->willThrowException(OAuthServerException::serverError('something bad happened'));
|
||||
|
||||
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
|
||||
$scopeEntity = new ScopeEntity();
|
||||
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
|
||||
|
||||
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
|
||||
@@ -397,7 +393,6 @@ class ImplicitGrantTest extends TestCase
|
||||
$accessTokenRepositoryMock->method('persistNewAccessToken')->willThrowException(UniqueTokenIdentifierConstraintViolationException::create());
|
||||
|
||||
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
|
||||
$scopeEntity = new ScopeEntity();
|
||||
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
|
||||
|
||||
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
|
||||
|
@@ -104,7 +104,7 @@ class AuthorizationServerMiddlewareTest extends TestCase
|
||||
$response = $exception->generateHttpResponse(new Response());
|
||||
|
||||
$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]);
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ class AuthorizationServerMiddlewareTest extends TestCase
|
||||
$response = $exception->generateHttpResponse(new Response(), true);
|
||||
|
||||
$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]);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user