Skip to content

Commit

Permalink
Merge v9.0.0-WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Sephster committed Oct 25, 2023
2 parents abe3157 + ef5ea77 commit cd6fae1
Show file tree
Hide file tree
Showing 88 changed files with 2,303 additions and 2,561 deletions.
34 changes: 32 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,34 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Added
- GrantTypeInterface has a new function, `revokeRefreshTokens()` for enabling or disabling refresh tokens after use (PR #1375)
- A CryptKeyInterface to allow developers to change the CryptKey implementation with greater ease (PR #1044)
- The authorization server can now finalize scopes when a client uses a refresh token (PR #1094)
- An AuthorizationRequestInterface to make it easier to extend the AuthorizationRequest (PR #1110)
- Added function `getKeyContents()` to the `CryptKeyInterface` (PR #1375)

### Fixed
- If a refresh token has expired, been revoked, cannot be decrypted, or does not belong to the correct client, the server will now issue an `invalid_grant` error and a HTTP 400 response. In previous versions the server incorrectly issued an `invalid_request` and HTTP 401 response (PR #1042) (PR #1082)

### Changed
- Authorization Request objects are now created through the factory method, `createAuthorizationRequest()` (PR #1111)
- Changed parameters for `finalizeScopes()` to allow a reference to an auth code ID (PR #1112)

### Removed
- Removed message property from OAuthException HTTP response. Now just use error_description as per the OAuth 2 spec (PR #1375)

## [8.5.4] - released 2023-08-25
### Added
- Support for league/uri ^7.0 (PR #1367)

## [8.5.3] - released 2023-07-06
### Security
- If a key string is provided to the CryptKey constructor with an invalid
passphrase, the LogicException message generated will expose the given key.
The key is no longer leaked via this exception (PR #1353)

## [8.5.2] - released 2023-06-16
### Changed
- Bumped the versions for laminas/diactoros and psr/http-message to support
PSR-7 v2.0 (PR #1339)
Expand Down Expand Up @@ -107,7 +135,6 @@ a PKCE downgrade attack (PR #1326)
- If you provide a valid redirect_uri with the auth code grant and an invalid scope, the server will use the given
redirect_uri instead of the default client redirect uri (PR #1126)


## [8.1.0] - released 2020-04-29

### Added
Expand Down Expand Up @@ -594,7 +621,10 @@ Version 5 is a complete code rewrite.

- First major release

[Unreleased]: https://github.com/thephpleague/oauth2-server/compare/8.5.1...HEAD
[Unreleased]: https://github.com/thephpleague/oauth2-server/compare/8.5.4...HEAD
[8.5.4]: https://github.com/thephpleague/oauth2-server/compare/8.5.3...8.5.4
[8.5.3]: https://github.com/thephpleague/oauth2-server/compare/8.5.2...8.5.3
[8.5.2]: https://github.com/thephpleague/oauth2-server/compare/8.5.1...8.5.2
[8.5.1]: https://github.com/thephpleague/oauth2-server/compare/8.5.0...8.5.1
[8.5.0]: https://github.com/thephpleague/oauth2-server/compare/8.4.1...8.5.0
[8.4.1]: https://github.com/thephpleague/oauth2-server/compare/8.4.0...8.4.1
Expand Down
25 changes: 19 additions & 6 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,24 @@
"php": "^8.0",
"ext-openssl": "*",
"league/event": "^3.0",
"league/uri": "^6.7",
"league/uri": "^6.7 || ^7.0",
"lcobucci/jwt": "^4.3 || ^5.0",
"psr/http-message": "^1.0.1 || ^2.0",
"defuse/php-encryption": "^2.3",
"defuse/php-encryption": "^2.3.1",
"lcobucci/clock": "^2.2 || ^3.0"
},
"require-dev": {
"phpunit/phpunit": "^9.6.6",
"phpunit/phpunit": "^9.6.11",
"laminas/laminas-diactoros": "^3.0.0",
"phpstan/phpstan": "^0.12.57",
"phpstan/phpstan-phpunit": "^0.12.16",
"roave/security-advisories": "dev-master"
"phpstan/phpstan": "^1.10.26",
"phpstan/phpstan-phpunit": "^1.3.14",
"roave/security-advisories": "dev-master",
"phpstan/extension-installer": "^1.3",
"phpstan/phpstan-deprecation-rules": "^1.1",
"phpstan/phpstan-strict-rules": "^1.5",
"slevomat/coding-standard": "^8.13",
"php-parallel-lint/php-parallel-lint": "^1.3",
"squizlabs/php_codesniffer": "^3.7"
},
"repositories": [
{
Expand Down Expand Up @@ -69,5 +75,12 @@
"psr-4": {
"LeagueTests\\": "tests/"
}
},
"config": {
"allow-plugins": {
"ocramius/package-versions": true,
"phpstan/extension-installer": true,
"dealerdirect/phpcodesniffer-composer-installer": false
}
}
}
8 changes: 0 additions & 8 deletions phpstan.neon

This file was deleted.

10 changes: 10 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
parameters:
level: 8
paths:
- src
- tests
ignoreErrors:
-
message: '#Call to an undefined method League\\OAuth2\\Server\\ResponseTypes\\ResponseTypeInterface::getAccessToken\(\)\.#'
path: tests/Grant/ClientCredentialsGrantTest.php
- '#Return type \(League\\Event\\EmitterInterface\|null\) of method LeagueTests\\Stubs\\GrantType::getEmitter\(\) should be covariant with return type \(League\\Event\\EmitterInterface\) of method League\\Event\\EmitterAwareInterface::getEmitter\(\)#'
126 changes: 32 additions & 94 deletions src/AuthorizationServer.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

/**
* @author Alex Bilbie <[email protected]>
* @copyright Copyright (c) Alex Bilbie
Expand All @@ -7,6 +8,8 @@
* @link https://github.com/thephpleague/oauth2-server
*/

declare(strict_types=1);

namespace League\OAuth2\Server;

use DateInterval;
Expand All @@ -18,7 +21,7 @@
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
use League\OAuth2\Server\Repositories\ClientRepositoryInterface;
use League\OAuth2\Server\Repositories\ScopeRepositoryInterface;
use League\OAuth2\Server\RequestTypes\AuthorizationRequest;
use League\OAuth2\Server\RequestTypes\AuthorizationRequestInterface;
use League\OAuth2\Server\ResponseTypes\AbstractResponseType;
use League\OAuth2\Server\ResponseTypes\BearerTokenResponse;
use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface;
Expand All @@ -32,81 +35,38 @@ class AuthorizationServer implements EmitterAwareInterface
/**
* @var GrantTypeInterface[]
*/
protected $enabledGrantTypes = [];
protected array $enabledGrantTypes = [];

/**
* @var DateInterval[]
*/
protected $grantTypeAccessTokenTTL = [];
protected array $grantTypeAccessTokenTTL = [];

/**
* @var CryptKey
*/
protected $privateKey;
protected CryptKeyInterface $privateKey;

/**
* @var CryptKey
*/
protected $publicKey;
protected CryptKeyInterface $publicKey;

/**
* @var ResponseTypeInterface
*/
protected $responseType;
protected ResponseTypeInterface $responseType;

/**
* @var ClientRepositoryInterface
*/
private $clientRepository;
private string|Key $encryptionKey;

/**
* @var AccessTokenRepositoryInterface
*/
private $accessTokenRepository;
private string $defaultScope = '';

/**
* @var ScopeRepositoryInterface
*/
private $scopeRepository;
private bool $revokeRefreshTokens = true;

/**
* @var string|Key
*/
private $encryptionKey;

/**
* @var string
*/
private $defaultScope = '';

/**
* @var bool
*/
private $revokeRefreshTokens = true;

/**
* New server instance.
*
* @param ClientRepositoryInterface $clientRepository
* @param AccessTokenRepositoryInterface $accessTokenRepository
* @param ScopeRepositoryInterface $scopeRepository
* @param CryptKey|string $privateKey
* @param string|Key $encryptionKey
* @param null|ResponseTypeInterface $responseType
* New server instance
*/
public function __construct(
ClientRepositoryInterface $clientRepository,
AccessTokenRepositoryInterface $accessTokenRepository,
ScopeRepositoryInterface $scopeRepository,
$privateKey,
$encryptionKey,
ResponseTypeInterface $responseType = null
private ClientRepositoryInterface $clientRepository,
private AccessTokenRepositoryInterface $accessTokenRepository,
private ScopeRepositoryInterface $scopeRepository,
CryptKeyInterface|string $privateKey,
Key|string $encryptionKey,
ResponseTypeInterface|null $responseType = null
) {
$this->clientRepository = $clientRepository;
$this->accessTokenRepository = $accessTokenRepository;
$this->scopeRepository = $scopeRepository;

if ($privateKey instanceof CryptKey === false) {
if ($privateKey instanceof CryptKeyInterface === false) {
$privateKey = new CryptKey($privateKey);
}

Expand All @@ -123,12 +83,9 @@ public function __construct(
}

/**
* Enable a grant type on the server.
*
* @param GrantTypeInterface $grantType
* @param null|DateInterval $accessTokenTTL
* Enable a grant type on the server
*/
public function enableGrantType(GrantTypeInterface $grantType, DateInterval $accessTokenTTL = null)
public function enableGrantType(GrantTypeInterface $grantType, DateInterval|null $accessTokenTTL = null): void
{
if ($accessTokenTTL === null) {
$accessTokenTTL = new DateInterval('PT1H');
Expand All @@ -150,13 +107,9 @@ public function enableGrantType(GrantTypeInterface $grantType, DateInterval $acc
/**
* Validate an authorization request
*
* @param ServerRequestInterface $request
*
* @throws OAuthServerException
*
* @return AuthorizationRequest
*/
public function validateAuthorizationRequest(ServerRequestInterface $request)
public function validateAuthorizationRequest(ServerRequestInterface $request): AuthorizationRequestInterface
{
foreach ($this->enabledGrantTypes as $grantType) {
if ($grantType->canRespondToAuthorizationRequest($request)) {
Expand All @@ -169,14 +122,11 @@ public function validateAuthorizationRequest(ServerRequestInterface $request)

/**
* Complete an authorization request
*
* @param AuthorizationRequest $authRequest
* @param ResponseInterface $response
*
* @return ResponseInterface
*/
public function completeAuthorizationRequest(AuthorizationRequest $authRequest, ResponseInterface $response)
{
public function completeAuthorizationRequest(
AuthorizationRequestInterface $authRequest,
ResponseInterface $response
): ResponseInterface {
return $this->enabledGrantTypes[$authRequest->getGrantTypeId()]
->completeAuthorizationRequest($authRequest)
->generateHttpResponse($response);
Expand All @@ -185,39 +135,31 @@ public function completeAuthorizationRequest(AuthorizationRequest $authRequest,
/**
* Return an access token response.
*
* @param ServerRequestInterface $request
* @param ResponseInterface $response
*
* @throws OAuthServerException
*
* @return ResponseInterface
*/
public function respondToAccessTokenRequest(ServerRequestInterface $request, ResponseInterface $response)
public function respondToAccessTokenRequest(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
{
foreach ($this->enabledGrantTypes as $grantType) {
if (!$grantType->canRespondToAccessTokenRequest($request)) {
continue;
}

$tokenResponse = $grantType->respondToAccessTokenRequest(
$request,
$this->getResponseType(),
$this->grantTypeAccessTokenTTL[$grantType->getIdentifier()]
);

if ($tokenResponse instanceof ResponseTypeInterface) {
return $tokenResponse->generateHttpResponse($response);
}
return $tokenResponse->generateHttpResponse($response);
}

throw OAuthServerException::unsupportedGrantType();
}

/**
* Get the token type that grants will return in the HTTP response.
*
* @return ResponseTypeInterface
*/
protected function getResponseType()
protected function getResponseType(): ResponseTypeInterface
{
$responseType = clone $this->responseType;

Expand All @@ -232,18 +174,14 @@ protected function getResponseType()

/**
* Set the default scope for the authorization server.
*
* @param string $defaultScope
*/
public function setDefaultScope($defaultScope)
public function setDefaultScope(string $defaultScope): void
{
$this->defaultScope = $defaultScope;
}

/**
* Sets whether to revoke refresh tokens or not (for all grant types).
*
* @param bool $revokeRefreshTokens
*/
public function revokeRefreshTokens(bool $revokeRefreshTokens): void
{
Expand Down
13 changes: 6 additions & 7 deletions src/AuthorizationValidators/AuthorizationValidatorInterface.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

/**
* @author Alex Bilbie <[email protected]>
* @copyright Copyright (c) Alex Bilbie
Expand All @@ -7,19 +8,17 @@
* @link https://github.com/thephpleague/oauth2-server
*/

declare(strict_types=1);

namespace League\OAuth2\Server\AuthorizationValidators;

use Psr\Http\Message\ServerRequestInterface;

interface AuthorizationValidatorInterface
{
/**
* Determine the access token in the authorization header and append OAUth properties to the request
* as attributes.
*
* @param ServerRequestInterface $request
*
* @return ServerRequestInterface
* Determine the access token in the authorization header and append OAUth
* properties to the request as attributes.
*/
public function validateAuthorization(ServerRequestInterface $request);
public function validateAuthorization(ServerRequestInterface $request): ServerRequestInterface;
}
Loading

0 comments on commit cd6fae1

Please sign in to comment.