Skip to content

Commit fac8a9b

Browse files
committed
Merge in v9 branch
2 parents abfa828 + 0610336 commit fac8a9b

23 files changed

Lines changed: 392 additions & 171 deletions

.github/workflows/backwards-compatibility.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ jobs:
1414
uses: "actions/checkout@v2"
1515
with:
1616
fetch-depth: 0
17-
17+
- name: Fix git safe.directory in container
18+
run: mkdir -p /home/runner/work/_temp/_github_home && printf "[safe]\n\tdirectory = /github/workspace" > /home/runner/work/_temp/_github_home/.gitconfig
1819
- name: "Backwards Compatibility Check"
1920
uses: docker://nyholm/roave-bc-check-ga
2021
with:

.github/workflows/tests.yml

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,29 @@ on:
88

99
jobs:
1010
tests:
11-
runs-on: ubuntu-latest
12-
1311
strategy:
1412
fail-fast: false
1513
matrix:
16-
php: [7.4, 8.0, 8.1]
14+
php: [8.1, 8.2]
15+
os: [ubuntu-22.04]
1716
stability: [prefer-lowest, prefer-stable]
17+
include:
18+
- os: ubuntu-20.04
19+
php: 8.0
20+
stability: prefer-lowest
21+
- os: ubuntu-20.04
22+
php: 8.0
23+
stability: prefer-stable
24+
25+
runs-on: ${{ matrix.os }}
1826

1927
name: PHP ${{ matrix.php }} - ${{ matrix.stability }}
2028

2129
steps:
2230
- name: Checkout code
23-
uses: actions/checkout@v2
31+
uses: actions/checkout@v3
32+
with:
33+
fetch-depth: 0
2434

2535
- name: Setup PHP
2636
uses: shivammathur/setup-php@v2
@@ -30,13 +40,17 @@ jobs:
3040
coverage: pcov
3141

3242
- name: Install dependencies
33-
run: composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress
43+
run:
44+
composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress
45+
46+
- name: Install Scrutinizer/Ocular
47+
run:
48+
composer global require scrutinizer/ocular
3449

3550
- name: Execute tests
3651
run: vendor/bin/phpunit --verbose --coverage-clover=coverage.clover
3752

3853
- name: Code coverage
39-
if: ${{ github.ref == 'refs/heads/master' && matrix.php != 8.0 && github.repository == 'thephpleague/oauth2-server' }}
40-
run: |
41-
wget https://scrutinizer-ci.com/ocular.phar
42-
php ocular.phar code-coverage:upload --format=php-clover coverage.clover
54+
if: ${{ github.ref == 'refs/heads/master' && github.repository == 'thephpleague/oauth2-server' }}
55+
run:
56+
~/.composer/vendor/bin/ocular code-coverage:upload --format=php-clover coverage.clover

CHANGELOG.md

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,49 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
2222
### Removed
2323
- Removed message property from OAuthException HTTP response. Now just use error_description as per the OAuth 2 spec (PR #1375)
2424

25-
### [8.3.6] - released 2022-11-14
25+
## [8.5.4] - released 2023-08-25
26+
### Added
27+
- Support for league/uri ^7.0 (PR #1367)
28+
29+
## [8.5.3] - released 2023-07-06
30+
### Security
31+
- If a key string is provided to the CryptKey constructor with an invalid
32+
passphrase, the LogicException message generated will expose the given key.
33+
The key is no longer leaked via this exception (PR #1353)
34+
35+
## [8.5.2] - released 2023-06-16
36+
### Changed
37+
- Bumped the versions for laminas/diactoros and psr/http-message to support
38+
PSR-7 v2.0 (PR #1339)
39+
40+
## [8.5.1] - released 2023-04-04
41+
### Fixed
42+
- Fixed PHP version constraints and lcobucci/clock version constraint to support PHP 8.1 (PR #1336)
43+
44+
## [8.5.0] - released 2023-04-03
45+
### Added
46+
- Support for PHP 8.1 and 8.2 (PR #1333)
47+
48+
### Removed
49+
- Support PHP 7.2, 7.3, and 7.4 (PR #1333)
50+
51+
## [8.4.1] - released 2023-03-22
52+
### Fixed
53+
- Fix deprecation notices for PHP 8.x (PR #1329)
54+
55+
## [8.4.0] - released 2023-02-15
56+
### Added
57+
- You can now set a leeway for time drift between servers when validating a JWT (PR #1304)
58+
59+
### Security
60+
- Access token requests that contain a code_verifier but are not bound to a code_challenge will be rejected to prevent
61+
a PKCE downgrade attack (PR #1326)
62+
63+
## [8.3.6] - released 2022-11-14
2664
### Fixed
2765
- Use LooseValidAt instead of StrictValidAt so that users aren't forced to use claims such as NBF in their JWT tokens (PR #1312)
2866

29-
### [8.3.5] - released 2022-05-12
67+
## [8.3.5] - released 2022-05-12
3068
### Fixed
3169
- Use InMemory::plainText('empty', 'empty') instead of InMemory::plainText('') to avoid [new empty string exception](https://github.com/lcobucci/jwt/pull/833) thrown by lcobucci/jwt (PR #1282)
3270

@@ -583,7 +621,14 @@ Version 5 is a complete code rewrite.
583621

584622
- First major release
585623

586-
[Unreleased]: https://github.com/thephpleague/oauth2-server/compare/8.3.6...HEAD
624+
[Unreleased]: https://github.com/thephpleague/oauth2-server/compare/8.5.4...HEAD
625+
[8.5.4]: https://github.com/thephpleague/oauth2-server/compare/8.5.3...8.5.4
626+
[8.5.3]: https://github.com/thephpleague/oauth2-server/compare/8.5.2...8.5.3
627+
[8.5.2]: https://github.com/thephpleague/oauth2-server/compare/8.5.1...8.5.2
628+
[8.5.1]: https://github.com/thephpleague/oauth2-server/compare/8.5.0...8.5.1
629+
[8.5.0]: https://github.com/thephpleague/oauth2-server/compare/8.4.1...8.5.0
630+
[8.4.1]: https://github.com/thephpleague/oauth2-server/compare/8.4.0...8.4.1
631+
[8.4.0]: https://github.com/thephpleague/oauth2-server/compare/8.3.6...8.4.0
587632
[8.3.6]: https://github.com/thephpleague/oauth2-server/compare/8.3.5...8.3.6
588633
[8.3.5]: https://github.com/thephpleague/oauth2-server/compare/8.3.4...8.3.5
589634
[8.3.4]: https://github.com/thephpleague/oauth2-server/compare/8.3.3...8.3.4

README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,9 @@ This library was created by Alex Bilbie. Find him on Twitter at [@alexbilbie](ht
3030

3131
The latest version of this package supports the following versions of PHP:
3232

33-
* PHP 7.2
34-
* PHP 7.3
35-
* PHP 7.4
3633
* PHP 8.0
34+
* PHP 8.1
35+
* PHP 8.2
3736

3837
The `openssl` and `json` extensions are also required.
3938

composer.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@
44
"homepage": "https://oauth2.thephpleague.com/",
55
"license": "MIT",
66
"require": {
7-
"php": "^7.4 || ^8.0",
7+
"php": "^8.0",
88
"ext-openssl": "*",
99
"league/event": "^2.2",
10-
"league/uri": "^6.4",
11-
"lcobucci/jwt": "^4.1.5",
12-
"psr/http-message": "^1.0.1",
10+
"league/uri": "^6.7 || ^7.0",
11+
"lcobucci/jwt": "^4.3 || ^5.0",
12+
"psr/http-message": "^1.0.1 || ^2.0",
1313
"defuse/php-encryption": "^2.3.1",
14-
"ext-json": "*"
14+
"lcobucci/clock": "^2.2 || ^3.0"
1515
},
1616
"require-dev": {
17-
"phpunit/phpunit": "^9.5.11",
18-
"laminas/laminas-diactoros": "^2.8.0",
17+
"phpunit/phpunit": "^9.6.6",
18+
"laminas/laminas-diactoros": "^3.0.0",
1919
"phpstan/phpstan": "^1.10.26",
2020
"phpstan/phpstan-phpunit": "^1.3.14",
2121
"roave/security-advisories": "dev-master",

examples/public/client_credentials.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,20 +53,16 @@
5353
]);
5454

5555
$app->post('/access_token', function (ServerRequestInterface $request, ResponseInterface $response) use ($app) {
56-
5756
/* @var \League\OAuth2\Server\AuthorizationServer $server */
5857
$server = $app->getContainer()->get(AuthorizationServer::class);
5958

6059
try {
61-
6260
// Try to respond to the request
6361
return $server->respondToAccessTokenRequest($request, $response);
6462
} catch (OAuthServerException $exception) {
65-
6663
// All instances of OAuthServerException can be formatted into a HTTP response
6764
return $exception->generateHttpResponse($response);
6865
} catch (\Exception $exception) {
69-
7066
// Unknown exception
7167
$body = new Stream('php://temp', 'r+');
7268
$body->write($exception->getMessage());

examples/public/password.php

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
$app = new App([
1818
// Add the authorization server to the DI container
1919
AuthorizationServer::class => function () {
20-
2120
// Setup the authorization server
2221
$server = new AuthorizationServer(
2322
new ClientRepository(), // instance of ClientRepositoryInterface
@@ -46,20 +45,16 @@
4645
$app->post(
4746
'/access_token',
4847
function (ServerRequestInterface $request, ResponseInterface $response) use ($app) {
49-
5048
/* @var \League\OAuth2\Server\AuthorizationServer $server */
5149
$server = $app->getContainer()->get(AuthorizationServer::class);
5250

5351
try {
54-
5552
// Try to respond to the access token request
5653
return $server->respondToAccessTokenRequest($request, $response);
5754
} catch (OAuthServerException $exception) {
58-
5955
// All instances of OAuthServerException can be converted to a PSR-7 response
6056
return $exception->generateHttpResponse($response);
6157
} catch (\Exception $exception) {
62-
6358
// Catch unexpected exceptions
6459
$body = $response->getBody();
6560
$body->write($exception->getMessage());

phpstan.neon.dist

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,3 @@ parameters:
88
message: '#Call to an undefined method League\\OAuth2\\Server\\ResponseTypes\\ResponseTypeInterface::getAccessToken\(\)\.#'
99
path: tests/Grant/ClientCredentialsGrantTest.php
1010
- '#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\(\)#'
11-
- '#Method League\\OAuth2\\Server\\Grant\\AbstractGrant::issueAccessToken\(\) should return League\\OAuth2\\Server\\Entities\\AccessTokenEntityInterface but return statement is missing\.#'
12-
- '#Method League\\OAuth2\\Server\\Grant\\AbstractGrant::issueAuthCode\(\) should return League\\OAuth2\\Server\\Entities\\AuthCodeEntityInterface but return statement is missing\.#'
13-
- '#Method League\\OAuth2\\Server\\Grant\\AbstractGrant::issueRefreshToken\(\) should return League\\OAuth2\\Server\\Entities\\RefreshTokenEntityInterface\|null but return statement is missing\.#'

phpunit.xml.dist

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<phpunit colors="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" stopOnError="true"
3-
stopOnFailure="true" stopOnIncomplete="false" stopOnSkipped="false" bootstrap="tests/Bootstrap.php">
4-
<testsuites>
5-
<testsuite name="Tests">
6-
<directory>./tests/</directory>
7-
</testsuite>
8-
</testsuites>
9-
<filter>
10-
<whitelist addUncoveredFilesFromWhitelist="true">
11-
<directory suffix=".php">src</directory>
12-
</whitelist>
13-
</filter>
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"
4+
colors="true"
5+
stopOnError="true"
6+
stopOnFailure="true"
7+
stopOnIncomplete="false"
8+
stopOnSkipped="false"
9+
bootstrap="tests/Bootstrap.php"
10+
>
11+
<coverage includeUncoveredFiles="true">
12+
<include>
13+
<directory suffix=".php">src</directory>
14+
</include>
15+
</coverage>
16+
<testsuites>
17+
<testsuite name="Tests">
18+
<directory>./tests/</directory>
19+
</testsuite>
20+
</testsuites>
1421
</phpunit>

src/AuthorizationValidators/BearerTokenValidator.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
namespace League\OAuth2\Server\AuthorizationValidators;
1414

15+
use DateInterval;
1516
use DateTimeZone;
1617
use Lcobucci\Clock\SystemClock;
1718
use Lcobucci\JWT\Configuration;
@@ -43,7 +44,7 @@ class BearerTokenValidator implements AuthorizationValidatorInterface
4344

4445
private Configuration $jwtConfiguration;
4546

46-
public function __construct(private AccessTokenRepositoryInterface $accessTokenRepository)
47+
public function __construct(private AccessTokenRepositoryInterface $accessTokenRepository, private ?DateInterval $jwtValidAtDateLeeway = null)
4748
{
4849
}
4950

@@ -67,14 +68,16 @@ private function initJwtConfiguration(): void
6768
InMemory::plainText('empty', 'empty')
6869
);
6970

71+
$clock = new SystemClock(new DateTimeZone(date_default_timezone_get()));
72+
7073
$publicKeyContents = $this->publicKey->getKeyContents();
7174

7275
if ($publicKeyContents === '') {
7376
throw new RuntimeException('Public key is empty');
7477
}
7578

7679
$this->jwtConfiguration->setValidationConstraints(
77-
new LooseValidAt(new SystemClock(new DateTimeZone(date_default_timezone_get()))),
80+
new LooseValidAt($clock, $this->jwtValidAtDateLeeway),
7881
new SignedWith(
7982
new Sha256(),
8083
InMemory::plainText($publicKeyContents, $this->publicKey->getPassPhrase() ?? '')
@@ -106,7 +109,7 @@ public function validateAuthorization(ServerRequestInterface $request): ServerRe
106109
$constraints = $this->jwtConfiguration->validationConstraints();
107110
$this->jwtConfiguration->validator()->assert($token, ...$constraints);
108111
} catch (RequiredConstraintsViolated $exception) {
109-
throw OAuthServerException::accessDenied('Access token could not be verified');
112+
throw OAuthServerException::accessDenied('Access token could not be verified', null, $exception);
110113
}
111114

112115
if (!$token instanceof UnencryptedToken) {

0 commit comments

Comments
 (0)