Compare commits

..

2 Commits

Author SHA1 Message Date
Alex Bilbie
7f93e9bcae Added token signers 2016-08-21 12:54:24 +01:00
Alex Bilbie
b62a5cd24a Added league/openid-connect-claims 2016-08-21 11:45:48 +01:00
53 changed files with 551 additions and 1060 deletions

View File

@@ -7,10 +7,11 @@ cache:
- vendor
php:
- 5.5.9
- 5.5
- 5.6
- 7.0
- 7.1
- 7.2
- hhvm
install:
- travis_retry composer install --no-interaction --prefer-source
@@ -20,4 +21,4 @@ script:
branches:
only:
- master
- master

View File

@@ -1,41 +1,5 @@
# Changelog
## 6.0.2 (released 2017-08-03)
* An invalid refresh token that can't be decrypted now returns a HTTP 401 error instead of HTTP 400 (Issue #759)
* Removed chmod from CryptKey and add toggle to disable checking (Issue #776)
* Fixes invalid code challenge method payload key name (Issue #777)
## 6.0.1 (released 2017-07-19)
To address feedback from the security release the following change has been made:
* If an RSA key cannot be chmod'ed to 600 then it will now throw a E_USER_NOTICE instead of an exception.
## 6.0.0 (released 2017-07-01)
* Breaking change: The `AuthorizationServer` constructor now expects an encryption key string instead of a public key
* Remove support for HHVM
* Remove support for PHP 5.5
## 5.1.4 (released 2017-07-01)
* Fixed multiple security vulnerabilities as a result of a security audit paid for by the [Mozilla Secure Open Source Fund](https://wiki.mozilla.org/MOSS/Secure_Open_Source). All users of this library are encouraged to update as soon as possible to this version or version 6.0 or greater.
* It is recommended on each `AuthorizationServer` instance you set the `setEncryptionKey()`. This will result in stronger encryption being used. If this method is not set messages will be sent to the defined error handling routines (using `error_log`). Please see the examples and documentation for examples.
* TravisCI now tests PHP 7.1 (Issue #671)
* Fix middleware example fatal error (Issue #682)
* Fix typo in the first README sentence (Issue #690)
* Corrected DateInterval from 1 min to 1 month (Issue #709)
## 5.1.3 (released 2016-10-12)
* Fixed WWW-Authenticate header (Issue #669)
* Increase the recommended RSA key length from 1024 to 2048 bits (Issue #668)
## 5.1.2 (released 2016-09-19)
* Fixed `finalizeScopes` call (Issue #650)
## 5.1.1 (released 2016-07-26)
* Improved test suite (Issue #614)

View File

@@ -1,7 +1,7 @@
Thanks for contributing to this project.
**Please submit your pull request against the `master` branch only.**
**Please submit your pull request against the `develop` branch only.**
Please ensure that you run `phpunit` from the project root after you've made any changes.

View File

@@ -1,11 +1,5 @@
# PHP OAuth 2.0 Server
### :warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning:
### Security Notice
### Please upgrade to version `>=5.1.6` (backwards compatible) or `6.x` (one tiny breaking change) to fix some potential security vulnerabilities - [visit this page for more information](https://oauth2.thephpleague.com/v5-security-improvements/)
### :warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning:
[![Latest Version](http://img.shields.io/packagist/v/league/oauth2-server.svg?style=flat-square)](https://github.com/thephpleague/oauth2-server/releases)
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md)
[![Build Status](https://img.shields.io/travis/thephpleague/oauth2-server/master.svg?style=flat-square)](https://travis-ci.org/thephpleague/oauth2-server)
@@ -13,7 +7,7 @@
[![Quality Score](https://img.shields.io/scrutinizer/g/thephpleague/oauth2-server.svg?style=flat-square)](https://scrutinizer-ci.com/g/thephpleague/oauth2-server)
[![Total Downloads](https://img.shields.io/packagist/dt/league/oauth2-server.svg?style=flat-square)](https://packagist.org/packages/league/oauth2-server)
`league/oauth2-server` is a standards compliant implementation of an [OAuth 2.0](https://tools.ietf.org/html/rfc6749) authorization server written in PHP which makes working with OAuth 2.0 trivial. You can easily configure an OAuth 2.0 server to protect your API with access tokens, or allow clients to request new access tokens and refresh them.
`league/oauth2-server` is a a standards compliant implementation of an [OAuth 2.0](https://tools.ietf.org/html/rfc6749) authorization server written in PHP which makes working with OAuth 2.0 trivial. You can easily configure an OAuth 2.0 server to protect your API with access tokens, or allow clients to request new access tokens and refresh them.
It supports out of the box the following grants:
@@ -36,10 +30,10 @@ This library was created by Alex Bilbie. Find him on Twitter at [@alexbilbie](ht
The following versions of PHP are supported:
* PHP 5.5 (>=5.5.9)
* PHP 5.6
* PHP 7.0
* PHP 7.1
* PHP 7.2
* HHVM
The `openssl` extension is also required.
@@ -62,10 +56,6 @@ Bugs and feature request are tracked on [GitHub](https://github.com/thephpleague
If you have any questions about OAuth _please_ open a ticket here; please **don't** email the address below.
<a target='_blank' rel='nofollow' href='https://app.codesponsor.io/link/N2YMJcLBppt2Eg9E1jGu4gef/thephpleague/oauth2-server'>
<img alt='Sponsor' width='888' height='68' src='https://app.codesponsor.io/embed/N2YMJcLBppt2Eg9E1jGu4gef/thephpleague/oauth2-server.svg' />
</a>
## Commercial Support
If you would like help implementing this library into your existing platform, or would be interested in OAuth advice or training for you and your team please get in touch with [Glynde Labs](https://glyndelabs.com).
@@ -80,13 +70,8 @@ This package is released under the MIT License. See the bundled [LICENSE](https:
## Credits
This code is principally developed and maintained by [Andy Millington](https://twitter.com/Sephster), [Brian
Retterer](https://twitter.com/bretterer), and [Simon Hamp](https://twitter.com/simonhamp).
This code is principally developed and maintained by [Alex Bilbie](https://twitter.com/alexbilbie).
Between 2012 and 2017 this library was developed and maintained by [Alex Bilbie](https://alexbilbie.com/).
Special thanks to [all of these awesome contributors](https://github.com/thephpleague/oauth2-server/contributors).
Additional thanks go to the [Mozilla Secure Open Source Fund](https://wiki.mozilla.org/MOSS/Secure_Open_Source) for funding a security audit of this library.
Special thanks to [all of these awesome contributors](https://github.com/thephpleague/oauth2-server/contributors)
The initial code was developed as part of the [Linkey](http://linkey.blogs.lincoln.ac.uk) project which was funded by [JISC](http://jisc.ac.uk) under the Access and Identity Management programme.

View File

@@ -4,17 +4,18 @@
"homepage": "https://oauth2.thephpleague.com/",
"license": "MIT",
"require": {
"php": ">=5.6.0",
"php": ">=5.5.9",
"ext-openssl": "*",
"league/event": "^2.1",
"lcobucci/jwt": "^3.1",
"paragonie/random_compat": "^2.0",
"paragonie/random_compat": "^1.1 || ^2.0",
"psr/http-message": "^1.0",
"defuse/php-encryption": "^2.1"
"league/openid-connect-claims": "^1.1.0"
},
"require-dev": {
"phpunit/phpunit": "^4.8.38 || ^5.7.21",
"zendframework/zend-diactoros": "^1.0"
"phpunit/phpunit": "^4.8 || ^5.0",
"zendframework/zend-diactoros": "^1.0",
"indigophp/hash-compat": "^1.1"
},
"repositories": [
{
@@ -59,5 +60,13 @@
"psr-4": {
"LeagueTests\\": "tests/"
}
},
"extra": {
"branch-alias": {
"dev-V5-WIP": "5.0-dev"
}
},
"suggest": {
"indigophp/hash-compat": "Polyfill for hash_equals function for PHP 5.5"
}
}

View File

@@ -3,7 +3,7 @@
## Installation
0. Run `composer install` in this directory to install dependencies
0. Create a private key `openssl genrsa -out private.key 2048`
0. Create a private key `openssl genrsa -out private.key 1024`
0. Create a public key `openssl rsa -in private.key -pubout > public.key`
0. `cd` into the public directory
0. Start a PHP server `php -S localhost:4444`

View File

@@ -5,10 +5,8 @@
"require-dev": {
"league/event": "^2.1",
"lcobucci/jwt": "^3.1",
"paragonie/random_compat": "^2.0",
"psr/http-message": "^1.0",
"defuse/php-encryption": "^2.1",
"zendframework/zend-diactoros": "^1.0"
"paragonie/random_compat": "^1.1",
"psr/http-message": "^1.0"
},
"autoload": {
"psr-4": {

170
examples/composer.lock generated
View File

@@ -4,25 +4,23 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "9813ed7c3b6dcf107f44df9392935b8f",
"hash": "48bcb7a3514d7c7f271c554ba1440124",
"content-hash": "e41be75973527cb9d63f27ad14ac8624",
"packages": [
{
"name": "container-interop/container-interop",
"version": "1.2.0",
"version": "1.1.0",
"source": {
"type": "git",
"url": "https://github.com/container-interop/container-interop.git",
"reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8"
"reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/container-interop/container-interop/zipball/79cbf1341c22ec75643d841642dd5d6acd83bdb8",
"reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8",
"url": "https://api.github.com/repos/container-interop/container-interop/zipball/fc08354828f8fd3245f77a66b9e23a6bca48297e",
"reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e",
"shasum": ""
},
"require": {
"psr/container": "^1.0"
},
"type": "library",
"autoload": {
"psr-4": {
@@ -34,8 +32,7 @@
"MIT"
],
"description": "Promoting the interoperability of container objects (DIC, SL, etc.)",
"homepage": "https://github.com/container-interop/container-interop",
"time": "2017-02-14T19:40:03+00:00"
"time": "2014-12-30 15:22:37"
},
{
"name": "nikic/fast-route",
@@ -78,7 +75,7 @@
"router",
"routing"
],
"time": "2015-06-18T19:15:47+00:00"
"time": "2015-06-18 19:15:47"
},
{
"name": "pimple/pimple",
@@ -124,69 +121,20 @@
"container",
"dependency injection"
],
"time": "2015-09-11T15:10:35+00:00"
},
{
"name": "psr/container",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/container.git",
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Container\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common Container Interface (PHP FIG PSR-11)",
"homepage": "https://github.com/php-fig/container",
"keywords": [
"PSR-11",
"container",
"container-interface",
"container-interop",
"psr"
],
"time": "2017-02-14T16:28:37+00:00"
"time": "2015-09-11 15:10:35"
},
{
"name": "psr/http-message",
"version": "1.0.1",
"version": "1.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
"reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/85d63699f0dbedb190bbd4b0d2b9dc707ea4c298",
"reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298",
"shasum": ""
},
"require": {
@@ -214,7 +162,6 @@
}
],
"description": "Common interface for HTTP messages",
"homepage": "https://github.com/php-fig/http-message",
"keywords": [
"http",
"http-message",
@@ -223,7 +170,7 @@
"request",
"response"
],
"time": "2016-08-06T14:39:51+00:00"
"time": "2015-05-04 20:22:00"
},
{
"name": "slim/slim",
@@ -289,85 +236,22 @@
"micro",
"router"
],
"time": "2015-12-07T14:11:09+00:00"
"time": "2015-12-07 14:11:09"
}
],
"packages-dev": [
{
"name": "defuse/php-encryption",
"version": "v2.1.0",
"source": {
"type": "git",
"url": "https://github.com/defuse/php-encryption.git",
"reference": "5176f5abb38d3ea8a6e3ac6cd3bbb54d8185a689"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/defuse/php-encryption/zipball/5176f5abb38d3ea8a6e3ac6cd3bbb54d8185a689",
"reference": "5176f5abb38d3ea8a6e3ac6cd3bbb54d8185a689",
"shasum": ""
},
"require": {
"ext-openssl": "*",
"paragonie/random_compat": "~2.0",
"php": ">=5.4.0"
},
"require-dev": {
"nikic/php-parser": "^2.0|^3.0",
"phpunit/phpunit": "^4|^5"
},
"bin": [
"bin/generate-defuse-key"
],
"type": "library",
"autoload": {
"psr-4": {
"Defuse\\Crypto\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Hornby",
"email": "taylor@defuse.ca",
"homepage": "https://defuse.ca/"
},
{
"name": "Scott Arciszewski",
"email": "info@paragonie.com",
"homepage": "https://paragonie.com"
}
],
"description": "Secure PHP Encryption Library",
"keywords": [
"aes",
"authenticated encryption",
"cipher",
"crypto",
"cryptography",
"encrypt",
"encryption",
"openssl",
"security",
"symmetric key cryptography"
],
"time": "2017-05-18T21:28:48+00:00"
},
{
"name": "lcobucci/jwt",
"version": "3.2.1",
"version": "3.1.1",
"source": {
"type": "git",
"url": "https://github.com/lcobucci/jwt.git",
"reference": "ddce703826f9c5229781933b1a39069e38e6a0f3"
"reference": "afea8e682e911a21574fd8519321b32522fa25b5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/lcobucci/jwt/zipball/ddce703826f9c5229781933b1a39069e38e6a0f3",
"reference": "ddce703826f9c5229781933b1a39069e38e6a0f3",
"url": "https://api.github.com/repos/lcobucci/jwt/zipball/afea8e682e911a21574fd8519321b32522fa25b5",
"reference": "afea8e682e911a21574fd8519321b32522fa25b5",
"shasum": ""
},
"require": {
@@ -375,7 +259,7 @@
"php": ">=5.5"
},
"require-dev": {
"mdanter/ecc": "~0.3.1",
"mdanter/ecc": "~0.3",
"mikey179/vfsstream": "~1.5",
"phpmd/phpmd": "~2.2",
"phpunit/php-invoker": "~1.1",
@@ -412,7 +296,7 @@
"JWS",
"jwt"
],
"time": "2016-10-31T20:09:32+00:00"
"time": "2016-03-24 22:46:13"
},
{
"name": "league/event",
@@ -462,20 +346,20 @@
"event",
"listener"
],
"time": "2015-05-21T12:24:47+00:00"
"time": "2015-05-21 12:24:47"
},
{
"name": "paragonie/random_compat",
"version": "v2.0.10",
"version": "v1.4.1",
"source": {
"type": "git",
"url": "https://github.com/paragonie/random_compat.git",
"reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d"
"reference": "c7e26a21ba357863de030f0b9e701c7d04593774"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/634bae8e911eefa89c1abfbf1b66da679ac8f54d",
"reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/c7e26a21ba357863de030f0b9e701c7d04593774",
"reference": "c7e26a21ba357863de030f0b9e701c7d04593774",
"shasum": ""
},
"require": {
@@ -510,7 +394,7 @@
"pseudorandom",
"random"
],
"time": "2017-03-13T16:27:32+00:00"
"time": "2016-03-18 20:34:03"
}
],
"aliases": [],

View File

@@ -31,6 +31,7 @@ $app->add(
$app->get(
'/users',
function (ServerRequestInterface $request, ResponseInterface $response) use ($app) {
$users = [
[
'id' => 123,
@@ -69,4 +70,4 @@ $app->get(
}
);
$app->run();
$app->run();

View File

@@ -36,6 +36,7 @@ $app = new App([
$refreshTokenRepository = new RefreshTokenRepository();
$privateKeyPath = 'file://' . __DIR__ . '/../private.key';
$publicKeyPath = 'file://' . __DIR__ . '/../public.key';
// Setup the authorization server
$server = new AuthorizationServer(
@@ -43,7 +44,7 @@ $app = new App([
$accessTokenRepository,
$scopeRepository,
$privateKeyPath,
'lxZFUEsBCJ2Yb14IF2ygAHI5N4+ZAUXXaSeeJm6+twsUmIen'
$publicKeyPath
);
// Enable the authentication code grant on the server with a token TTL of 1 hour

View File

@@ -30,8 +30,9 @@ $app = new App([
$accessTokenRepository = new AccessTokenRepository(); // instance of AccessTokenRepositoryInterface
// Path to public and private keys
$privateKey = 'file://' . __DIR__ . '/../private.key';
$privateKey = 'file://'.__DIR__.'/../private.key';
//$privateKey = new CryptKey('file://path/to/private.key', 'passphrase'); // if private key has a pass phrase
$publicKey = 'file://'.__DIR__.'/../public.key';
// Setup the authorization server
$server = new AuthorizationServer(
@@ -39,7 +40,7 @@ $app = new App([
$accessTokenRepository,
$scopeRepository,
$privateKey,
'lxZFUEsBCJ2Yb14IF2ygAHI5N4+ZAUXXaSeeJm6+twsUmIen'
$publicKey
);
// Enable the client credentials grant on the server

View File

@@ -32,6 +32,7 @@ $app = new App([
$accessTokenRepository = new AccessTokenRepository();
$privateKeyPath = 'file://' . __DIR__ . '/../private.key';
$publicKeyPath = 'file://' . __DIR__ . '/../public.key';
// Setup the authorization server
$server = new AuthorizationServer(
@@ -39,9 +40,8 @@ $app = new App([
$accessTokenRepository,
$scopeRepository,
$privateKeyPath,
'lxZFUEsBCJ2Yb14IF2ygAHI5N4+ZAUXXaSeeJm6+twsUmIen'
$publicKeyPath
);
$server->setEncryptionKey('lxZFUEsBCJ2Yb14IF2ygAHI5N4+ZAUXXaSeeJm6+twsUmIen');
// Enable the implicit grant on the server with a token TTL of 1 hour
$server->enableGrantType(new ImplicitGrant(new \DateInterval('PT1H')));

View File

@@ -12,7 +12,6 @@ use League\OAuth2\Server\Grant\AuthCodeGrant;
use League\OAuth2\Server\Grant\RefreshTokenGrant;
use League\OAuth2\Server\Middleware\AuthorizationServerMiddleware;
use League\OAuth2\Server\Middleware\ResourceServerMiddleware;
use League\OAuth2\Server\ResourceServer;
use OAuth2ServerExamples\Repositories\AccessTokenRepository;
use OAuth2ServerExamples\Repositories\AuthCodeRepository;
use OAuth2ServerExamples\Repositories\ClientRepository;
@@ -38,6 +37,7 @@ $app = new App([
$refreshTokenRepository = new RefreshTokenRepository();
$privateKeyPath = 'file://' . __DIR__ . '/../private.key';
$publicKeyPath = 'file://' . __DIR__ . '/../public.key';
// Setup the authorization server
$server = new AuthorizationServer(
@@ -45,7 +45,7 @@ $app = new App([
$accessTokenRepository,
$scopeRepository,
$privateKeyPath,
'lxZFUEsBCJ2Yb14IF2ygAHI5N4+ZAUXXaSeeJm6+twsUmIen'
$publicKeyPath
);
// Enable the authentication code grant on the server with a token TTL of 1 hour
@@ -61,17 +61,7 @@ $app = new App([
// Enable the refresh token grant on the server with a token TTL of 1 month
$server->enableGrantType(
new RefreshTokenGrant($refreshTokenRepository),
new \DateInterval('P1M')
);
return $server;
},
ResourceServer::class => function () {
$publicKeyPath = 'file://' . __DIR__ . '/../public.key';
$server = new ResourceServer(
new AccessTokenRepository(),
$publicKeyPath
new \DateInterval('PT1M')
);
return $server;
@@ -104,6 +94,6 @@ $app->group('/api', function () {
return $response->withBody($body);
});
})->add(new ResourceServerMiddleware($app->getContainer()->get(ResourceServer::class)));
})->add(new ResourceServerMiddleware($app->getContainer()->get(AuthorizationServer::class)));
$app->run();

View File

@@ -23,8 +23,8 @@ $app = new App([
new ClientRepository(), // instance of ClientRepositoryInterface
new AccessTokenRepository(), // instance of AccessTokenRepositoryInterface
new ScopeRepository(), // instance of ScopeRepositoryInterface
'file://' . __DIR__ . '/../private.key', // path to private key
'lxZFUEsBCJ2Yb14IF2ygAHI5N4+ZAUXXaSeeJm6+twsUmIen' // encryption key
'file://'.__DIR__.'/../private.key', // path to private key
'file://'.__DIR__.'/../public.key' // path to public key
);
$grant = new PasswordGrant(
@@ -54,17 +54,19 @@ $app->post(
// Try to respond to the access token request
return $server->respondToAccessTokenRequest($request, $response);
} catch (OAuthServerException $exception) {
// All instances of OAuthServerException can be converted to a PSR-7 response
return $exception->generateHttpResponse($response);
} catch (\Exception $exception) {
// Catch unexpected exceptions
$body = $response->getBody();
$body->write($exception->getMessage());
return $response->withStatus(500)->withBody($body);
}
}
);

View File

@@ -17,6 +17,7 @@ use OAuth2ServerExamples\Repositories\ScopeRepository;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Slim\App;
use Zend\Diactoros\Stream;
include __DIR__ . '/../vendor/autoload.php';
@@ -32,6 +33,7 @@ $app = new App([
$refreshTokenRepository = new RefreshTokenRepository();
$privateKeyPath = 'file://' . __DIR__ . '/../private.key';
$publicKeyPath = 'file://' . __DIR__ . '/../public.key';
// Setup the authorization server
$server = new AuthorizationServer(
@@ -39,7 +41,7 @@ $app = new App([
$accessTokenRepository,
$scopeRepository,
$privateKeyPath,
'lxZFUEsBCJ2Yb14IF2ygAHI5N4+ZAUXXaSeeJm6+twsUmIen'
$publicKeyPath
);
// Enable the refresh token grant on the server
@@ -64,9 +66,10 @@ $app->post('/access_token', function (ServerRequestInterface $request, ResponseI
} catch (OAuthServerException $exception) {
return $exception->generateHttpResponse($response);
} catch (\Exception $exception) {
$response->getBody()->write($exception->getMessage());
$body = new Stream('php://temp', 'r+');
$body->write($exception->getMessage());
return $response->withStatus(500);
return $response->withStatus(500)->withBody($body);
}
});

View File

@@ -54,7 +54,7 @@ class ScopeRepository implements ScopeRepositoryInterface
$scope->setIdentifier('email');
$scopes[] = $scope;
}
return $scopes;
}
}

View File

@@ -66,16 +66,6 @@ class AuthorizationServer implements EmitterAwareInterface
*/
private $scopeRepository;
/**
* @var string
*/
private $encryptionKey;
/**
* @var string
*/
private $defaultScope = '';
/**
* New server instance.
*
@@ -83,7 +73,7 @@ class AuthorizationServer implements EmitterAwareInterface
* @param AccessTokenRepositoryInterface $accessTokenRepository
* @param ScopeRepositoryInterface $scopeRepository
* @param CryptKey|string $privateKey
* @param string $encryptionKey
* @param CryptKey|string $publicKey
* @param null|ResponseTypeInterface $responseType
*/
public function __construct(
@@ -91,7 +81,7 @@ class AuthorizationServer implements EmitterAwareInterface
AccessTokenRepositoryInterface $accessTokenRepository,
ScopeRepositoryInterface $scopeRepository,
$privateKey,
$encryptionKey,
$publicKey,
ResponseTypeInterface $responseType = null
) {
$this->clientRepository = $clientRepository;
@@ -102,7 +92,12 @@ class AuthorizationServer implements EmitterAwareInterface
$privateKey = new CryptKey($privateKey);
}
$this->privateKey = $privateKey;
$this->encryptionKey = $encryptionKey;
if ($publicKey instanceof CryptKey === false) {
$publicKey = new CryptKey($publicKey);
}
$this->publicKey = $publicKey;
$this->responseType = $responseType;
}
@@ -121,10 +116,9 @@ class AuthorizationServer implements EmitterAwareInterface
$grantType->setAccessTokenRepository($this->accessTokenRepository);
$grantType->setClientRepository($this->clientRepository);
$grantType->setScopeRepository($this->scopeRepository);
$grantType->setDefaultScope($this->defaultScope);
$grantType->setPrivateKey($this->privateKey);
$grantType->setPublicKey($this->publicKey);
$grantType->setEmitter($this->getEmitter());
$grantType->setEncryptionKey($this->encryptionKey);
$this->enabledGrantTypes[$grantType->getIdentifier()] = $grantType;
$this->grantTypeAccessTokenTTL[$grantType->getIdentifier()] = $accessTokenTTL;
@@ -178,19 +172,17 @@ class AuthorizationServer implements EmitterAwareInterface
public function respondToAccessTokenRequest(ServerRequestInterface $request, ResponseInterface $response)
{
foreach ($this->enabledGrantTypes as $grantType) {
if (!$grantType->canRespondToAccessTokenRequest($request)) {
continue;
}
$tokenResponse = $grantType->respondToAccessTokenRequest(
$request,
$this->getResponseType(),
$this->grantTypeAccessTokenTTL[$grantType->getIdentifier()]
);
if ($grantType->canRespondToAccessTokenRequest($request)) {
$tokenResponse = $grantType->respondToAccessTokenRequest(
$request,
$this->getResponseType(),
$this->grantTypeAccessTokenTTL[$grantType->getIdentifier()]
);
if ($tokenResponse instanceof ResponseTypeInterface) {
return $tokenResponse->generateHttpResponse($response);
if ($tokenResponse instanceof ResponseTypeInterface) {
return $tokenResponse->generateHttpResponse($response);
}
}
}
throw OAuthServerException::unsupportedGrantType();
@@ -208,18 +200,7 @@ class AuthorizationServer implements EmitterAwareInterface
}
$this->responseType->setPrivateKey($this->privateKey);
$this->responseType->setEncryptionKey($this->encryptionKey);
return $this->responseType;
}
/**
* Set the default scope for the authorization server.
*
* @param string $defaultScope
*/
public function setDefaultScope($defaultScope)
{
$this->defaultScope = $defaultScope;
}
}

View File

@@ -12,7 +12,6 @@ namespace League\OAuth2\Server\AuthorizationValidators;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\Signer\Rsa\Sha256;
use Lcobucci\JWT\ValidationData;
use League\OAuth2\Server\CryptKey;
use League\OAuth2\Server\CryptTrait;
use League\OAuth2\Server\Exception\OAuthServerException;
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
@@ -27,11 +26,6 @@ class BearerTokenValidator implements AuthorizationValidatorInterface
*/
private $accessTokenRepository;
/**
* @var \League\OAuth2\Server\CryptKey
*/
protected $publicKey;
/**
* @param AccessTokenRepositoryInterface $accessTokenRepository
*/
@@ -40,16 +34,6 @@ class BearerTokenValidator implements AuthorizationValidatorInterface
$this->accessTokenRepository = $accessTokenRepository;
}
/**
* Set the public key
*
* @param \League\OAuth2\Server\CryptKey $key
*/
public function setPublicKey(CryptKey $key)
{
$this->publicKey = $key;
}
/**
* {@inheritdoc}
*/
@@ -91,7 +75,7 @@ class BearerTokenValidator implements AuthorizationValidatorInterface
} catch (\InvalidArgumentException $exception) {
// JWT couldn't be parsed so return the request as is
throw OAuthServerException::accessDenied($exception->getMessage());
} catch (\RuntimeException $exception) {
} catch(\RuntimeException $exception){
//JWR couldn't be parsed so return the request as is
throw OAuthServerException::accessDenied('Error while decoding to JSON');
}

View File

@@ -29,9 +29,8 @@ class CryptKey
/**
* @param string $keyPath
* @param null|string $passPhrase
* @param bool $keyPermissionsCheck
*/
public function __construct($keyPath, $passPhrase = null, $keyPermissionsCheck = true)
public function __construct($keyPath, $passPhrase = null)
{
if (preg_match(self::RSA_KEY_PATTERN, $keyPath)) {
$keyPath = $this->saveKeyToFile($keyPath);
@@ -45,18 +44,6 @@ class CryptKey
throw new \LogicException(sprintf('Key path "%s" does not exist or is not readable', $keyPath));
}
if ($keyPermissionsCheck === true) {
// Verify the permissions of the key
$keyPathPerms = decoct(fileperms($keyPath) & 0777);
if (in_array($keyPathPerms, ['600', '660'], true) === false) {
trigger_error(sprintf(
'Key file "%s" permissions are not correct, should be 600 or 660 instead of %s',
$keyPath,
$keyPathPerms
), E_USER_NOTICE);
}
}
$this->keyPath = $keyPath;
$this->passPhrase = $passPhrase;
}
@@ -70,26 +57,15 @@ class CryptKey
*/
private function saveKeyToFile($key)
{
$tmpDir = sys_get_temp_dir();
$keyPath = $tmpDir . '/' . sha1($key) . '.key';
$keyPath = sys_get_temp_dir() . '/' . sha1($key) . '.key';
if (!file_exists($keyPath) && !touch($keyPath)) {
// @codeCoverageIgnoreStart
throw new \RuntimeException(sprintf('"%s" key file could not be created', $keyPath));
throw new \RuntimeException('"%s" key file could not be created', $keyPath);
// @codeCoverageIgnoreEnd
}
if (file_put_contents($keyPath, $key) === false) {
// @codeCoverageIgnoreStart
throw new \RuntimeException(sprintf('Unable to write key file to temporary directory "%s"', $tmpDir));
// @codeCoverageIgnoreEnd
}
if (chmod($keyPath, 0600) === false) {
// @codeCoverageIgnoreStart
throw new \RuntimeException(sprintf('The key file "%s" file mode could not be changed with chmod to 600', $keyPath));
// @codeCoverageIgnoreEnd
}
file_put_contents($keyPath, $key);
return 'file://' . $keyPath;
}

View File

@@ -11,14 +11,37 @@
namespace League\OAuth2\Server;
use Defuse\Crypto\Crypto;
trait CryptTrait
{
/**
* @var string
* @var CryptKey
*/
protected $encryptionKey;
protected $privateKey;
/**
* @var CryptKey
*/
protected $publicKey;
/**
* Set path to private key.
*
* @param CryptKey $privateKey
*/
public function setPrivateKey(CryptKey $privateKey)
{
$this->privateKey = $privateKey;
}
/**
* Set path to public key.
*
* @param CryptKey $publicKey
*/
public function setPublicKey(CryptKey $publicKey)
{
$this->publicKey = $publicKey;
}
/**
* Encrypt data with a private key.
@@ -31,11 +54,30 @@ trait CryptTrait
*/
protected function encrypt($unencryptedData)
{
try {
return Crypto::encryptWithPassword($unencryptedData, $this->encryptionKey);
} catch (\Exception $e) {
throw new \LogicException($e->getMessage());
$privateKey = openssl_pkey_get_private($this->privateKey->getKeyPath(), $this->privateKey->getPassPhrase());
$privateKeyDetails = @openssl_pkey_get_details($privateKey);
if ($privateKeyDetails === null) {
throw new \LogicException(
sprintf('Could not get details of private key: %s', $this->privateKey->getKeyPath())
);
}
$chunkSize = ceil($privateKeyDetails['bits'] / 8) - 11;
$output = '';
while ($unencryptedData) {
$chunk = substr($unencryptedData, 0, $chunkSize);
$unencryptedData = substr($unencryptedData, $chunkSize);
if (openssl_private_encrypt($chunk, $encrypted, $privateKey) === false) {
// @codeCoverageIgnoreStart
throw new \LogicException('Failed to encrypt data');
// @codeCoverageIgnoreEnd
}
$output .= $encrypted;
}
openssl_pkey_free($privateKey);
return base64_encode($output);
}
/**
@@ -49,20 +91,31 @@ trait CryptTrait
*/
protected function decrypt($encryptedData)
{
try {
return Crypto::decryptWithPassword($encryptedData, $this->encryptionKey);
} catch (\Exception $e) {
throw new \LogicException($e->getMessage());
$publicKey = openssl_pkey_get_public($this->publicKey->getKeyPath());
$publicKeyDetails = @openssl_pkey_get_details($publicKey);
if ($publicKeyDetails === null) {
throw new \LogicException(
sprintf('Could not get details of public key: %s', $this->publicKey->getKeyPath())
);
}
}
/**
* Set the encryption key
*
* @param string $key
*/
public function setEncryptionKey($key = null)
{
$this->encryptionKey = $key;
$chunkSize = ceil($publicKeyDetails['bits'] / 8);
$output = '';
$encryptedData = base64_decode($encryptedData);
while ($encryptedData) {
$chunk = substr($encryptedData, 0, $chunkSize);
$encryptedData = substr($encryptedData, $chunkSize);
if (openssl_public_decrypt($chunk, $decrypted, $publicKey/*, OPENSSL_PKCS1_OAEP_PADDING*/) === false) {
// @codeCoverageIgnoreStart
throw new \LogicException('Failed to decrypt data');
// @codeCoverageIgnoreEnd
}
$output .= $decrypted;
}
openssl_pkey_free($publicKey);
return $output;
}
}

View File

@@ -105,15 +105,7 @@ class OAuthServerException extends \Exception
public static function invalidScope($scope, $redirectUri = null)
{
$errorMessage = 'The requested scope is invalid, unknown, or malformed';
if (empty($scope)) {
$hint = 'Specify a scope in the request or set a default scope';
} else {
$hint = sprintf(
'Check the `%s` scope',
htmlspecialchars($scope, ENT_QUOTES, 'UTF-8', false)
);
}
$hint = sprintf('Check the `%s` scope', $scope);
return new static($errorMessage, 5, 'invalid_scope', 400, $hint, $redirectUri);
}
@@ -157,7 +149,7 @@ class OAuthServerException extends \Exception
*/
public static function invalidRefreshToken($hint = null)
{
return new static('The refresh token is invalid.', 8, 'invalid_request', 401, $hint);
return new static('The refresh token is invalid.', 8, 'invalid_request', 400, $hint);
}
/**
@@ -275,7 +267,7 @@ class OAuthServerException extends \Exception
) {
$authScheme = 'Bearer';
}
$headers['WWW-Authenticate'] = $authScheme . ' realm="OAuth"';
$headers[] = 'WWW-Authenticate: ' . $authScheme . ' realm="OAuth"';
}
// @codeCoverageIgnoreEnd
return $headers;

View File

@@ -9,6 +9,7 @@
namespace League\OAuth2\Server\Exception;
class UniqueTokenIdentifierConstraintViolationException extends OAuthServerException
{
public static function create()

View File

@@ -11,7 +11,6 @@
namespace League\OAuth2\Server\Grant;
use League\Event\EmitterAwareTrait;
use League\OAuth2\Server\CryptKey;
use League\OAuth2\Server\CryptTrait;
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
use League\OAuth2\Server\Entities\AuthCodeEntityInterface;
@@ -76,16 +75,6 @@ abstract class AbstractGrant implements GrantTypeInterface
*/
protected $refreshTokenTTL;
/**
* @var \League\OAuth2\Server\CryptKey
*/
protected $privateKey;
/**
* @string
*/
protected $defaultScope;
/**
* @param ClientRepositoryInterface $clientRepository
*/
@@ -142,24 +131,6 @@ abstract class AbstractGrant implements GrantTypeInterface
$this->refreshTokenTTL = $refreshTokenTTL;
}
/**
* Set the private key
*
* @param \League\OAuth2\Server\CryptKey $key
*/
public function setPrivateKey(CryptKey $key)
{
$this->privateKey = $key;
}
/**
* @param string $scope
*/
public function setDefaultScope($scope)
{
$this->defaultScope = $scope;
}
/**
* Validate the client.
*
@@ -224,14 +195,18 @@ abstract class AbstractGrant implements GrantTypeInterface
*
* @return ScopeEntityInterface[]
*/
public function validateScopes($scopes, $redirectUri = null)
{
$scopesList = array_filter(explode(self::SCOPE_DELIMITER_STRING, trim($scopes)), function ($scope) {
return !empty($scope);
});
$validScopes = [];
public function validateScopes(
$scopes,
$redirectUri = null
) {
$scopesList = array_filter(
explode(self::SCOPE_DELIMITER_STRING, trim($scopes)),
function ($scope) {
return !empty($scope);
}
);
$scopes = [];
foreach ($scopesList as $scopeItem) {
$scope = $this->scopeRepository->getScopeEntityByIdentifier($scopeItem);
@@ -239,10 +214,10 @@ abstract class AbstractGrant implements GrantTypeInterface
throw OAuthServerException::invalidScope($scopeItem, $redirectUri);
}
$validScopes[] = $scope;
$scopes[] = $scope;
}
return $validScopes;
return $scopes;
}
/**
@@ -370,7 +345,6 @@ abstract class AbstractGrant implements GrantTypeInterface
$accessToken->setIdentifier($this->generateUniqueIdentifier());
try {
$this->accessTokenRepository->persistNewAccessToken($accessToken);
return $accessToken;
} catch (UniqueTokenIdentifierConstraintViolationException $e) {
if ($maxGenerationAttempts === 0) {
@@ -417,7 +391,6 @@ abstract class AbstractGrant implements GrantTypeInterface
$authCode->setIdentifier($this->generateUniqueIdentifier());
try {
$this->authCodeRepository->persistNewAuthCode($authCode);
return $authCode;
} catch (UniqueTokenIdentifierConstraintViolationException $e) {
if ($maxGenerationAttempts === 0) {
@@ -447,7 +420,6 @@ abstract class AbstractGrant implements GrantTypeInterface
$refreshToken->setIdentifier($this->generateUniqueIdentifier());
try {
$this->refreshTokenRepository->persistNewRefreshToken($refreshToken);
return $refreshToken;
} catch (UniqueTokenIdentifierConstraintViolationException $e) {
if ($maxGenerationAttempts === 0) {

View File

@@ -144,7 +144,7 @@ class AuthCodeGrant extends AbstractAuthorizeGrant
case 'S256':
if (
hash_equals(
hash('sha256', strtr(rtrim(base64_encode($codeVerifier), '='), '+/', '-_')),
urlencode(base64_encode(hash('sha256', $codeVerifier))),
$authCodePayload->code_challenge
) === false
) {
@@ -240,15 +240,10 @@ class AuthCodeGrant extends AbstractAuthorizeGrant
$this->getEmitter()->emit(new RequestEvent(RequestEvent::CLIENT_AUTHENTICATION_FAILED, $request));
throw OAuthServerException::invalidClient();
}
} elseif (is_array($client->getRedirectUri()) && count($client->getRedirectUri()) !== 1
|| empty($client->getRedirectUri())
) {
$this->getEmitter()->emit(new RequestEvent(RequestEvent::CLIENT_AUTHENTICATION_FAILED, $request));
throw OAuthServerException::invalidClient();
}
$scopes = $this->validateScopes(
$this->getQueryStringParameter('scope', $request, $this->defaultScope),
$this->getQueryStringParameter('scope', $request),
is_array($client->getRedirectUri())
? $client->getRedirectUri()[0]
: $client->getRedirectUri()
@@ -269,13 +264,6 @@ class AuthCodeGrant extends AbstractAuthorizeGrant
throw OAuthServerException::invalidRequest('code_challenge');
}
if (preg_match('/^[A-Za-z0-9-._~]{43,128}$/', $codeChallenge) !== 1) {
throw OAuthServerException::invalidRequest(
'code_challenge',
'The code_challenge must be between 43 and 128 characters'
);
}
$codeChallengeMethod = $this->getQueryStringParameter('code_challenge_method', $request, 'plain');
if (in_array($codeChallengeMethod, ['plain', 'S256']) === false) {
throw OAuthServerException::invalidRequest(
@@ -316,17 +304,6 @@ class AuthCodeGrant extends AbstractAuthorizeGrant
$authorizationRequest->getScopes()
);
$payload = [
'client_id' => $authCode->getClient()->getIdentifier(),
'redirect_uri' => $authCode->getRedirectUri(),
'auth_code_id' => $authCode->getIdentifier(),
'scopes' => $authCode->getScopes(),
'user_id' => $authCode->getUserIdentifier(),
'expire_time' => (new \DateTime())->add($this->authCodeTTL)->format('U'),
'code_challenge' => $authorizationRequest->getCodeChallenge(),
'code_challenge_method' => $authorizationRequest->getCodeChallengeMethod(),
];
$response = new RedirectResponse();
$response->setRedirectUri(
$this->makeRedirectUri(
@@ -334,7 +311,16 @@ class AuthCodeGrant extends AbstractAuthorizeGrant
[
'code' => $this->encrypt(
json_encode(
$payload
[
'client_id' => $authCode->getClient()->getIdentifier(),
'redirect_uri' => $authCode->getRedirectUri(),
'auth_code_id' => $authCode->getIdentifier(),
'scopes' => $authCode->getScopes(),
'user_id' => $authCode->getUserIdentifier(),
'expire_time' => (new \DateTime())->add($this->authCodeTTL)->format('U'),
'code_challenge' => $authorizationRequest->getCodeChallenge(),
'code_challenge_method ' => $authorizationRequest->getCodeChallengeMethod(),
]
)
),
'state' => $authorizationRequest->getState(),

View File

@@ -29,13 +29,13 @@ class ClientCredentialsGrant extends AbstractGrant
) {
// Validate request
$client = $this->validateClient($request);
$scopes = $this->validateScopes($this->getRequestParameter('scope', $request, $this->defaultScope));
$scopes = $this->validateScopes($this->getRequestParameter('scope', $request));
// Finalize the requested scopes
$finalizedScopes = $this->scopeRepository->finalizeScopes($scopes, $this->getIdentifier(), $client);
$scopes = $this->scopeRepository->finalizeScopes($scopes, $this->getIdentifier(), $client);
// Issue and persist access token
$accessToken = $this->issueAccessToken($accessTokenTTL, $client, null, $finalizedScopes);
$accessToken = $this->issueAccessToken($accessTokenTTL, $client, null, $scopes);
// Inject access token into response type
$responseType->setAccessToken($accessToken);

View File

@@ -119,13 +119,6 @@ interface GrantTypeInterface extends EmitterAwareInterface
*/
public function setScopeRepository(ScopeRepositoryInterface $scopeRepository);
/**
* Set the default scope.
*
* @param string $scope
*/
public function setDefaultScope($scope);
/**
* Set the path to the private key.
*
@@ -134,9 +127,9 @@ interface GrantTypeInterface extends EmitterAwareInterface
public function setPrivateKey(CryptKey $privateKey);
/**
* Set the encryption key
* Set the path to the public key.
*
* @param string|null $key
* @param CryptKey $publicKey
*/
public function setEncryptionKey($key = null);
public function setPublicKey(CryptKey $publicKey);
}

View File

@@ -26,19 +26,12 @@ class ImplicitGrant extends AbstractAuthorizeGrant
*/
private $accessTokenTTL;
/**
* @var string
*/
private $queryDelimiter;
/**
* @param \DateInterval $accessTokenTTL
* @param string $queryDelimiter
*/
public function __construct(\DateInterval $accessTokenTTL, $queryDelimiter = '#')
public function __construct(\DateInterval $accessTokenTTL)
{
$this->accessTokenTTL = $accessTokenTTL;
$this->queryDelimiter = $queryDelimiter;
}
/**
@@ -102,7 +95,7 @@ class ImplicitGrant extends AbstractAuthorizeGrant
public function canRespondToAuthorizationRequest(ServerRequestInterface $request)
{
return (
isset($request->getQueryParams()['response_type'])
array_key_exists('response_type', $request->getQueryParams())
&& $request->getQueryParams()['response_type'] === 'token'
&& isset($request->getQueryParams()['client_id'])
);
@@ -149,27 +142,15 @@ class ImplicitGrant extends AbstractAuthorizeGrant
$this->getEmitter()->emit(new RequestEvent(RequestEvent::CLIENT_AUTHENTICATION_FAILED, $request));
throw OAuthServerException::invalidClient();
}
} elseif (is_array($client->getRedirectUri()) && count($client->getRedirectUri()) !== 1
|| empty($client->getRedirectUri())
) {
$this->getEmitter()->emit(new RequestEvent(RequestEvent::CLIENT_AUTHENTICATION_FAILED, $request));
throw OAuthServerException::invalidClient();
}
$scopes = $this->validateScopes(
$this->getQueryStringParameter('scope', $request, $this->defaultScope),
$this->getQueryStringParameter('scope', $request),
is_array($client->getRedirectUri())
? $client->getRedirectUri()[0]
: $client->getRedirectUri()
);
// Finalize the requested scopes
$finalizedScopes = $this->scopeRepository->finalizeScopes(
$scopes,
$this->getIdentifier(),
$client
);
$stateParameter = $this->getQueryStringParameter('state', $request);
$authorizationRequest = new AuthorizationRequest();
@@ -177,7 +158,7 @@ class ImplicitGrant extends AbstractAuthorizeGrant
$authorizationRequest->setClient($client);
$authorizationRequest->setRedirectUri($redirectUri);
$authorizationRequest->setState($stateParameter);
$authorizationRequest->setScopes($finalizedScopes);
$authorizationRequest->setScopes($scopes);
return $authorizationRequest;
}
@@ -212,11 +193,11 @@ class ImplicitGrant extends AbstractAuthorizeGrant
$finalRedirectUri,
[
'access_token' => (string) $accessToken->convertToJWT($this->privateKey),
'token_type' => 'Bearer',
'token_type' => 'bearer',
'expires_in' => $accessToken->getExpiryDateTime()->getTimestamp() - (new \DateTime())->getTimestamp(),
'state' => $authorizationRequest->getState(),
],
$this->queryDelimiter
'#'
)
);

View File

@@ -49,14 +49,14 @@ class PasswordGrant extends AbstractGrant
) {
// Validate request
$client = $this->validateClient($request);
$scopes = $this->validateScopes($this->getRequestParameter('scope', $request, $this->defaultScope));
$scopes = $this->validateScopes($this->getRequestParameter('scope', $request));
$user = $this->validateUser($request, $client);
// Finalize the requested scopes
$finalizedScopes = $this->scopeRepository->finalizeScopes($scopes, $this->getIdentifier(), $client, $user->getIdentifier());
$scopes = $this->scopeRepository->finalizeScopes($scopes, $this->getIdentifier(), $client, $user->getIdentifier());
// Issue and persist new tokens
$accessToken = $this->issueAccessToken($accessTokenTTL, $client, $user->getIdentifier(), $finalizedScopes);
$accessToken = $this->issueAccessToken($accessTokenTTL, $client, $user->getIdentifier(), $scopes);
$refreshToken = $this->issueRefreshToken($accessToken);
// Inject tokens into response

View File

@@ -44,17 +44,28 @@ class RefreshTokenGrant extends AbstractGrant
// Validate request
$client = $this->validateClient($request);
$oldRefreshToken = $this->validateOldRefreshToken($request, $client->getIdentifier());
$scopes = $this->validateScopes($this->getRequestParameter(
'scope',
$request,
implode(self::SCOPE_DELIMITER_STRING, $oldRefreshToken['scopes']))
);
$scopes = $this->validateScopes($this->getRequestParameter('scope', $request));
// The OAuth spec says that a refreshed access token can have the original scopes or fewer so ensure
// the request doesn't include any new scopes
foreach ($scopes as $scope) {
if (in_array($scope->getIdentifier(), $oldRefreshToken['scopes']) === false) {
throw OAuthServerException::invalidScope($scope->getIdentifier());
// If no new scopes are requested then give the access token the original session scopes
if (count($scopes) === 0) {
$scopes = array_map(function ($scopeId) use ($client) {
$scope = $this->scopeRepository->getScopeEntityByIdentifier($scopeId);
if ($scope instanceof ScopeEntityInterface === false) {
// @codeCoverageIgnoreStart
throw OAuthServerException::invalidScope($scopeId);
// @codeCoverageIgnoreEnd
}
return $scope;
}, $oldRefreshToken['scopes']);
} else {
// The OAuth spec says that a refreshed access token can have the original scopes or fewer so ensure
// the request doesn't include any new scopes
foreach ($scopes as $scope) {
if (in_array($scope->getIdentifier(), $oldRefreshToken['scopes']) === false) {
throw OAuthServerException::invalidScope($scope->getIdentifier());
}
}
}
@@ -91,7 +102,7 @@ class RefreshTokenGrant extends AbstractGrant
// Validate refresh token
try {
$refreshToken = $this->decrypt($encryptedRefreshToken);
} catch (\Exception $e) {
} catch (\LogicException $e) {
throw OAuthServerException::invalidRefreshToken('Cannot decrypt the refresh token');
}

View File

@@ -12,7 +12,6 @@ namespace League\OAuth2\Server\Repositories;
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
use League\OAuth2\Server\Entities\ClientEntityInterface;
use League\OAuth2\Server\Entities\ScopeEntityInterface;
use League\OAuth2\Server\Exception\UniqueTokenIdentifierConstraintViolationException;
/**
* Access token interface.
@@ -34,8 +33,6 @@ interface AccessTokenRepositoryInterface extends RepositoryInterface
* Persists a new access token to permanent storage.
*
* @param AccessTokenEntityInterface $accessTokenEntity
*
* @throws UniqueTokenIdentifierConstraintViolationException
*/
public function persistNewAccessToken(AccessTokenEntityInterface $accessTokenEntity);

View File

@@ -10,7 +10,6 @@
namespace League\OAuth2\Server\Repositories;
use League\OAuth2\Server\Entities\AuthCodeEntityInterface;
use League\OAuth2\Server\Exception\UniqueTokenIdentifierConstraintViolationException;
/**
* Auth code storage interface.
@@ -28,8 +27,6 @@ interface AuthCodeRepositoryInterface extends RepositoryInterface
* Persists a new auth code to permanent storage.
*
* @param AuthCodeEntityInterface $authCodeEntity
*
* @throws UniqueTokenIdentifierConstraintViolationException
*/
public function persistNewAuthCode(AuthCodeEntityInterface $authCodeEntity);

View File

@@ -10,7 +10,6 @@
namespace League\OAuth2\Server\Repositories;
use League\OAuth2\Server\Entities\RefreshTokenEntityInterface;
use League\OAuth2\Server\Exception\UniqueTokenIdentifierConstraintViolationException;
/**
* Refresh token interface.
@@ -28,8 +27,6 @@ interface RefreshTokenRepositoryInterface extends RepositoryInterface
* Create a new refresh token_name.
*
* @param RefreshTokenEntityInterface $refreshTokenEntity
*
* @throws UniqueTokenIdentifierConstraintViolationException
*/
public function persistNewRefreshToken(RefreshTokenEntityInterface $refreshTokenEntity);

View File

@@ -66,14 +66,12 @@ class AuthorizationRequest
/**
* The code challenge (if provided)
*
* @var string
*/
protected $codeChallenge;
/**
* The code challenge method (if provided)
*
* @var string
*/
protected $codeChallengeMethod;

View File

@@ -11,7 +11,6 @@
namespace League\OAuth2\Server\ResponseTypes;
use League\OAuth2\Server\CryptKey;
use League\OAuth2\Server\CryptTrait;
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
use League\OAuth2\Server\Entities\RefreshTokenEntityInterface;
@@ -30,11 +29,6 @@ abstract class AbstractResponseType implements ResponseTypeInterface
*/
protected $refreshToken;
/**
* @var CryptKey
*/
protected $privateKey;
/**
* {@inheritdoc}
*/
@@ -50,14 +44,4 @@ abstract class AbstractResponseType implements ResponseTypeInterface
{
$this->refreshToken = $refreshToken;
}
/**
* Set the private key
*
* @param \League\OAuth2\Server\CryptKey $key
*/
public function setPrivateKey(CryptKey $key)
{
$this->privateKey = $key;
}
}

View File

@@ -68,7 +68,6 @@ class BearerTokenResponse extends AbstractResponseType
* this class rather than the default.
*
* @param AccessTokenEntityInterface $accessToken
*
* @return array
*/
protected function getExtraParams(AccessTokenEntityInterface $accessToken)

View File

@@ -33,11 +33,4 @@ interface ResponseTypeInterface
* @return ResponseInterface
*/
public function generateHttpResponse(ResponseInterface $response);
/**
* Set the encryption key
*
* @param string|null $key
*/
public function setEncryptionKey($key = null);
}

View File

@@ -0,0 +1,46 @@
<?php
namespace League\OAuth2\Server\TokenSigner;
use Lcobucci\JWT\Signer;
class HmacTokenSigner implements TokenSignerInterface
{
/**
* @var \Lcobucci\JWT\Signer
*/
private $signer;
/**
* @var string
*/
private $key;
/**
* TokenSignerInterface constructor.
*
* @param \Lcobucci\JWT\Signer $signer
* @param string $key
*/
public function __construct(Signer $signer, $key)
{
$this->signer = $signer;
$this->key = $key;
}
/**
* @return \Lcobucci\JWT\Signer
*/
public function getSigner()
{
return $this->signer;
}
/**
* @return string
*/
public function getKey()
{
return $this->key;
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace League\OAuth2\Server\TokenSigner;
use Lcobucci\JWT\Signer;
use League\OAuth2\Server\CryptKey;
class RsaKeyTokenSigner implements TokenSignerInterface
{
/**
* @var \Lcobucci\JWT\Signer
*/
private $signer;
/**
* @var \League\OAuth2\Server\CryptKey
*/
private $key;
/**
* TokenSignerInterface constructor.
*
* @param \Lcobucci\JWT\Signer $signer
* @param CryptKey $privateKey
*/
public function __construct(Signer $signer, CryptKey $privateKey)
{
$this->signer = $signer;
$this->key = new Signer\Key($privateKey->getKeyPath(), $privateKey->getPassPhrase());
}
/**
* @return \Lcobucci\JWT\Signer
*/
public function getSigner()
{
return $this->signer;
}
/**
* @return CryptKey
*/
public function getKey()
{
return $this->key;
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace League\OAuth2\Server\TokenSigner;
interface TokenSignerInterface
{
/**
* @return \Lcobucci\JWT\Signer
*/
public function getSigner();
/**
* @return mixed
*/
public function getKey();
}

View File

@@ -3,6 +3,7 @@
namespace LeagueTests;
use League\OAuth2\Server\AuthorizationServer;
use League\OAuth2\Server\CryptKey;
use League\OAuth2\Server\Exception\OAuthServerException;
use League\OAuth2\Server\Grant\AuthCodeGrant;
use League\OAuth2\Server\Grant\ClientCredentialsGrant;
@@ -16,27 +17,15 @@ use League\OAuth2\Server\ResponseTypes\BearerTokenResponse;
use LeagueTests\Stubs\AccessTokenEntity;
use LeagueTests\Stubs\AuthCodeEntity;
use LeagueTests\Stubs\ClientEntity;
use LeagueTests\Stubs\ScopeEntity;
use LeagueTests\Stubs\StubResponseType;
use LeagueTests\Stubs\UserEntity;
use Psr\Http\Message\ResponseInterface;
use PHPUnit\Framework\TestCase;
use Zend\Diactoros\Response;
use Zend\Diactoros\ServerRequest;
use Zend\Diactoros\ServerRequestFactory;
class AuthorizationServerTest extends TestCase
class AuthorizationServerTest extends \PHPUnit_Framework_TestCase
{
const DEFAULT_SCOPE = 'basic';
public function setUp()
{
// Make sure the keys have the correct permissions.
chmod(__DIR__ . '/Stubs/private.key', 0600);
chmod(__DIR__ . '/Stubs/public.key', 0600);
}
public function testRespondToRequestInvalidGrantType()
{
$server = new AuthorizationServer(
@@ -44,7 +33,7 @@ class AuthorizationServerTest extends TestCase
$this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(),
$this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(),
'file://' . __DIR__ . '/Stubs/private.key',
base64_encode(random_bytes(36)),
'file://' . __DIR__ . '/Stubs/public.key',
new StubResponseType()
);
@@ -63,9 +52,7 @@ class AuthorizationServerTest extends TestCase
$clientRepository = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepository->method('getClientEntity')->willReturn(new ClientEntity());
$scope = new ScopeEntity();
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
$scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scope);
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
@@ -76,11 +63,10 @@ class AuthorizationServerTest extends TestCase
$accessTokenRepositoryMock,
$scopeRepositoryMock,
'file://' . __DIR__ . '/Stubs/private.key',
base64_encode(random_bytes(36)),
'file://' . __DIR__ . '/Stubs/public.key',
new StubResponseType()
);
$server->setDefaultScope(self::DEFAULT_SCOPE);
$server->enableGrantType(new ClientCredentialsGrant(), new \DateInterval('PT1M'));
$_POST['grant_type'] = 'client_credentials';
@@ -106,7 +92,7 @@ class AuthorizationServerTest extends TestCase
$method = $abstractGrantReflection->getMethod('getResponseType');
$method->setAccessible(true);
$this->assertInstanceOf(BearerTokenResponse::class, $method->invoke($server));
$this->assertTrue($method->invoke($server) instanceof BearerTokenResponse);
}
public function testCompleteAuthorizationRequest()
@@ -130,6 +116,9 @@ class AuthorizationServerTest extends TestCase
new \DateInterval('PT10M')
);
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/Stubs/private.key'));
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/Stubs/public.key'));
$server->enableGrantType($grant);
$authRequest = new AuthorizationRequest();
@@ -138,23 +127,17 @@ class AuthorizationServerTest extends TestCase
$authRequest->setGrantTypeId('authorization_code');
$authRequest->setUser(new UserEntity());
$this->assertInstanceOf(
ResponseInterface::class,
$server->completeAuthorizationRequest($authRequest, new Response)
$this->assertTrue(
$server->completeAuthorizationRequest($authRequest, new Response) instanceof ResponseInterface
);
}
public function testValidateAuthorizationRequest()
{
$client = new ClientEntity();
$client->setRedirectUri('http://foo/bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$scope = new ScopeEntity();
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
$scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scope);
$grant = new AuthCodeGrant(
$this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(),
$this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(),
@@ -165,48 +148,7 @@ class AuthorizationServerTest extends TestCase
$server = new AuthorizationServer(
$clientRepositoryMock,
$this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(),
$scopeRepositoryMock,
'file://' . __DIR__ . '/Stubs/private.key',
'file://' . __DIR__ . '/Stubs/public.key'
);
$server->setDefaultScope(self::DEFAULT_SCOPE);
$server->enableGrantType($grant);
$request = new ServerRequest(
[],
[],
null,
null,
'php://input',
$headers = [],
$cookies = [],
$queryParams = [
'response_type' => 'code',
'client_id' => 'foo',
]
);
$this->assertInstanceOf(AuthorizationRequest::class, $server->validateAuthorizationRequest($request));
}
public function testValidateAuthorizationRequestWithMissingRedirectUri()
{
$client = new ClientEntity();
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$grant = new AuthCodeGrant(
$this->getMock(AuthCodeRepositoryInterface::class),
$this->getMock(RefreshTokenRepositoryInterface::class),
new \DateInterval('PT10M')
);
$grant->setClientRepository($clientRepositoryMock);
$server = new AuthorizationServer(
$clientRepositoryMock,
$this->getMock(AccessTokenRepositoryInterface::class),
$this->getMock(ScopeRepositoryInterface::class),
$this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(),
'file://' . __DIR__ . '/Stubs/private.key',
'file://' . __DIR__ . '/Stubs/public.key'
);
@@ -226,12 +168,7 @@ class AuthorizationServerTest extends TestCase
]
);
try {
$server->validateAuthorizationRequest($request);
} catch (OAuthServerException $e) {
$this->assertEquals('invalid_client', $e->getErrorType());
$this->assertEquals(401, $e->getHttpStatusCode());
}
$this->assertTrue($server->validateAuthorizationRequest($request) instanceof AuthorizationRequest);
}
/**

View File

@@ -3,9 +3,8 @@
namespace LeagueTests\Utils;
use League\OAuth2\Server\CryptKey;
use PHPUnit\Framework\TestCase;
class CryptKeyTest extends TestCase
class CryptKeyTest extends \PHPUnit_Framework_TestCase
{
/**
* @expectedException \LogicException

View File

@@ -2,13 +2,13 @@
namespace LeagueTests\Utils;
use League\OAuth2\Server\CryptKey;
use LeagueTests\Stubs\CryptTraitStub;
use PHPUnit\Framework\TestCase;
class CryptTraitTest extends TestCase
class CryptTraitTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \LeagueTests\Stubs\CryptTraitStub
* CryptTrait stub
*/
protected $cryptStub;
@@ -26,4 +26,30 @@ class CryptTraitTest extends TestCase
$this->assertNotEquals($payload, $encrypted);
$this->assertEquals($payload, $plainText);
}
/**
* @expectedException \LogicException
*/
public function testBadPrivateKey()
{
$this->cryptStub->setPrivateKey(new CryptKey(__DIR__ . '/Stubs/public.key'));
$this->cryptStub->doEncrypt('');
}
/**
* @expectedException \LogicException
*/
public function testBadPublicKey()
{
$this->cryptStub->setPublicKey(new CryptKey(__DIR__ . '/Stubs/private.key'));
$this->cryptStub->doDecrypt('');
}
/**
* @expectedException \LogicException
*/
public function testNonExistentKey()
{
new CryptKey('foo/bar');
}
}

View File

@@ -3,6 +3,7 @@
namespace LeagueTests\Grant;
use League\Event\Emitter;
use League\OAuth2\Server\CryptKey;
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
use League\OAuth2\Server\Entities\AuthCodeEntityInterface;
use League\OAuth2\Server\Entities\RefreshTokenEntityInterface;
@@ -18,15 +19,16 @@ use LeagueTests\Stubs\AuthCodeEntity;
use LeagueTests\Stubs\ClientEntity;
use LeagueTests\Stubs\RefreshTokenEntity;
use LeagueTests\Stubs\ScopeEntity;
use PHPUnit\Framework\TestCase;
use Zend\Diactoros\ServerRequest;
class AbstractGrantTest extends TestCase
class AbstractGrantTest extends \PHPUnit_Framework_TestCase
{
public function testGetSet()
{
/** @var AbstractGrant $grantMock */
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
$grantMock->setPrivateKey(new CryptKey(__DIR__ . '/../Stubs/private.key'));
$grantMock->setPublicKey(new CryptKey(__DIR__ . '/../Stubs/public.key'));
$grantMock->setEmitter(new Emitter());
}
@@ -342,7 +344,7 @@ class AbstractGrantTest extends TestCase
$accessToken = new AccessTokenEntity();
/** @var RefreshTokenEntityInterface $refreshToken */
$refreshToken = $issueRefreshTokenMethod->invoke($grantMock, $accessToken);
$this->assertInstanceOf(RefreshTokenEntityInterface::class, $refreshToken);
$this->assertTrue($refreshToken instanceof RefreshTokenEntityInterface);
$this->assertEquals($accessToken, $refreshToken->getAccessToken());
}
@@ -367,7 +369,7 @@ class AbstractGrantTest extends TestCase
123,
[new ScopeEntity()]
);
$this->assertInstanceOf(AccessTokenEntityInterface::class, $accessToken);
$this->assertTrue($accessToken instanceof AccessTokenEntityInterface);
}
public function testIssueAuthCode()
@@ -383,8 +385,7 @@ class AbstractGrantTest extends TestCase
$issueAuthCodeMethod = $abstractGrantReflection->getMethod('issueAuthCode');
$issueAuthCodeMethod->setAccessible(true);
$this->assertInstanceOf(
AuthCodeEntityInterface::class,
$this->assertTrue(
$issueAuthCodeMethod->invoke(
$grantMock,
new \DateInterval('PT1H'),
@@ -392,7 +393,7 @@ class AbstractGrantTest extends TestCase
123,
'http://foo/bar',
[new ScopeEntity()]
)
) instanceof AuthCodeEntityInterface
);
}
@@ -468,7 +469,7 @@ class AbstractGrantTest extends TestCase
$method = $abstractGrantReflection->getMethod('generateUniqueIdentifier');
$method->setAccessible(true);
$this->assertInternalType('string', $method->invoke($grantMock));
$this->assertTrue(is_string($method->invoke($grantMock)));
}
public function testCanRespondToAuthorizationRequest()

View File

@@ -2,6 +2,7 @@
namespace LeagueTests\Grant;
use League\OAuth2\Server\CryptKey;
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
use League\OAuth2\Server\Entities\RefreshTokenEntityInterface;
use League\OAuth2\Server\Exception\OAuthServerException;
@@ -22,13 +23,10 @@ use LeagueTests\Stubs\RefreshTokenEntity;
use LeagueTests\Stubs\ScopeEntity;
use LeagueTests\Stubs\StubResponseType;
use LeagueTests\Stubs\UserEntity;
use PHPUnit\Framework\TestCase;
use Zend\Diactoros\ServerRequest;
class AuthCodeGrantTest extends TestCase
class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
{
const DEFAULT_SCOPE = 'basic';
/**
* @var CryptTraitStub
*/
@@ -79,22 +77,15 @@ class AuthCodeGrantTest extends TestCase
{
$client = new ClientEntity();
$client->setRedirectUri('http://foo/bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$scope = new ScopeEntity();
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
$scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scope);
$grant = new AuthCodeGrant(
$this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(),
$this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(),
new \DateInterval('PT10M')
);
$grant->setClientRepository($clientRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setDefaultScope(self::DEFAULT_SCOPE);
$request = new ServerRequest(
[],
@@ -111,7 +102,7 @@ class AuthCodeGrantTest extends TestCase
]
);
$this->assertInstanceOf(AuthorizationRequest::class, $grant->validateAuthorizationRequest($request));
$this->assertTrue($grant->validateAuthorizationRequest($request) instanceof AuthorizationRequest);
}
public function testValidateAuthorizationRequestRedirectUriArray()
@@ -121,18 +112,12 @@ class AuthCodeGrantTest extends TestCase
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$scope = new ScopeEntity();
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
$scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scope);
$grant = new AuthCodeGrant(
$this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(),
$this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(),
new \DateInterval('PT10M')
);
$grant->setClientRepository($clientRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setDefaultScope(self::DEFAULT_SCOPE);
$request = new ServerRequest(
[],
@@ -149,9 +134,10 @@ class AuthCodeGrantTest extends TestCase
]
);
$this->assertInstanceOf(AuthorizationRequest::class, $grant->validateAuthorizationRequest($request));
$this->assertTrue($grant->validateAuthorizationRequest($request) instanceof AuthorizationRequest);
}
public function testValidateAuthorizationRequestCodeChallenge()
{
$client = new ClientEntity();
@@ -159,49 +145,6 @@ class AuthCodeGrantTest extends TestCase
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$scope = new ScopeEntity();
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
$scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scope);
$grant = new AuthCodeGrant(
$this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(),
$this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(),
new \DateInterval('PT10M')
);
$grant->enableCodeExchangeProof();
$grant->setClientRepository($clientRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setDefaultScope(self::DEFAULT_SCOPE);
$request = new ServerRequest(
[],
[],
null,
null,
'php://input',
[],
[],
[
'response_type' => 'code',
'client_id' => 'foo',
'redirect_uri' => 'http://foo/bar',
'code_challenge' => str_repeat('A', 43),
]
);
$this->assertInstanceOf(AuthorizationRequest::class, $grant->validateAuthorizationRequest($request));
}
/**
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
*/
public function testValidateAuthorizationRequestCodeChallengeInvalidLengthTooShort()
{
$client = new ClientEntity();
$client->setRedirectUri('http://foo/bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$grant = new AuthCodeGrant(
$this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(),
$this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(),
@@ -222,85 +165,11 @@ class AuthCodeGrantTest extends TestCase
'response_type' => 'code',
'client_id' => 'foo',
'redirect_uri' => 'http://foo/bar',
'code_challenge' => str_repeat('A', 42),
'code_challenge' => 'FOOBAR',
]
);
$grant->validateAuthorizationRequest($request);
}
/**
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
*/
public function testValidateAuthorizationRequestCodeChallengeInvalidLengthTooLong()
{
$client = new ClientEntity();
$client->setRedirectUri('http://foo/bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$grant = new AuthCodeGrant(
$this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(),
$this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(),
new \DateInterval('PT10M')
);
$grant->enableCodeExchangeProof();
$grant->setClientRepository($clientRepositoryMock);
$request = new ServerRequest(
[],
[],
null,
null,
'php://input',
[],
[],
[
'response_type' => 'code',
'client_id' => 'foo',
'redirect_uri' => 'http://foo/bar',
'code_challenge' => str_repeat('A', 129),
]
);
$grant->validateAuthorizationRequest($request);
}
/**
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
*/
public function testValidateAuthorizationRequestCodeChallengeInvalidCharacters()
{
$client = new ClientEntity();
$client->setRedirectUri('http://foo/bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$grant = new AuthCodeGrant(
$this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(),
$this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(),
new \DateInterval('PT10M')
);
$grant->enableCodeExchangeProof();
$grant->setClientRepository($clientRepositoryMock);
$request = new ServerRequest(
[],
[],
null,
null,
'php://input',
[],
[],
[
'response_type' => 'code',
'client_id' => 'foo',
'redirect_uri' => 'http://foo/bar',
'code_challenge' => str_repeat('A', 42) . '!',
]
);
$grant->validateAuthorizationRequest($request);
$this->assertTrue($grant->validateAuthorizationRequest($request) instanceof AuthorizationRequest);
}
/**
@@ -450,10 +319,6 @@ class AuthCodeGrantTest extends TestCase
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$scope = new ScopeEntity();
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
$scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scope);
$grant = new AuthCodeGrant(
$this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(),
$this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(),
@@ -461,8 +326,6 @@ class AuthCodeGrantTest extends TestCase
);
$grant->enableCodeExchangeProof();
$grant->setClientRepository($clientRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setDefaultScope(self::DEFAULT_SCOPE);
$request = new ServerRequest(
[],
@@ -493,10 +356,6 @@ class AuthCodeGrantTest extends TestCase
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$scope = new ScopeEntity();
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
$scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scope);
$grant = new AuthCodeGrant(
$this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(),
$this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(),
@@ -504,8 +363,6 @@ class AuthCodeGrantTest extends TestCase
);
$grant->enableCodeExchangeProof();
$grant->setClientRepository($clientRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setDefaultScope(self::DEFAULT_SCOPE);
$request = new ServerRequest(
[],
@@ -543,9 +400,11 @@ class AuthCodeGrantTest extends TestCase
$this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(),
new \DateInterval('PT10M')
);
$grant->setEncryptionKey($this->cryptStub->getKey());
$this->assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$this->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse);
}
/**
@@ -568,7 +427,9 @@ class AuthCodeGrantTest extends TestCase
$this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(),
new \DateInterval('PT10M')
);
$grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->completeAuthorizationRequest($authRequest);
}
@@ -603,7 +464,8 @@ class AuthCodeGrantTest extends TestCase
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest(
[],
@@ -636,8 +498,8 @@ class AuthCodeGrantTest extends TestCase
/** @var StubResponseType $response */
$response = $grant->respondToAccessTokenRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
$this->assertInstanceOf(AccessTokenEntityInterface::class, $response->getAccessToken());
$this->assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken());
$this->assertTrue($response->getAccessToken() instanceof AccessTokenEntityInterface);
$this->assertTrue($response->getRefreshToken() instanceof RefreshTokenEntityInterface);
}
public function testRespondToAccessTokenRequestCodeChallengePlain()
@@ -671,7 +533,8 @@ class AuthCodeGrantTest extends TestCase
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest(
[],
@@ -707,8 +570,8 @@ class AuthCodeGrantTest extends TestCase
/** @var StubResponseType $response */
$response = $grant->respondToAccessTokenRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
$this->assertInstanceOf(AccessTokenEntityInterface::class, $response->getAccessToken());
$this->assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken());
$this->assertTrue($response->getAccessToken() instanceof AccessTokenEntityInterface);
$this->assertTrue($response->getRefreshToken() instanceof RefreshTokenEntityInterface);
}
public function testRespondToAccessTokenRequestCodeChallengeS256()
@@ -742,7 +605,8 @@ class AuthCodeGrantTest extends TestCase
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest(
[],
@@ -767,7 +631,7 @@ class AuthCodeGrantTest extends TestCase
'user_id' => 123,
'scopes' => ['foo'],
'redirect_uri' => 'http://foo/bar',
'code_challenge' => hash('sha256', strtr(rtrim(base64_encode('foobar'), '='), '+/', '-_')),
'code_challenge' => urlencode(base64_encode(hash('sha256', 'foobar'))),
'code_challenge_method' => 'S256',
]
)
@@ -778,8 +642,8 @@ class AuthCodeGrantTest extends TestCase
/** @var StubResponseType $response */
$response = $grant->respondToAccessTokenRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
$this->assertInstanceOf(AccessTokenEntityInterface::class, $response->getAccessToken());
$this->assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken());
$this->assertTrue($response->getAccessToken() instanceof AccessTokenEntityInterface);
$this->assertTrue($response->getRefreshToken() instanceof RefreshTokenEntityInterface);
}
/**
@@ -799,7 +663,7 @@ class AuthCodeGrantTest extends TestCase
new \DateInterval('PT10M')
);
$grant->setClientRepository($clientRepositoryMock);
$grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$request = new ServerRequest(
[],
@@ -846,7 +710,7 @@ class AuthCodeGrantTest extends TestCase
new \DateInterval('PT10M')
);
$grant->setClientRepository($clientRepositoryMock);
$grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$request = new ServerRequest(
[],
@@ -899,7 +763,8 @@ class AuthCodeGrantTest extends TestCase
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest(
[],
@@ -944,7 +809,8 @@ class AuthCodeGrantTest extends TestCase
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest(
[],
@@ -1007,7 +873,8 @@ class AuthCodeGrantTest extends TestCase
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest(
[],
@@ -1067,7 +934,8 @@ class AuthCodeGrantTest extends TestCase
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest(
[],
@@ -1127,7 +995,8 @@ class AuthCodeGrantTest extends TestCase
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest(
[],
@@ -1185,7 +1054,8 @@ class AuthCodeGrantTest extends TestCase
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest(
[],
@@ -1257,7 +1127,8 @@ class AuthCodeGrantTest extends TestCase
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest(
[],
@@ -1329,7 +1200,8 @@ class AuthCodeGrantTest extends TestCase
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest(
[],
@@ -1388,9 +1260,11 @@ class AuthCodeGrantTest extends TestCase
$this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(),
new \DateInterval('PT10M')
);
$grant->setEncryptionKey($this->cryptStub->getKey());
$this->assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$this->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse);
}
/**
@@ -1414,9 +1288,11 @@ class AuthCodeGrantTest extends TestCase
$this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(),
new \DateInterval('PT10M')
);
$grant->setEncryptionKey($this->cryptStub->getKey());
$this->assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$this->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse);
}
/**
@@ -1441,7 +1317,10 @@ class AuthCodeGrantTest extends TestCase
new \DateInterval('PT10M')
);
$this->assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$this->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse);
}
public function testRefreshTokenRepositoryUniqueConstraintCheck()
@@ -1475,7 +1354,8 @@ class AuthCodeGrantTest extends TestCase
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest(
[],
@@ -1508,8 +1388,8 @@ class AuthCodeGrantTest extends TestCase
/** @var StubResponseType $response */
$response = $grant->respondToAccessTokenRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
$this->assertInstanceOf(AccessTokenEntityInterface::class, $response->getAccessToken());
$this->assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken());
$this->assertTrue($response->getAccessToken() instanceof AccessTokenEntityInterface);
$this->assertTrue($response->getRefreshToken() instanceof RefreshTokenEntityInterface);
}
/**
@@ -1546,7 +1426,8 @@ class AuthCodeGrantTest extends TestCase
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest(
[],
@@ -1579,8 +1460,8 @@ class AuthCodeGrantTest extends TestCase
/** @var StubResponseType $response */
$response = $grant->respondToAccessTokenRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
$this->assertInstanceOf(AccessTokenEntityInterface::class, $response->getAccessToken());
$this->assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken());
$this->assertTrue($response->getAccessToken() instanceof AccessTokenEntityInterface);
$this->assertTrue($response->getRefreshToken() instanceof RefreshTokenEntityInterface);
}
/**
@@ -1617,7 +1498,8 @@ class AuthCodeGrantTest extends TestCase
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest(
[],
@@ -1650,8 +1532,8 @@ class AuthCodeGrantTest extends TestCase
/** @var StubResponseType $response */
$response = $grant->respondToAccessTokenRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
$this->assertInstanceOf(AccessTokenEntityInterface::class, $response->getAccessToken());
$this->assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken());
$this->assertTrue($response->getAccessToken() instanceof AccessTokenEntityInterface);
$this->assertTrue($response->getRefreshToken() instanceof RefreshTokenEntityInterface);
}
/**
@@ -1667,47 +1549,4 @@ class AuthCodeGrantTest extends TestCase
$grant->completeAuthorizationRequest(new AuthorizationRequest());
}
/**
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
* @expectedExceptionCode 5
*/
public function testValidateAuthorizationRequestFailsWithoutScope()
{
$client = new ClientEntity();
$client->setRedirectUri('http://foo/bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$scope = new ScopeEntity();
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
$scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scope);
$grant = new AuthCodeGrant(
$this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(),
$this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(),
new \DateInterval('PT10M')
);
$grant->setClientRepository($clientRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock);
$request = new ServerRequest(
[],
[],
null,
null,
'php://input',
[],
[],
[
'response_type' => 'code',
'client_id' => 'foo',
'redirect_uri' => 'http://foo/bar',
]
);
$grant->validateAuthorizationRequest($request);
}
}

View File

@@ -9,15 +9,11 @@ use League\OAuth2\Server\Repositories\ClientRepositoryInterface;
use League\OAuth2\Server\Repositories\ScopeRepositoryInterface;
use LeagueTests\Stubs\AccessTokenEntity;
use LeagueTests\Stubs\ClientEntity;
use LeagueTests\Stubs\ScopeEntity;
use LeagueTests\Stubs\StubResponseType;
use PHPUnit\Framework\TestCase;
use Zend\Diactoros\ServerRequest;
class ClientCredentialsGrantTest extends TestCase
class ClientCredentialsGrantTest extends \PHPUnit_Framework_TestCase
{
const DEFAULT_SCOPE = 'basic';
public function testGetIdentifier()
{
$grant = new ClientCredentialsGrant();
@@ -34,48 +30,7 @@ class ClientCredentialsGrantTest extends TestCase
$accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity());
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
$scope = new ScopeEntity();
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
$scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scope);
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
$grant = new ClientCredentialsGrant();
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setDefaultScope(self::DEFAULT_SCOPE);
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withParsedBody(
[
'client_id' => 'foo',
'client_secret' => 'bar',
]
);
$responseType = new StubResponseType();
$grant->respondToAccessTokenRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
$this->assertInstanceOf(AccessTokenEntityInterface::class, $responseType->getAccessToken());
}
/**
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
* @expectedExceptionCode 5
*/
public function testRespondToRequestFailsWithoutScope()
{
$client = new ClientEntity();
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
$accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity());
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
$scope = new ScopeEntity();
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
$scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scope);
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
$grant = new ClientCredentialsGrant();
@@ -93,5 +48,7 @@ class ClientCredentialsGrantTest extends TestCase
$responseType = new StubResponseType();
$grant->respondToAccessTokenRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
$this->assertTrue($responseType->getAccessToken() instanceof AccessTokenEntityInterface);
}
}

View File

@@ -9,22 +9,17 @@ use League\OAuth2\Server\Grant\ImplicitGrant;
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
use League\OAuth2\Server\Repositories\ClientRepositoryInterface;
use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;
use League\OAuth2\Server\Repositories\ScopeRepositoryInterface;
use League\OAuth2\Server\RequestTypes\AuthorizationRequest;
use League\OAuth2\Server\ResponseTypes\RedirectResponse;
use LeagueTests\Stubs\AccessTokenEntity;
use LeagueTests\Stubs\ClientEntity;
use LeagueTests\Stubs\CryptTraitStub;
use LeagueTests\Stubs\ScopeEntity;
use LeagueTests\Stubs\StubResponseType;
use LeagueTests\Stubs\UserEntity;
use PHPUnit\Framework\TestCase;
use Zend\Diactoros\ServerRequest;
class ImplicitGrantTest extends TestCase
class ImplicitGrantTest extends \PHPUnit_Framework_TestCase
{
const DEFAULT_SCOPE = 'basic';
/**
* CryptTrait stub
*/
@@ -91,15 +86,8 @@ class ImplicitGrantTest extends TestCase
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
$scopeEntity = new ScopeEntity();
$scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scopeEntity);
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
$grant->setClientRepository($clientRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setDefaultScope(self::DEFAULT_SCOPE);
$request = new ServerRequest(
[],
@@ -116,7 +104,7 @@ class ImplicitGrantTest extends TestCase
]
);
$this->assertInstanceOf(AuthorizationRequest::class, $grant->validateAuthorizationRequest($request));
$this->assertTrue($grant->validateAuthorizationRequest($request) instanceof AuthorizationRequest);
}
public function testValidateAuthorizationRequestRedirectUriArray()
@@ -126,15 +114,8 @@ class ImplicitGrantTest extends TestCase
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
$scopeEntity = new ScopeEntity();
$scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scopeEntity);
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
$grant->setClientRepository($clientRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setDefaultScope(self::DEFAULT_SCOPE);
$request = new ServerRequest(
[],
@@ -151,7 +132,7 @@ class ImplicitGrantTest extends TestCase
]
);
$this->assertInstanceOf(AuthorizationRequest::class, $grant->validateAuthorizationRequest($request));
$this->assertTrue($grant->validateAuthorizationRequest($request) instanceof AuthorizationRequest);
}
/**
@@ -288,9 +269,10 @@ class ImplicitGrantTest extends TestCase
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$this->assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest));
$this->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse);
}
/**
@@ -311,6 +293,7 @@ class ImplicitGrantTest extends TestCase
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->completeAuthorizationRequest($authRequest);
@@ -332,9 +315,10 @@ class ImplicitGrantTest extends TestCase
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$this->assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest));
$this->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse);
}
/**
@@ -356,6 +340,7 @@ class ImplicitGrantTest extends TestCase
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->completeAuthorizationRequest($authRequest);
@@ -380,6 +365,7 @@ class ImplicitGrantTest extends TestCase
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->completeAuthorizationRequest($authRequest);
@@ -412,42 +398,4 @@ class ImplicitGrantTest extends TestCase
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
$grant->completeAuthorizationRequest(new AuthorizationRequest());
}
/**
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
* @expectedExceptionCode 5
*/
public function testValidateAuthorizationRequestFailsWithoutScope()
{
$client = new ClientEntity();
$client->setRedirectUri('http://foo/bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
$scopeEntity = new ScopeEntity();
$scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scopeEntity);
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
$grant->setClientRepository($clientRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock);
$request = new ServerRequest(
[],
[],
null,
null,
'php://input',
$headers = [],
$cookies = [],
$queryParams = [
'response_type' => 'code',
'client_id' => 'foo',
'redirect_uri' => 'http://foo/bar',
]
);
$grant->validateAuthorizationRequest($request);
}
}

View File

@@ -13,16 +13,12 @@ use League\OAuth2\Server\Repositories\UserRepositoryInterface;
use LeagueTests\Stubs\AccessTokenEntity;
use LeagueTests\Stubs\ClientEntity;
use LeagueTests\Stubs\RefreshTokenEntity;
use LeagueTests\Stubs\ScopeEntity;
use LeagueTests\Stubs\StubResponseType;
use LeagueTests\Stubs\UserEntity;
use PHPUnit\Framework\TestCase;
use Zend\Diactoros\ServerRequest;
class PasswordGrantTest extends TestCase
class PasswordGrantTest extends \PHPUnit_Framework_TestCase
{
const DEFAULT_SCOPE = 'basic';
public function testGetIdentifier()
{
$userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
@@ -50,16 +46,13 @@ class PasswordGrantTest extends TestCase
$refreshTokenRepositoryMock->method('persistNewRefreshToken')->willReturnSelf();
$refreshTokenRepositoryMock->method('getNewRefreshToken')->willReturn(new RefreshTokenEntity());
$scope = new ScopeEntity();
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
$scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scope);
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
$grant = new PasswordGrant($userRepositoryMock, $refreshTokenRepositoryMock);
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setDefaultScope(self::DEFAULT_SCOPE);
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withParsedBody(
@@ -74,8 +67,8 @@ class PasswordGrantTest extends TestCase
$responseType = new StubResponseType();
$grant->respondToAccessTokenRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
$this->assertInstanceOf(AccessTokenEntityInterface::class, $responseType->getAccessToken());
$this->assertInstanceOf(RefreshTokenEntityInterface::class, $responseType->getRefreshToken());
$this->assertTrue($responseType->getAccessToken() instanceof AccessTokenEntityInterface);
$this->assertTrue($responseType->getRefreshToken() instanceof RefreshTokenEntityInterface);
}
/**
@@ -174,50 +167,4 @@ class PasswordGrantTest extends TestCase
$responseType = new StubResponseType();
$grant->respondToAccessTokenRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
}
/**
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
* @expectedExceptionCode 5
*/
public function testRespondToRequestFailsWithoutScope()
{
$client = new ClientEntity();
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
$accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity());
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
$userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
$userEntity = new UserEntity();
$userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity);
$refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
$refreshTokenRepositoryMock->method('persistNewRefreshToken')->willReturnSelf();
$refreshTokenRepositoryMock->method('getNewRefreshToken')->willReturn(new RefreshTokenEntity());
$scope = new ScopeEntity();
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
$scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scope);
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
$grant = new PasswordGrant($userRepositoryMock, $refreshTokenRepositoryMock);
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock);
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withParsedBody(
[
'client_id' => 'foo',
'client_secret' => 'bar',
'username' => 'foo',
'password' => 'bar',
]
);
$responseType = new StubResponseType();
$grant->respondToAccessTokenRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
}
}

View File

@@ -16,13 +16,12 @@ use LeagueTests\Stubs\CryptTraitStub;
use LeagueTests\Stubs\RefreshTokenEntity;
use LeagueTests\Stubs\ScopeEntity;
use LeagueTests\Stubs\StubResponseType;
use PHPUnit\Framework\TestCase;
use Zend\Diactoros\ServerRequest;
class RefreshTokenGrantTest extends TestCase
class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
{
/**
* @var CryptTraitStub
* CryptTrait stub
*/
protected $cryptStub;
@@ -46,24 +45,27 @@ class RefreshTokenGrantTest extends TestCase
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$scopeEntity = new ScopeEntity();
$scopeEntity->setIdentifier('foo');
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
$scopeEntity = new ScopeEntity();
$scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scopeEntity);
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
$accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity());
$accessTokenRepositoryMock->expects($this->once())->method('persistNewAccessToken')->willReturnSelf();
$accessTokenRepositoryMock
->expects($this->once())
->method('persistNewAccessToken')->willReturnSelf();
$refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
$refreshTokenRepositoryMock->method('getNewRefreshToken')->willReturn(new RefreshTokenEntity());
$refreshTokenRepositoryMock->expects($this->once())->method('persistNewRefreshToken')->willReturnSelf();
$refreshTokenRepositoryMock
->expects($this->once())
->method('persistNewRefreshToken')->willReturnSelf();
$grant = new RefreshTokenGrant($refreshTokenRepositoryMock);
$grant->setClientRepository($clientRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$oldRefreshToken = $this->cryptStub->doEncrypt(
@@ -80,18 +82,19 @@ class RefreshTokenGrantTest extends TestCase
);
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withParsedBody([
'client_id' => 'foo',
'client_secret' => 'bar',
'refresh_token' => $oldRefreshToken,
'scopes' => ['foo'],
]);
$serverRequest = $serverRequest->withParsedBody(
[
'client_id' => 'foo',
'client_secret' => 'bar',
'refresh_token' => $oldRefreshToken,
]
);
$responseType = new StubResponseType();
$grant->respondToAccessTokenRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
$this->assertInstanceOf(AccessTokenEntityInterface::class, $responseType->getAccessToken());
$this->assertInstanceOf(RefreshTokenEntityInterface::class, $responseType->getRefreshToken());
$this->assertTrue($responseType->getAccessToken() instanceof AccessTokenEntityInterface);
$this->assertTrue($responseType->getRefreshToken() instanceof RefreshTokenEntityInterface);
}
public function testRespondToReducedScopes()
@@ -118,7 +121,7 @@ class RefreshTokenGrantTest extends TestCase
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$oldRefreshToken = $this->cryptStub->doEncrypt(
@@ -147,8 +150,8 @@ class RefreshTokenGrantTest extends TestCase
$responseType = new StubResponseType();
$grant->respondToAccessTokenRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
$this->assertInstanceOf(AccessTokenEntityInterface::class, $responseType->getAccessToken());
$this->assertInstanceOf(RefreshTokenEntityInterface::class, $responseType->getRefreshToken());
$this->assertTrue($responseType->getAccessToken() instanceof AccessTokenEntityInterface);
$this->assertTrue($responseType->getRefreshToken() instanceof RefreshTokenEntityInterface);
}
/**
@@ -177,7 +180,7 @@ class RefreshTokenGrantTest extends TestCase
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$oldRefreshToken = $this->cryptStub->doEncrypt(
@@ -224,7 +227,7 @@ class RefreshTokenGrantTest extends TestCase
$grant = new RefreshTokenGrant($refreshTokenRepositoryMock);
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$serverRequest = new ServerRequest();
@@ -256,7 +259,7 @@ class RefreshTokenGrantTest extends TestCase
$grant = new RefreshTokenGrant($refreshTokenRepositoryMock);
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$oldRefreshToken = 'foobar';
@@ -288,13 +291,14 @@ class RefreshTokenGrantTest extends TestCase
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
$refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
$refreshTokenRepositoryMock->method('persistNewRefreshToken')->willReturnSelf();
$grant = new RefreshTokenGrant($refreshTokenRepositoryMock);
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$oldRefreshToken = $this->cryptStub->doEncrypt(
@@ -340,7 +344,7 @@ class RefreshTokenGrantTest extends TestCase
$grant = new RefreshTokenGrant($refreshTokenRepositoryMock);
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$oldRefreshToken = $this->cryptStub->doEncrypt(
@@ -387,7 +391,7 @@ class RefreshTokenGrantTest extends TestCase
$grant = new RefreshTokenGrant($refreshTokenRepositoryMock);
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$oldRefreshToken = $this->cryptStub->doEncrypt(

View File

@@ -11,24 +11,18 @@ use League\OAuth2\Server\Repositories\ClientRepositoryInterface;
use League\OAuth2\Server\Repositories\ScopeRepositoryInterface;
use LeagueTests\Stubs\AccessTokenEntity;
use LeagueTests\Stubs\ClientEntity;
use LeagueTests\Stubs\ScopeEntity;
use LeagueTests\Stubs\StubResponseType;
use PHPUnit\Framework\TestCase;
use Zend\Diactoros\Response;
use Zend\Diactoros\ServerRequestFactory;
class AuthorizationServerMiddlewareTest extends TestCase
class AuthorizationServerMiddlewareTest extends \PHPUnit_Framework_TestCase
{
const DEFAULT_SCOPE = 'basic';
public function testValidResponse()
{
$clientRepository = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepository->method('getClientEntity')->willReturn(new ClientEntity());
$scopeEntity = new ScopeEntity;
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
$scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scopeEntity);
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
$accessRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
@@ -39,11 +33,10 @@ class AuthorizationServerMiddlewareTest extends TestCase
$accessRepositoryMock,
$scopeRepositoryMock,
'file://' . __DIR__ . '/../Stubs/private.key',
base64_encode(random_bytes(36)),
'file://' . __DIR__ . '/../Stubs/public.key',
new StubResponseType()
);
$server->setDefaultScope(self::DEFAULT_SCOPE);
$server->enableGrantType(new ClientCredentialsGrant());
$_POST['grant_type'] = 'client_credentials';
@@ -73,7 +66,7 @@ class AuthorizationServerMiddlewareTest extends TestCase
$this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(),
$this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(),
'file://' . __DIR__ . '/../Stubs/private.key',
base64_encode(random_bytes(36)),
'file://' . __DIR__ . '/../Stubs/public.key',
new StubResponseType()
);
@@ -104,8 +97,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',
$response->getHeader('location')[0]);
$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', $response->getHeader('location')[0]);
}
public function testOAuthErrorResponseRedirectUriFragment()
@@ -114,7 +106,6 @@ 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',
$response->getHeader('location')[0]);
$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', $response->getHeader('location')[0]);
}
}

View File

@@ -8,11 +8,10 @@ use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
use League\OAuth2\Server\ResourceServer;
use LeagueTests\Stubs\AccessTokenEntity;
use LeagueTests\Stubs\ClientEntity;
use PHPUnit\Framework\TestCase;
use Zend\Diactoros\Response;
use Zend\Diactoros\ServerRequest;
class ResourceServerMiddlewareTest extends TestCase
class ResourceServerMiddlewareTest extends \PHPUnit_Framework_TestCase
{
public function testValidResponse()
{

View File

@@ -6,10 +6,9 @@ namespace LeagueTests;
use League\OAuth2\Server\Exception\OAuthServerException;
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
use League\OAuth2\Server\ResourceServer;
use PHPUnit\Framework\TestCase;
use Zend\Diactoros\ServerRequestFactory;
class ResourceServerTest extends TestCase
class ResourceServerTest extends \PHPUnit_Framework_TestCase
{
public function testValidateAuthenticatedRequest()
{

View File

@@ -11,12 +11,11 @@ use LeagueTests\Stubs\AccessTokenEntity;
use LeagueTests\Stubs\ClientEntity;
use LeagueTests\Stubs\RefreshTokenEntity;
use LeagueTests\Stubs\ScopeEntity;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\ResponseInterface;
use Zend\Diactoros\Response;
use Zend\Diactoros\ServerRequest;
class BearerResponseTypeTest extends TestCase
class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase
{
public function testGenerateHttpResponse()
{
@@ -24,7 +23,7 @@ class BearerResponseTypeTest extends TestCase
$responseType = new BearerTokenResponse($accessTokenRepositoryMock);
$responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$responseType->setEncryptionKey(base64_encode(random_bytes(36)));
$responseType->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$client = new ClientEntity();
$client->setIdentifier('clientName');
@@ -48,7 +47,7 @@ class BearerResponseTypeTest extends TestCase
$response = $responseType->generateHttpResponse(new Response());
$this->assertInstanceOf(ResponseInterface::class, $response);
$this->assertTrue($response instanceof ResponseInterface);
$this->assertEquals(200, $response->getStatusCode());
$this->assertEquals('no-cache', $response->getHeader('pragma')[0]);
$this->assertEquals('no-store', $response->getHeader('cache-control')[0]);
@@ -56,10 +55,10 @@ class BearerResponseTypeTest extends TestCase
$response->getBody()->rewind();
$json = json_decode($response->getBody()->getContents());
$this->assertAttributeEquals('Bearer', 'token_type', $json);
$this->assertObjectHasAttribute('expires_in', $json);
$this->assertObjectHasAttribute('access_token', $json);
$this->assertObjectHasAttribute('refresh_token', $json);
$this->assertEquals('Bearer', $json->token_type);
$this->assertTrue(isset($json->expires_in));
$this->assertTrue(isset($json->access_token));
$this->assertTrue(isset($json->refresh_token));
}
public function testGenerateHttpResponseWithExtraParams()
@@ -68,7 +67,7 @@ class BearerResponseTypeTest extends TestCase
$responseType = new BearerTokenResponseWithParams($accessTokenRepositoryMock);
$responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$responseType->setEncryptionKey(base64_encode(random_bytes(36)));
$responseType->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$client = new ClientEntity();
$client->setIdentifier('clientName');
@@ -92,7 +91,7 @@ class BearerResponseTypeTest extends TestCase
$response = $responseType->generateHttpResponse(new Response());
$this->assertInstanceOf(ResponseInterface::class, $response);
$this->assertTrue($response instanceof ResponseInterface);
$this->assertEquals(200, $response->getStatusCode());
$this->assertEquals('no-cache', $response->getHeader('pragma')[0]);
$this->assertEquals('no-store', $response->getHeader('cache-control')[0]);
@@ -100,13 +99,13 @@ class BearerResponseTypeTest extends TestCase
$response->getBody()->rewind();
$json = json_decode($response->getBody()->getContents());
$this->assertAttributeEquals('Bearer', 'token_type', $json);
$this->assertObjectHasAttribute('expires_in', $json);
$this->assertObjectHasAttribute('access_token', $json);
$this->assertObjectHasAttribute('refresh_token', $json);
$this->assertEquals('Bearer', $json->token_type);
$this->assertTrue(isset($json->expires_in));
$this->assertTrue(isset($json->access_token));
$this->assertTrue(isset($json->refresh_token));
$this->assertObjectHasAttribute('foo', $json);
$this->assertAttributeEquals('bar', 'foo', $json);
$this->assertTrue(isset($json->foo));
$this->assertEquals('bar', $json->foo);
}
public function testDetermineAccessTokenInHeaderValidToken()
@@ -116,7 +115,7 @@ class BearerResponseTypeTest extends TestCase
$responseType = new BearerTokenResponse($accessTokenRepositoryMock);
$responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$responseType->setEncryptionKey(base64_encode(random_bytes(36)));
$responseType->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$client = new ClientEntity();
$client->setIdentifier('clientName');
@@ -142,6 +141,7 @@ class BearerResponseTypeTest extends TestCase
$accessTokenRepositoryMock->method('isAccessTokenRevoked')->willReturn(false);
$authorizationValidator = new BearerTokenValidator($accessTokenRepositoryMock);
$authorizationValidator->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$authorizationValidator->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$request = new ServerRequest();
@@ -162,7 +162,7 @@ class BearerResponseTypeTest extends TestCase
$responseType = new BearerTokenResponse($accessTokenRepositoryMock);
$responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$responseType->setEncryptionKey(base64_encode(random_bytes(36)));
$responseType->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$client = new ClientEntity();
$client->setIdentifier('clientName');
@@ -185,6 +185,7 @@ class BearerResponseTypeTest extends TestCase
$json = json_decode((string) $response->getBody());
$authorizationValidator = new BearerTokenValidator($accessTokenRepositoryMock);
$authorizationValidator->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$authorizationValidator->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$request = new ServerRequest();
@@ -204,7 +205,7 @@ class BearerResponseTypeTest extends TestCase
{
$responseType = new BearerTokenResponse();
$responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$responseType->setEncryptionKey(base64_encode(random_bytes(36)));
$responseType->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$client = new ClientEntity();
$client->setIdentifier('clientName');
@@ -230,6 +231,7 @@ class BearerResponseTypeTest extends TestCase
$accessTokenRepositoryMock->method('isAccessTokenRevoked')->willReturn(true);
$authorizationValidator = new BearerTokenValidator($accessTokenRepositoryMock);
$authorizationValidator->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$authorizationValidator->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$request = new ServerRequest();
@@ -251,11 +253,12 @@ class BearerResponseTypeTest extends TestCase
$responseType = new BearerTokenResponse($accessTokenRepositoryMock);
$responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$responseType->setEncryptionKey(base64_encode(random_bytes(36)));
$responseType->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
$authorizationValidator = new BearerTokenValidator($accessTokenRepositoryMock);
$authorizationValidator->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$authorizationValidator->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$request = new ServerRequest();
@@ -277,11 +280,12 @@ class BearerResponseTypeTest extends TestCase
$responseType = new BearerTokenResponse($accessTokenRepositoryMock);
$responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$responseType->setEncryptionKey(base64_encode(random_bytes(36)));
$responseType->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
$authorizationValidator = new BearerTokenValidator($accessTokenRepositoryMock);
$authorizationValidator->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$authorizationValidator->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$request = new ServerRequest();

View File

@@ -2,6 +2,7 @@
namespace LeagueTests\Stubs;
use League\OAuth2\Server\CryptKey;
use League\OAuth2\Server\CryptTrait;
class CryptTraitStub
@@ -10,12 +11,8 @@ class CryptTraitStub
public function __construct()
{
$this->setEncryptionKey(base64_encode(random_bytes(36)));
}
public function getKey()
{
return $this->encryptionKey;
$this->setPrivateKey(new CryptKey('file://' . __DIR__ . '/private.key'));
$this->setPublicKey(new CryptKey('file://' . __DIR__ . '/public.key'));
}
public function doEncrypt($unencryptedData)