Merge branch 'master' of github.com:erickjth/oauth2-server into fix-pkce-implementation

# Conflicts:
#	src/Grant/AuthCodeGrant.php
#	tests/Grant/AuthCodeGrantTest.php
This commit is contained in:
Erick Torres 2017-07-07 12:06:32 -05:00
commit fbb3586cae
32 changed files with 497 additions and 285 deletions

View File

@ -8,12 +8,9 @@ cache:
- vendor - vendor
php: php:
- 5.5.9
- 5.5
- 5.6 - 5.6
- 7.0 - 7.0
- 7.1 - 7.1
- hhvm
install: install:
- travis_retry composer install --no-interaction --prefer-source - travis_retry composer install --no-interaction --prefer-source

View File

@ -1,5 +1,20 @@
# Changelog # Changelog
## 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) ## 5.1.3 (released 2016-10-12)
* Fixed WWW-Authenticate header (Issue #669) * Fixed WWW-Authenticate header (Issue #669)

View File

@ -1,5 +1,11 @@
# PHP OAuth 2.0 Server # 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.4` (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) [![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) [![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) [![Build Status](https://img.shields.io/travis/thephpleague/oauth2-server/master.svg?style=flat-square)](https://travis-ci.org/thephpleague/oauth2-server)
@ -30,11 +36,9 @@ This library was created by Alex Bilbie. Find him on Twitter at [@alexbilbie](ht
The following versions of PHP are supported: The following versions of PHP are supported:
* PHP 5.5 (>=5.5.9)
* PHP 5.6 * PHP 5.6
* PHP 7.0 * PHP 7.0
* PHP 7.1 * PHP 7.1
* HHVM
The `openssl` extension is also required. The `openssl` extension is also required.
@ -73,6 +77,8 @@ This package is released under the MIT License. See the bundled [LICENSE](https:
This code is principally developed and maintained by [Alex Bilbie](https://twitter.com/alexbilbie). This code is principally developed and maintained by [Alex Bilbie](https://twitter.com/alexbilbie).
Special thanks to [all of these awesome contributors](https://github.com/thephpleague/oauth2-server/contributors) 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.
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. 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,17 @@
"homepage": "https://oauth2.thephpleague.com/", "homepage": "https://oauth2.thephpleague.com/",
"license": "MIT", "license": "MIT",
"require": { "require": {
"php": ">=5.5.9", "php": ">=5.6.0",
"ext-openssl": "*", "ext-openssl": "*",
"league/event": "^2.1", "league/event": "^2.1",
"lcobucci/jwt": "^3.1", "lcobucci/jwt": "^3.1",
"paragonie/random_compat": "^1.1 || ^2.0", "paragonie/random_compat": "^2.0",
"psr/http-message": "^1.0" "psr/http-message": "^1.0",
"defuse/php-encryption": "^2.1"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^4.8 || ^5.0", "phpunit/phpunit": "^4.8 || ^5.0",
"zendframework/zend-diactoros": "^1.0", "zendframework/zend-diactoros": "^1.0"
"indigophp/hash-compat": "^1.1"
}, },
"repositories": [ "repositories": [
{ {
@ -59,13 +59,5 @@
"psr-4": { "psr-4": {
"LeagueTests\\": "tests/" "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

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

178
examples/composer.lock generated
View File

@ -4,23 +4,25 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"hash": "48bcb7a3514d7c7f271c554ba1440124", "content-hash": "9813ed7c3b6dcf107f44df9392935b8f",
"content-hash": "e41be75973527cb9d63f27ad14ac8624",
"packages": [ "packages": [
{ {
"name": "container-interop/container-interop", "name": "container-interop/container-interop",
"version": "1.1.0", "version": "1.2.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/container-interop/container-interop.git", "url": "https://github.com/container-interop/container-interop.git",
"reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e" "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/container-interop/container-interop/zipball/fc08354828f8fd3245f77a66b9e23a6bca48297e", "url": "https://api.github.com/repos/container-interop/container-interop/zipball/79cbf1341c22ec75643d841642dd5d6acd83bdb8",
"reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e", "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8",
"shasum": "" "shasum": ""
}, },
"require": {
"psr/container": "^1.0"
},
"type": "library", "type": "library",
"autoload": { "autoload": {
"psr-4": { "psr-4": {
@ -32,7 +34,8 @@
"MIT" "MIT"
], ],
"description": "Promoting the interoperability of container objects (DIC, SL, etc.)", "description": "Promoting the interoperability of container objects (DIC, SL, etc.)",
"time": "2014-12-30 15:22:37" "homepage": "https://github.com/container-interop/container-interop",
"time": "2017-02-14T19:40:03+00:00"
}, },
{ {
"name": "nikic/fast-route", "name": "nikic/fast-route",
@ -75,7 +78,7 @@
"router", "router",
"routing" "routing"
], ],
"time": "2015-06-18 19:15:47" "time": "2015-06-18T19:15:47+00:00"
}, },
{ {
"name": "pimple/pimple", "name": "pimple/pimple",
@ -121,20 +124,69 @@
"container", "container",
"dependency injection" "dependency injection"
], ],
"time": "2015-09-11 15:10:35" "time": "2015-09-11T15:10:35+00:00"
}, },
{ {
"name": "psr/http-message", "name": "psr/container",
"version": "1.0", "version": "1.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/php-fig/http-message.git", "url": "https://github.com/php-fig/container.git",
"reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298" "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
"reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", "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"
},
{
"name": "psr/http-message",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -162,6 +214,7 @@
} }
], ],
"description": "Common interface for HTTP messages", "description": "Common interface for HTTP messages",
"homepage": "https://github.com/php-fig/http-message",
"keywords": [ "keywords": [
"http", "http",
"http-message", "http-message",
@ -170,7 +223,7 @@
"request", "request",
"response" "response"
], ],
"time": "2015-05-04 20:22:00" "time": "2016-08-06T14:39:51+00:00"
}, },
{ {
"name": "slim/slim", "name": "slim/slim",
@ -236,22 +289,85 @@
"micro", "micro",
"router" "router"
], ],
"time": "2015-12-07 14:11:09" "time": "2015-12-07T14:11:09+00:00"
} }
], ],
"packages-dev": [ "packages-dev": [
{ {
"name": "lcobucci/jwt", "name": "defuse/php-encryption",
"version": "3.1.1", "version": "v2.1.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/lcobucci/jwt.git", "url": "https://github.com/defuse/php-encryption.git",
"reference": "afea8e682e911a21574fd8519321b32522fa25b5" "reference": "5176f5abb38d3ea8a6e3ac6cd3bbb54d8185a689"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/lcobucci/jwt/zipball/afea8e682e911a21574fd8519321b32522fa25b5", "url": "https://api.github.com/repos/defuse/php-encryption/zipball/5176f5abb38d3ea8a6e3ac6cd3bbb54d8185a689",
"reference": "afea8e682e911a21574fd8519321b32522fa25b5", "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",
"source": {
"type": "git",
"url": "https://github.com/lcobucci/jwt.git",
"reference": "ddce703826f9c5229781933b1a39069e38e6a0f3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/lcobucci/jwt/zipball/ddce703826f9c5229781933b1a39069e38e6a0f3",
"reference": "ddce703826f9c5229781933b1a39069e38e6a0f3",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -259,7 +375,7 @@
"php": ">=5.5" "php": ">=5.5"
}, },
"require-dev": { "require-dev": {
"mdanter/ecc": "~0.3", "mdanter/ecc": "~0.3.1",
"mikey179/vfsstream": "~1.5", "mikey179/vfsstream": "~1.5",
"phpmd/phpmd": "~2.2", "phpmd/phpmd": "~2.2",
"phpunit/php-invoker": "~1.1", "phpunit/php-invoker": "~1.1",
@ -296,7 +412,7 @@
"JWS", "JWS",
"jwt" "jwt"
], ],
"time": "2016-03-24 22:46:13" "time": "2016-10-31T20:09:32+00:00"
}, },
{ {
"name": "league/event", "name": "league/event",
@ -346,20 +462,20 @@
"event", "event",
"listener" "listener"
], ],
"time": "2015-05-21 12:24:47" "time": "2015-05-21T12:24:47+00:00"
}, },
{ {
"name": "paragonie/random_compat", "name": "paragonie/random_compat",
"version": "v1.4.1", "version": "v2.0.10",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/paragonie/random_compat.git", "url": "https://github.com/paragonie/random_compat.git",
"reference": "c7e26a21ba357863de030f0b9e701c7d04593774" "reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/c7e26a21ba357863de030f0b9e701c7d04593774", "url": "https://api.github.com/repos/paragonie/random_compat/zipball/634bae8e911eefa89c1abfbf1b66da679ac8f54d",
"reference": "c7e26a21ba357863de030f0b9e701c7d04593774", "reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -394,7 +510,7 @@
"pseudorandom", "pseudorandom",
"random" "random"
], ],
"time": "2016-03-18 20:34:03" "time": "2017-03-13T16:27:32+00:00"
} }
], ],
"aliases": [], "aliases": [],

View File

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

View File

@ -32,7 +32,6 @@ $app = new App([
// Path to public and private keys // 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 //$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 // Setup the authorization server
$server = new AuthorizationServer( $server = new AuthorizationServer(
@ -40,7 +39,7 @@ $app = new App([
$accessTokenRepository, $accessTokenRepository,
$scopeRepository, $scopeRepository,
$privateKey, $privateKey,
$publicKey 'lxZFUEsBCJ2Yb14IF2ygAHI5N4+ZAUXXaSeeJm6+twsUmIen'
); );
// Enable the client credentials grant on the server // Enable the client credentials grant on the server

View File

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

View File

@ -8,11 +8,11 @@
*/ */
use League\OAuth2\Server\AuthorizationServer; use League\OAuth2\Server\AuthorizationServer;
use League\OAuth2\Server\ResourceServer;
use League\OAuth2\Server\Grant\AuthCodeGrant; use League\OAuth2\Server\Grant\AuthCodeGrant;
use League\OAuth2\Server\Grant\RefreshTokenGrant; use League\OAuth2\Server\Grant\RefreshTokenGrant;
use League\OAuth2\Server\Middleware\AuthorizationServerMiddleware; use League\OAuth2\Server\Middleware\AuthorizationServerMiddleware;
use League\OAuth2\Server\Middleware\ResourceServerMiddleware; use League\OAuth2\Server\Middleware\ResourceServerMiddleware;
use League\OAuth2\Server\ResourceServer;
use OAuth2ServerExamples\Repositories\AccessTokenRepository; use OAuth2ServerExamples\Repositories\AccessTokenRepository;
use OAuth2ServerExamples\Repositories\AuthCodeRepository; use OAuth2ServerExamples\Repositories\AuthCodeRepository;
use OAuth2ServerExamples\Repositories\ClientRepository; use OAuth2ServerExamples\Repositories\ClientRepository;
@ -38,7 +38,6 @@ $app = new App([
$refreshTokenRepository = new RefreshTokenRepository(); $refreshTokenRepository = new RefreshTokenRepository();
$privateKeyPath = 'file://' . __DIR__ . '/../private.key'; $privateKeyPath = 'file://' . __DIR__ . '/../private.key';
$publicKeyPath = 'file://' . __DIR__ . '/../public.key';
// Setup the authorization server // Setup the authorization server
$server = new AuthorizationServer( $server = new AuthorizationServer(
@ -46,7 +45,7 @@ $app = new App([
$accessTokenRepository, $accessTokenRepository,
$scopeRepository, $scopeRepository,
$privateKeyPath, $privateKeyPath,
$publicKeyPath 'lxZFUEsBCJ2Yb14IF2ygAHI5N4+ZAUXXaSeeJm6+twsUmIen'
); );
// Enable the authentication code grant on the server with a token TTL of 1 hour // Enable the authentication code grant on the server with a token TTL of 1 hour
@ -74,6 +73,7 @@ $app = new App([
new AccessTokenRepository(), new AccessTokenRepository(),
$publicKeyPath $publicKeyPath
); );
return $server; return $server;
}, },
]); ]);

View File

@ -24,7 +24,7 @@ $app = new App([
new AccessTokenRepository(), // instance of AccessTokenRepositoryInterface new AccessTokenRepository(), // instance of AccessTokenRepositoryInterface
new ScopeRepository(), // instance of ScopeRepositoryInterface new ScopeRepository(), // instance of ScopeRepositoryInterface
'file://' . __DIR__ . '/../private.key', // path to private key 'file://' . __DIR__ . '/../private.key', // path to private key
'file://' . __DIR__ . '/../public.key' // path to public key 'lxZFUEsBCJ2Yb14IF2ygAHI5N4+ZAUXXaSeeJm6+twsUmIen' // encryption key
); );
$grant = new PasswordGrant( $grant = new PasswordGrant(

View File

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

View File

@ -3,7 +3,6 @@
* @author Alex Bilbie <hello@alexbilbie.com> * @author Alex Bilbie <hello@alexbilbie.com>
* @copyright Copyright (c) Alex Bilbie * @copyright Copyright (c) Alex Bilbie
* @license http://mit-license.org/ * @license http://mit-license.org/
*
* @link https://github.com/thephpleague/oauth2-server * @link https://github.com/thephpleague/oauth2-server
*/ */
@ -66,6 +65,11 @@ class AuthorizationServer implements EmitterAwareInterface
*/ */
private $scopeRepository; private $scopeRepository;
/**
* @var string
*/
private $encryptionKey;
/** /**
* New server instance. * New server instance.
* *
@ -73,7 +77,7 @@ class AuthorizationServer implements EmitterAwareInterface
* @param AccessTokenRepositoryInterface $accessTokenRepository * @param AccessTokenRepositoryInterface $accessTokenRepository
* @param ScopeRepositoryInterface $scopeRepository * @param ScopeRepositoryInterface $scopeRepository
* @param CryptKey|string $privateKey * @param CryptKey|string $privateKey
* @param CryptKey|string $publicKey * @param string $encryptionKey
* @param null|ResponseTypeInterface $responseType * @param null|ResponseTypeInterface $responseType
*/ */
public function __construct( public function __construct(
@ -81,7 +85,7 @@ class AuthorizationServer implements EmitterAwareInterface
AccessTokenRepositoryInterface $accessTokenRepository, AccessTokenRepositoryInterface $accessTokenRepository,
ScopeRepositoryInterface $scopeRepository, ScopeRepositoryInterface $scopeRepository,
$privateKey, $privateKey,
$publicKey, $encryptionKey,
ResponseTypeInterface $responseType = null ResponseTypeInterface $responseType = null
) { ) {
$this->clientRepository = $clientRepository; $this->clientRepository = $clientRepository;
@ -93,11 +97,7 @@ class AuthorizationServer implements EmitterAwareInterface
} }
$this->privateKey = $privateKey; $this->privateKey = $privateKey;
if ($publicKey instanceof CryptKey === false) { $this->encryptionKey = $encryptionKey;
$publicKey = new CryptKey($publicKey);
}
$this->publicKey = $publicKey;
$this->responseType = $responseType; $this->responseType = $responseType;
} }
@ -117,8 +117,8 @@ class AuthorizationServer implements EmitterAwareInterface
$grantType->setClientRepository($this->clientRepository); $grantType->setClientRepository($this->clientRepository);
$grantType->setScopeRepository($this->scopeRepository); $grantType->setScopeRepository($this->scopeRepository);
$grantType->setPrivateKey($this->privateKey); $grantType->setPrivateKey($this->privateKey);
$grantType->setPublicKey($this->publicKey);
$grantType->setEmitter($this->getEmitter()); $grantType->setEmitter($this->getEmitter());
$grantType->setEncryptionKey($this->encryptionKey);
$this->enabledGrantTypes[$grantType->getIdentifier()] = $grantType; $this->enabledGrantTypes[$grantType->getIdentifier()] = $grantType;
$this->grantTypeAccessTokenTTL[$grantType->getIdentifier()] = $accessTokenTTL; $this->grantTypeAccessTokenTTL[$grantType->getIdentifier()] = $accessTokenTTL;
@ -200,6 +200,7 @@ class AuthorizationServer implements EmitterAwareInterface
} }
$this->responseType->setPrivateKey($this->privateKey); $this->responseType->setPrivateKey($this->privateKey);
$this->responseType->setEncryptionKey($this->encryptionKey);
return $this->responseType; return $this->responseType;
} }

View File

@ -12,6 +12,7 @@ namespace League\OAuth2\Server\AuthorizationValidators;
use Lcobucci\JWT\Parser; use Lcobucci\JWT\Parser;
use Lcobucci\JWT\Signer\Rsa\Sha256; use Lcobucci\JWT\Signer\Rsa\Sha256;
use Lcobucci\JWT\ValidationData; use Lcobucci\JWT\ValidationData;
use League\OAuth2\Server\CryptKey;
use League\OAuth2\Server\CryptTrait; use League\OAuth2\Server\CryptTrait;
use League\OAuth2\Server\Exception\OAuthServerException; use League\OAuth2\Server\Exception\OAuthServerException;
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
@ -26,6 +27,11 @@ class BearerTokenValidator implements AuthorizationValidatorInterface
*/ */
private $accessTokenRepository; private $accessTokenRepository;
/**
* @var \League\OAuth2\Server\CryptKey
*/
protected $publicKey;
/** /**
* @param AccessTokenRepositoryInterface $accessTokenRepository * @param AccessTokenRepositoryInterface $accessTokenRepository
*/ */
@ -34,6 +40,16 @@ class BearerTokenValidator implements AuthorizationValidatorInterface
$this->accessTokenRepository = $accessTokenRepository; $this->accessTokenRepository = $accessTokenRepository;
} }
/**
* Set the private key
*
* @param \League\OAuth2\Server\CryptKey $key
*/
public function setPublicKey(CryptKey $key)
{
$this->publicKey = $key;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */

View File

@ -44,6 +44,23 @@ class CryptKey
throw new \LogicException(sprintf('Key path "%s" does not exist or is not readable', $keyPath)); throw new \LogicException(sprintf('Key path "%s" does not exist or is not readable', $keyPath));
} }
// Verify the permissions of the key
$keyPathPerms = decoct(fileperms($keyPath) & 0777);
if ($keyPathPerms !== '600') {
// Attempt to correct the permissions
if (chmod($keyPath, 0600) === false) {
// @codeCoverageIgnoreStart
throw new \LogicException(
sprintf(
'Key file "%s" permissions are not correct, should be 600 instead of %s, unable to automatically resolve the issue',
$keyPath,
$keyPathPerms
)
);
// @codeCoverageIgnoreEnd
}
}
$this->keyPath = $keyPath; $this->keyPath = $keyPath;
$this->passPhrase = $passPhrase; $this->passPhrase = $passPhrase;
} }
@ -57,15 +74,26 @@ class CryptKey
*/ */
private function saveKeyToFile($key) private function saveKeyToFile($key)
{ {
$keyPath = sys_get_temp_dir() . '/' . sha1($key) . '.key'; $tmpDir = sys_get_temp_dir();
$keyPath = $tmpDir . '/' . sha1($key) . '.key';
if (!file_exists($keyPath) && !touch($keyPath)) { if (!file_exists($keyPath) && !touch($keyPath)) {
// @codeCoverageIgnoreStart // @codeCoverageIgnoreStart
throw new \RuntimeException('"%s" key file could not be created', $keyPath); throw new \RuntimeException(sprintf('"%s" key file could not be created', $keyPath));
// @codeCoverageIgnoreEnd // @codeCoverageIgnoreEnd
} }
file_put_contents($keyPath, $key); 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
}
return 'file://' . $keyPath; return 'file://' . $keyPath;
} }

View File

@ -1,47 +1,22 @@
<?php <?php
/** /**
* Public/private key encryption. * Public/private key encryption.
*
* @author Alex Bilbie <hello@alexbilbie.com> * @author Alex Bilbie <hello@alexbilbie.com>
* @copyright Copyright (c) Alex Bilbie * @copyright Copyright (c) Alex Bilbie
* @license http://mit-license.org/ * @license http://mit-license.org/
*
* @link https://github.com/thephpleague/oauth2-server * @link https://github.com/thephpleague/oauth2-server
*/ */
namespace League\OAuth2\Server; namespace League\OAuth2\Server;
use Defuse\Crypto\Crypto;
trait CryptTrait trait CryptTrait
{ {
/** /**
* @var CryptKey * @var string
*/ */
protected $privateKey; protected $encryptionKey;
/**
* @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. * Encrypt data with a private key.
@ -49,35 +24,15 @@ trait CryptTrait
* @param string $unencryptedData * @param string $unencryptedData
* *
* @throws \LogicException * @throws \LogicException
*
* @return string * @return string
*/ */
protected function encrypt($unencryptedData) protected function encrypt($unencryptedData)
{ {
$privateKey = openssl_pkey_get_private($this->privateKey->getKeyPath(), $this->privateKey->getPassPhrase()); try {
$privateKeyDetails = @openssl_pkey_get_details($privateKey); return Crypto::encryptWithPassword($unencryptedData, $this->encryptionKey);
if ($privateKeyDetails === null) { } catch (\Exception $e) {
throw new \LogicException( throw new \LogicException($e->getMessage());
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);
} }
/** /**
@ -86,36 +41,24 @@ trait CryptTrait
* @param string $encryptedData * @param string $encryptedData
* *
* @throws \LogicException * @throws \LogicException
*
* @return string * @return string
*/ */
protected function decrypt($encryptedData) protected function decrypt($encryptedData)
{ {
$publicKey = openssl_pkey_get_public($this->publicKey->getKeyPath()); try {
$publicKeyDetails = @openssl_pkey_get_details($publicKey); return Crypto::decryptWithPassword($encryptedData, $this->encryptionKey);
if ($publicKeyDetails === null) { } catch (\Exception $e) {
throw new \LogicException( throw new \LogicException($e->getMessage());
sprintf('Could not get details of public key: %s', $this->publicKey->getKeyPath()) }
);
} }
$chunkSize = ceil($publicKeyDetails['bits'] / 8); /**
$output = ''; * Set the encryption key
*
$encryptedData = base64_decode($encryptedData); * @param string $key
*/
while ($encryptedData) { public function setEncryptionKey($key = null)
$chunk = substr($encryptedData, 0, $chunkSize); {
$encryptedData = substr($encryptedData, $chunkSize); $this->encryptionKey = $key;
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,7 +105,10 @@ class OAuthServerException extends \Exception
public static function invalidScope($scope, $redirectUri = null) public static function invalidScope($scope, $redirectUri = null)
{ {
$errorMessage = 'The requested scope is invalid, unknown, or malformed'; $errorMessage = 'The requested scope is invalid, unknown, or malformed';
$hint = sprintf('Check the `%s` scope', $scope); $hint = sprintf(
'Check the `%s` scope',
htmlspecialchars($scope, ENT_QUOTES, 'UTF-8', false)
);
return new static($errorMessage, 5, 'invalid_scope', 400, $hint, $redirectUri); return new static($errorMessage, 5, 'invalid_scope', 400, $hint, $redirectUri);
} }

View File

@ -11,6 +11,7 @@
namespace League\OAuth2\Server\Grant; namespace League\OAuth2\Server\Grant;
use League\Event\EmitterAwareTrait; use League\Event\EmitterAwareTrait;
use League\OAuth2\Server\CryptKey;
use League\OAuth2\Server\CryptTrait; use League\OAuth2\Server\CryptTrait;
use League\OAuth2\Server\Entities\AccessTokenEntityInterface; use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
use League\OAuth2\Server\Entities\AuthCodeEntityInterface; use League\OAuth2\Server\Entities\AuthCodeEntityInterface;
@ -75,6 +76,11 @@ abstract class AbstractGrant implements GrantTypeInterface
*/ */
protected $refreshTokenTTL; protected $refreshTokenTTL;
/**
* @var \League\OAuth2\Server\CryptKey
*/
protected $privateKey;
/** /**
* @param ClientRepositoryInterface $clientRepository * @param ClientRepositoryInterface $clientRepository
*/ */
@ -131,6 +137,16 @@ abstract class AbstractGrant implements GrantTypeInterface
$this->refreshTokenTTL = $refreshTokenTTL; $this->refreshTokenTTL = $refreshTokenTTL;
} }
/**
* Set the private key
*
* @param \League\OAuth2\Server\CryptKey $key
*/
public function setPrivateKey(CryptKey $key)
{
$this->privateKey = $key;
}
/** /**
* Validate the client. * Validate the client.
* *

View File

@ -275,6 +275,13 @@ class AuthCodeGrant extends AbstractAuthorizeGrant
throw OAuthServerException::invalidRequest('code_challenge'); 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'); $codeChallengeMethod = $this->getQueryStringParameter('code_challenge_method', $request, 'plain');
if (in_array($codeChallengeMethod, ['plain', 'S256']) === false) { if (in_array($codeChallengeMethod, ['plain', 'S256']) === false) {
throw OAuthServerException::invalidRequest( throw OAuthServerException::invalidRequest(
@ -326,14 +333,7 @@ class AuthCodeGrant extends AbstractAuthorizeGrant
$authorizationRequest->getScopes() $authorizationRequest->getScopes()
); );
$response = new RedirectResponse(); $payload = [
$response->setRedirectUri(
$this->makeRedirectUri(
$finalRedirectUri,
[
'code' => $this->encrypt(
json_encode(
[
'client_id' => $authCode->getClient()->getIdentifier(), 'client_id' => $authCode->getClient()->getIdentifier(),
'redirect_uri' => $authCode->getRedirectUri(), 'redirect_uri' => $authCode->getRedirectUri(),
'auth_code_id' => $authCode->getIdentifier(), 'auth_code_id' => $authCode->getIdentifier(),
@ -342,7 +342,16 @@ class AuthCodeGrant extends AbstractAuthorizeGrant
'expire_time' => (new \DateTime())->add($this->authCodeTTL)->format('U'), 'expire_time' => (new \DateTime())->add($this->authCodeTTL)->format('U'),
'code_challenge' => $authorizationRequest->getCodeChallenge(), 'code_challenge' => $authorizationRequest->getCodeChallenge(),
'code_challenge_method' => $authorizationRequest->getCodeChallengeMethod(), 'code_challenge_method' => $authorizationRequest->getCodeChallengeMethod(),
] ];
$response = new RedirectResponse();
$response->setRedirectUri(
$this->makeRedirectUri(
$finalRedirectUri,
[
'code' => $this->encrypt(
json_encode(
$payload
) )
), ),
'state' => $authorizationRequest->getState(), 'state' => $authorizationRequest->getState(),

View File

@ -127,9 +127,9 @@ interface GrantTypeInterface extends EmitterAwareInterface
public function setPrivateKey(CryptKey $privateKey); public function setPrivateKey(CryptKey $privateKey);
/** /**
* Set the path to the public key. * Set the encryption key
* *
* @param CryptKey $publicKey * @param string|null $key
*/ */
public function setPublicKey(CryptKey $publicKey); public function setEncryptionKey($key = null);
} }

View File

@ -102,7 +102,7 @@ class RefreshTokenGrant extends AbstractGrant
// Validate refresh token // Validate refresh token
try { try {
$refreshToken = $this->decrypt($encryptedRefreshToken); $refreshToken = $this->decrypt($encryptedRefreshToken);
} catch (\LogicException $e) { } catch (\Exception $e) {
throw OAuthServerException::invalidRefreshToken('Cannot decrypt the refresh token'); throw OAuthServerException::invalidRefreshToken('Cannot decrypt the refresh token');
} }

View File

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

View File

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

View File

@ -33,7 +33,7 @@ class AuthorizationServerTest extends \PHPUnit_Framework_TestCase
$this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(), $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(),
$this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(), $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(),
'file://' . __DIR__ . '/Stubs/private.key', 'file://' . __DIR__ . '/Stubs/private.key',
'file://' . __DIR__ . '/Stubs/public.key', base64_encode(random_bytes(36)),
new StubResponseType() new StubResponseType()
); );
@ -63,7 +63,7 @@ class AuthorizationServerTest extends \PHPUnit_Framework_TestCase
$accessTokenRepositoryMock, $accessTokenRepositoryMock,
$scopeRepositoryMock, $scopeRepositoryMock,
'file://' . __DIR__ . '/Stubs/private.key', 'file://' . __DIR__ . '/Stubs/private.key',
'file://' . __DIR__ . '/Stubs/public.key', base64_encode(random_bytes(36)),
new StubResponseType() new StubResponseType()
); );
@ -116,9 +116,6 @@ class AuthorizationServerTest extends \PHPUnit_Framework_TestCase
new \DateInterval('PT10M') new \DateInterval('PT10M')
); );
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/Stubs/private.key'));
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/Stubs/public.key'));
$server->enableGrantType($grant); $server->enableGrantType($grant);
$authRequest = new AuthorizationRequest(); $authRequest = new AuthorizationRequest();

View File

@ -8,7 +8,7 @@ use LeagueTests\Stubs\CryptTraitStub;
class CryptTraitTest extends \PHPUnit_Framework_TestCase class CryptTraitTest extends \PHPUnit_Framework_TestCase
{ {
/** /**
* CryptTrait stub * @var \LeagueTests\Stubs\CryptTraitStub
*/ */
protected $cryptStub; protected $cryptStub;
@ -26,30 +26,4 @@ class CryptTraitTest extends \PHPUnit_Framework_TestCase
$this->assertNotEquals($payload, $encrypted); $this->assertNotEquals($payload, $encrypted);
$this->assertEquals($payload, $plainText); $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

@ -27,8 +27,6 @@ class AbstractGrantTest extends \PHPUnit_Framework_TestCase
{ {
/** @var AbstractGrant $grantMock */ /** @var AbstractGrant $grantMock */
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class); $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()); $grantMock->setEmitter(new Emitter());
} }

View File

@ -183,6 +183,117 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($grant->validateAuthorizationRequest($request) instanceof AuthorizationRequest); $this->assertTrue($grant->validateAuthorizationRequest($request) instanceof AuthorizationRequest);
} }
/**
* @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(),
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);
}
/**
* @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);
}
/** /**
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException * @expectedException \League\OAuth2\Server\Exception\OAuthServerException
* @expectedExceptionCode 3 * @expectedExceptionCode 3
@ -411,9 +522,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(),
new \DateInterval('PT10M') 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'));
$this->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse); $this->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse);
} }
@ -438,9 +547,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(),
new \DateInterval('PT10M') 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); $grant->completeAuthorizationRequest($authRequest);
} }
@ -475,8 +582,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setScopeRepository($scopeRepositoryMock); $grant->setScopeRepository($scopeRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock); $grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest( $request = new ServerRequest(
[], [],
@ -544,8 +650,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setScopeRepository($scopeRepositoryMock); $grant->setScopeRepository($scopeRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock); $grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest( $request = new ServerRequest(
[], [],
@ -616,8 +721,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setScopeRepository($scopeRepositoryMock); $grant->setScopeRepository($scopeRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock); $grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest( $request = new ServerRequest(
[], [],
@ -674,7 +778,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
new \DateInterval('PT10M') new \DateInterval('PT10M')
); );
$grant->setClientRepository($clientRepositoryMock); $grant->setClientRepository($clientRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $grant->setEncryptionKey($this->cryptStub->getKey());
$request = new ServerRequest( $request = new ServerRequest(
[], [],
@ -721,7 +825,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
new \DateInterval('PT10M') new \DateInterval('PT10M')
); );
$grant->setClientRepository($clientRepositoryMock); $grant->setClientRepository($clientRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $grant->setEncryptionKey($this->cryptStub->getKey());
$request = new ServerRequest( $request = new ServerRequest(
[], [],
@ -774,8 +878,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setClientRepository($clientRepositoryMock); $grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock); $grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest( $request = new ServerRequest(
[], [],
@ -820,8 +923,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setClientRepository($clientRepositoryMock); $grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock); $grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest( $request = new ServerRequest(
[], [],
@ -884,8 +986,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setClientRepository($clientRepositoryMock); $grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock); $grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest( $request = new ServerRequest(
[], [],
@ -945,8 +1046,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setClientRepository($clientRepositoryMock); $grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock); $grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest( $request = new ServerRequest(
[], [],
@ -1006,8 +1106,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setClientRepository($clientRepositoryMock); $grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock); $grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest( $request = new ServerRequest(
[], [],
@ -1065,8 +1164,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock); $grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock); $grant->setScopeRepository($scopeRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest( $request = new ServerRequest(
[], [],
@ -1138,8 +1236,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock); $grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock); $grant->setScopeRepository($scopeRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest( $request = new ServerRequest(
[], [],
@ -1357,8 +1454,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock); $grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock); $grant->setScopeRepository($scopeRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest( $request = new ServerRequest(
[], [],
@ -1417,9 +1513,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(),
new \DateInterval('PT10M') 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'));
$this->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse); $this->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse);
} }
@ -1445,9 +1539,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(),
new \DateInterval('PT10M') 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'));
$this->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse); $this->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse);
} }
@ -1474,9 +1566,6 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
new \DateInterval('PT10M') new \DateInterval('PT10M')
); );
$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); $this->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse);
} }
@ -1511,8 +1600,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setScopeRepository($scopeRepositoryMock); $grant->setScopeRepository($scopeRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock); $grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest( $request = new ServerRequest(
[], [],
@ -1583,8 +1671,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setScopeRepository($scopeRepositoryMock); $grant->setScopeRepository($scopeRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock); $grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest( $request = new ServerRequest(
[], [],
@ -1655,8 +1742,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setScopeRepository($scopeRepositoryMock); $grant->setScopeRepository($scopeRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock); $grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$request = new ServerRequest( $request = new ServerRequest(
[], [],

View File

@ -283,7 +283,6 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase
$grant = new ImplicitGrant(new \DateInterval('PT10M')); $grant = new ImplicitGrant(new \DateInterval('PT10M'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock);
$this->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse); $this->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse);
@ -307,7 +306,6 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase
$grant = new ImplicitGrant(new \DateInterval('PT10M')); $grant = new ImplicitGrant(new \DateInterval('PT10M'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->completeAuthorizationRequest($authRequest); $grant->completeAuthorizationRequest($authRequest);
@ -329,7 +327,6 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase
$grant = new ImplicitGrant(new \DateInterval('PT10M')); $grant = new ImplicitGrant(new \DateInterval('PT10M'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock);
$this->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse); $this->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse);
@ -354,7 +351,6 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase
$grant = new ImplicitGrant(new \DateInterval('PT10M')); $grant = new ImplicitGrant(new \DateInterval('PT10M'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->completeAuthorizationRequest($authRequest); $grant->completeAuthorizationRequest($authRequest);
@ -379,7 +375,6 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase
$grant = new ImplicitGrant(new \DateInterval('PT10M')); $grant = new ImplicitGrant(new \DateInterval('PT10M'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->completeAuthorizationRequest($authRequest); $grant->completeAuthorizationRequest($authRequest);

View File

@ -21,7 +21,7 @@ use Zend\Diactoros\ServerRequest;
class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
{ {
/** /**
* CryptTrait stub * @var CryptTraitStub
*/ */
protected $cryptStub; protected $cryptStub;
@ -65,7 +65,7 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
$grant->setClientRepository($clientRepositoryMock); $grant->setClientRepository($clientRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock); $grant->setScopeRepository($scopeRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$oldRefreshToken = $this->cryptStub->doEncrypt( $oldRefreshToken = $this->cryptStub->doEncrypt(
@ -121,7 +121,7 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
$grant->setClientRepository($clientRepositoryMock); $grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock); $grant->setScopeRepository($scopeRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$oldRefreshToken = $this->cryptStub->doEncrypt( $oldRefreshToken = $this->cryptStub->doEncrypt(
@ -180,7 +180,7 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
$grant->setClientRepository($clientRepositoryMock); $grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock); $grant->setScopeRepository($scopeRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$oldRefreshToken = $this->cryptStub->doEncrypt( $oldRefreshToken = $this->cryptStub->doEncrypt(
@ -227,7 +227,7 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
$grant = new RefreshTokenGrant($refreshTokenRepositoryMock); $grant = new RefreshTokenGrant($refreshTokenRepositoryMock);
$grant->setClientRepository($clientRepositoryMock); $grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$serverRequest = new ServerRequest(); $serverRequest = new ServerRequest();
@ -259,7 +259,7 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
$grant = new RefreshTokenGrant($refreshTokenRepositoryMock); $grant = new RefreshTokenGrant($refreshTokenRepositoryMock);
$grant->setClientRepository($clientRepositoryMock); $grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$oldRefreshToken = 'foobar'; $oldRefreshToken = 'foobar';
@ -291,14 +291,13 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf(); $accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
$refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); $refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
$refreshTokenRepositoryMock->method('persistNewRefreshToken')->willReturnSelf(); $refreshTokenRepositoryMock->method('persistNewRefreshToken')->willReturnSelf();
$grant = new RefreshTokenGrant($refreshTokenRepositoryMock); $grant = new RefreshTokenGrant($refreshTokenRepositoryMock);
$grant->setClientRepository($clientRepositoryMock); $grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$oldRefreshToken = $this->cryptStub->doEncrypt( $oldRefreshToken = $this->cryptStub->doEncrypt(
@ -344,7 +343,7 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
$grant = new RefreshTokenGrant($refreshTokenRepositoryMock); $grant = new RefreshTokenGrant($refreshTokenRepositoryMock);
$grant->setClientRepository($clientRepositoryMock); $grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$oldRefreshToken = $this->cryptStub->doEncrypt( $oldRefreshToken = $this->cryptStub->doEncrypt(
@ -391,7 +390,7 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
$grant = new RefreshTokenGrant($refreshTokenRepositoryMock); $grant = new RefreshTokenGrant($refreshTokenRepositoryMock);
$grant->setClientRepository($clientRepositoryMock); $grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $grant->setEncryptionKey($this->cryptStub->getKey());
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$oldRefreshToken = $this->cryptStub->doEncrypt( $oldRefreshToken = $this->cryptStub->doEncrypt(

View File

@ -33,7 +33,7 @@ class AuthorizationServerMiddlewareTest extends \PHPUnit_Framework_TestCase
$accessRepositoryMock, $accessRepositoryMock,
$scopeRepositoryMock, $scopeRepositoryMock,
'file://' . __DIR__ . '/../Stubs/private.key', 'file://' . __DIR__ . '/../Stubs/private.key',
'file://' . __DIR__ . '/../Stubs/public.key', base64_encode(random_bytes(36)),
new StubResponseType() new StubResponseType()
); );
@ -66,7 +66,7 @@ class AuthorizationServerMiddlewareTest extends \PHPUnit_Framework_TestCase
$this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(), $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(),
$this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(), $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(),
'file://' . __DIR__ . '/../Stubs/private.key', 'file://' . __DIR__ . '/../Stubs/private.key',
'file://' . __DIR__ . '/../Stubs/public.key', base64_encode(random_bytes(36)),
new StubResponseType() new StubResponseType()
); );
@ -97,7 +97,8 @@ class AuthorizationServerMiddlewareTest extends \PHPUnit_Framework_TestCase
$response = $exception->generateHttpResponse(new Response()); $response = $exception->generateHttpResponse(new Response());
$this->assertEquals(302, $response->getStatusCode()); $this->assertEquals(302, $response->getStatusCode());
$this->assertEquals('http://foo/bar?error=invalid_scope&message=The+requested+scope+is+invalid%2C+unknown%2C+or+malformed&hint=Check+the+%60test%60+scope', $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() public function testOAuthErrorResponseRedirectUriFragment()
@ -106,6 +107,7 @@ class AuthorizationServerMiddlewareTest extends \PHPUnit_Framework_TestCase
$response = $exception->generateHttpResponse(new Response(), true); $response = $exception->generateHttpResponse(new Response(), true);
$this->assertEquals(302, $response->getStatusCode()); $this->assertEquals(302, $response->getStatusCode());
$this->assertEquals('http://foo/bar#error=invalid_scope&message=The+requested+scope+is+invalid%2C+unknown%2C+or+malformed&hint=Check+the+%60test%60+scope', $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

@ -23,7 +23,7 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase
$responseType = new BearerTokenResponse($accessTokenRepositoryMock); $responseType = new BearerTokenResponse($accessTokenRepositoryMock);
$responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$responseType->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $responseType->setEncryptionKey(base64_encode(random_bytes(36)));
$client = new ClientEntity(); $client = new ClientEntity();
$client->setIdentifier('clientName'); $client->setIdentifier('clientName');
@ -67,7 +67,7 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase
$responseType = new BearerTokenResponseWithParams($accessTokenRepositoryMock); $responseType = new BearerTokenResponseWithParams($accessTokenRepositoryMock);
$responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$responseType->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $responseType->setEncryptionKey(base64_encode(random_bytes(36)));
$client = new ClientEntity(); $client = new ClientEntity();
$client->setIdentifier('clientName'); $client->setIdentifier('clientName');
@ -115,7 +115,7 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase
$responseType = new BearerTokenResponse($accessTokenRepositoryMock); $responseType = new BearerTokenResponse($accessTokenRepositoryMock);
$responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$responseType->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $responseType->setEncryptionKey(base64_encode(random_bytes(36)));
$client = new ClientEntity(); $client = new ClientEntity();
$client->setIdentifier('clientName'); $client->setIdentifier('clientName');
@ -141,7 +141,6 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase
$accessTokenRepositoryMock->method('isAccessTokenRevoked')->willReturn(false); $accessTokenRepositoryMock->method('isAccessTokenRevoked')->willReturn(false);
$authorizationValidator = new BearerTokenValidator($accessTokenRepositoryMock); $authorizationValidator = new BearerTokenValidator($accessTokenRepositoryMock);
$authorizationValidator->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$authorizationValidator->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $authorizationValidator->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$request = new ServerRequest(); $request = new ServerRequest();
@ -162,7 +161,7 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase
$responseType = new BearerTokenResponse($accessTokenRepositoryMock); $responseType = new BearerTokenResponse($accessTokenRepositoryMock);
$responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$responseType->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $responseType->setEncryptionKey(base64_encode(random_bytes(36)));
$client = new ClientEntity(); $client = new ClientEntity();
$client->setIdentifier('clientName'); $client->setIdentifier('clientName');
@ -185,7 +184,6 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase
$json = json_decode((string) $response->getBody()); $json = json_decode((string) $response->getBody());
$authorizationValidator = new BearerTokenValidator($accessTokenRepositoryMock); $authorizationValidator = new BearerTokenValidator($accessTokenRepositoryMock);
$authorizationValidator->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$authorizationValidator->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $authorizationValidator->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$request = new ServerRequest(); $request = new ServerRequest();
@ -205,7 +203,7 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase
{ {
$responseType = new BearerTokenResponse(); $responseType = new BearerTokenResponse();
$responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$responseType->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $responseType->setEncryptionKey(base64_encode(random_bytes(36)));
$client = new ClientEntity(); $client = new ClientEntity();
$client->setIdentifier('clientName'); $client->setIdentifier('clientName');
@ -231,7 +229,6 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase
$accessTokenRepositoryMock->method('isAccessTokenRevoked')->willReturn(true); $accessTokenRepositoryMock->method('isAccessTokenRevoked')->willReturn(true);
$authorizationValidator = new BearerTokenValidator($accessTokenRepositoryMock); $authorizationValidator = new BearerTokenValidator($accessTokenRepositoryMock);
$authorizationValidator->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$authorizationValidator->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $authorizationValidator->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$request = new ServerRequest(); $request = new ServerRequest();
@ -253,12 +250,11 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase
$responseType = new BearerTokenResponse($accessTokenRepositoryMock); $responseType = new BearerTokenResponse($accessTokenRepositoryMock);
$responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$responseType->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $responseType->setEncryptionKey(base64_encode(random_bytes(36)));
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
$authorizationValidator = new BearerTokenValidator($accessTokenRepositoryMock); $authorizationValidator = new BearerTokenValidator($accessTokenRepositoryMock);
$authorizationValidator->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$authorizationValidator->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $authorizationValidator->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$request = new ServerRequest(); $request = new ServerRequest();
@ -280,12 +276,11 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase
$responseType = new BearerTokenResponse($accessTokenRepositoryMock); $responseType = new BearerTokenResponse($accessTokenRepositoryMock);
$responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$responseType->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $responseType->setEncryptionKey(base64_encode(random_bytes(36)));
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
$authorizationValidator = new BearerTokenValidator($accessTokenRepositoryMock); $authorizationValidator = new BearerTokenValidator($accessTokenRepositoryMock);
$authorizationValidator->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$authorizationValidator->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); $authorizationValidator->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$request = new ServerRequest(); $request = new ServerRequest();

View File

@ -11,8 +11,12 @@ class CryptTraitStub
public function __construct() public function __construct()
{ {
$this->setPrivateKey(new CryptKey('file://' . __DIR__ . '/private.key')); $this->setEncryptionKey(base64_encode(random_bytes(36)));
$this->setPublicKey(new CryptKey('file://' . __DIR__ . '/public.key')); }
public function getKey()
{
return $this->encryptionKey;
} }
public function doEncrypt($unencryptedData) public function doEncrypt($unencryptedData)