Compare commits

..

57 Commits

Author SHA1 Message Date
Alex Bilbie
a1b8d87b47 Updated changelog 2017-07-19 07:58:56 +01:00
Alex Bilbie
80fc8e654b Trigger E_USER_NOTICE instead of throwing an exception if key cannot be chmod to 600 2017-07-19 07:57:47 +01:00
Alex Bilbie
317f46b7ae Merge pull request #754 from Lctrs/fix/missing-sprintf
Fix missing sprintf() calls
2017-07-07 16:50:08 +01:00
Jérôme Parmentier
88bf8b2367 Fix missing sprintf 2017-07-03 20:28:28 +02:00
Alex Bilbie
315d079033 Added link to security release information page 2017-07-02 18:44:55 +01:00
Alex Bilbie
2824f7d27e Fixed examples 2017-07-01 18:46:48 +01:00
Alex Bilbie
0a6a4deca6 5.1.4 not 5.1.14 2017-07-01 18:38:35 +01:00
Alex Bilbie
00c645545a Updated changelog 2017-07-01 18:33:17 +01:00
Alex Bilbie
417a64ad43 Added security notice 2017-07-01 18:33:03 +01:00
Alex Bilbie
f5c3ba0b24 Removed dead code 2017-07-01 18:22:51 +01:00
Alex Bilbie
e1ef133067 Dropped PHP 5.5 compatability 2017-07-01 18:22:44 +01:00
Alex Bilbie
523434902c Removed dead code 2017-07-01 18:15:41 +01:00
Alex Bilbie
aac467e616 Fixed broken tests 2017-07-01 18:11:19 +01:00
Alex Bilbie
76c2b6f88c AuthorizationServer no longer needs to know about the public key 2017-07-01 18:11:10 +01:00
Alex Bilbie
72349ef22f Encryption key is now always required so remove redundent code 2017-07-01 18:10:53 +01:00
Alex Bilbie
850793ab88 Added missing methods 2017-07-01 18:08:49 +01:00
Alex Bilbie
0f73bf0054 Encryption key just uses Defuse\Crypto now, no key based crypto 2017-07-01 18:07:51 +01:00
Alex Bilbie
7953f27b38 Stop testing HHVM 2017-07-01 18:07:09 +01:00
Alex Bilbie
cc2c3a7044 Removed unnecessary stuff from composer.json 2017-07-01 18:07:01 +01:00
Alex Bilbie
06424fdbe2 Use Trusty for TravisCI 2017-07-01 17:24:11 +01:00
Alex Bilbie
55f93f9400 Merge pull request #752 from thephpleague/analysis-qBDGNm
Apply fixes from StyleCI
2017-07-01 17:20:19 +01:00
Alex Bilbie
aee1779432 Apply fixes from StyleCI 2017-07-01 16:19:23 +00:00
Alex Bilbie
09c167ac43 Updated changelog and readme 2017-07-01 17:17:55 +01:00
Alex Bilbie
765a01021b Updated error message 2017-07-01 16:45:29 +01:00
Alex Bilbie
0706d66c76 Don’t pad and shuffle the payload if an encryption key has been set 2017-07-01 16:45:29 +01:00
Alex Bilbie
e123fe82d0 Ignore error_log messages in code coverage 2017-07-01 16:45:29 +01:00
Alex Bilbie
107cfc3678 Updated examples 2017-07-01 16:45:29 +01:00
Alex Bilbie
1954120c3d Use catch all exception 2017-07-01 16:45:29 +01:00
Alex Bilbie
dd5eee150d Ensure response type also has access to the encryption key 2017-07-01 16:45:29 +01:00
Alex Bilbie
76c1349181 Updated random_compat version 2017-07-01 16:45:29 +01:00
Alex Bilbie
1af4012df4 New property on AuthorizationServer to receive an encryption key which is used for future encryption/decryption instead of keybased encryption/decryption 2017-07-01 16:45:29 +01:00
Alex Bilbie
4a717104fa Shuffle the contents of the authorization code payload 2017-07-01 16:45:29 +01:00
Alex Bilbie
63530443fe Better error checking when saving a temporary key to ensure file was written successfully and the server is the exclusive mode 2017-07-01 16:44:57 +01:00
Alex Bilbie
2f8de3d230 Ensure the server is the exclusive owner of the key 2017-07-01 16:44:51 +01:00
Alex Bilbie
57d199b889 Stricter validation of code challenge value to match RFC 7636 requirements 2017-07-01 16:44:43 +01:00
Alex Bilbie
6bdd108145 Escape scope parameter to reduce pontential XSS vector 2017-07-01 16:43:31 +01:00
Alex Bilbie
bf7084a147 Merge pull request #709 from toby-griffiths/fix-refresh-token-ttl
Corrected DateInterval from 1 min to 1 month
2017-03-02 14:06:27 +00:00
Toby Griffiths
13c608b849 Corrected DateInterval from 1 min to 1 month 2017-03-01 13:08:42 +00:00
Alex Bilbie
ded7c1ed47 Mentioned PHP 7.1 support 2017-02-02 17:29:06 +00:00
Alex Bilbie
0da70c916a Merge pull request #690 from Jalle19/patch-1
Fix typo in the first README sentence
2016-12-23 07:42:23 +00:00
Sam Stenvall
90cb1bf012 Fix typo in the first README sentence 2016-12-23 00:30:54 +02:00
Alex Bilbie
b32204bd91 Merge pull request #682 from wilsonge/patch-1
Fix middleware example fatal error
2016-11-08 13:18:13 +00:00
George Wilson
518c1fcec5 Fix middleware example fatal error 2016-11-08 12:27:49 +00:00
Alex Bilbie
6946592553 Merge pull request #671 from duncan3dc/patch-1
[Travis] Test on PHP 7.1
2016-10-16 16:58:15 +01:00
Craig Duncan
25580b98b7 [Travis] Test on PHP 7.1 2016-10-16 16:48:44 +01:00
Alex Bilbie
f78dc2eca0 Updated README 2016-10-12 15:08:15 +01:00
Alex Bilbie
105b3116dc Merge pull request #669 from jeremykendall/fix/www-authenticate-header
Fix WWW-Authenticate entry in $headers array
2016-10-12 15:05:19 +01:00
jeremykendall
01677a564e Fix WWW-Authenticate entry in $headers array
In this context the header name should be the array key and the header
value the array value.
2016-10-11 22:27:24 -05:00
Alex Bilbie
4c4b0633b1 Merge pull request #668 from er0k/increase-ssl-key-length
Increase the recommended RSA key length from 1024 to 2048 bits
2016-10-11 14:27:16 +01:00
er0k
c4a75b2880 Increase the recommended RSA key length from 1024 to 2048 bits 2016-10-11 09:24:27 -04:00
Alex Bilbie
e091d48127 Changelog bump 2016-09-19 10:23:42 +01:00
Alex Bilbie
a798cfdc5d Merge pull request #656 from thephpleague/issue-650-fix
Fix for #650
2016-09-19 10:19:05 +01:00
Alex Bilbie
56e8d374fb Fix broken tests 2016-09-19 10:06:00 +01:00
Alex Bilbie
b1bfff7325 Don't pass in user because we don't know who user is 2016-09-19 10:05:55 +01:00
Alex Bilbie
32cde01ab2 Merge pull request #657 from thephpleague/analysis-86wPg4
Applied fixes from StyleCI
2016-09-13 15:19:56 +01:00
Alex Bilbie
11ccc305d0 Applied fixes from StyleCI 2016-09-13 14:17:09 +00:00
Alex Bilbie
d7df2f7e24 Fix for #650 2016-09-13 15:16:58 +01:00
42 changed files with 563 additions and 411 deletions

View File

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

View File

@@ -1,5 +1,35 @@
# Changelog
## 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,5 +1,11 @@
# 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)
[![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)
@@ -7,7 +13,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 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 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:
@@ -30,10 +36,9 @@ 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
* HHVM
* PHP 7.1
The `openssl` extension is also required.
@@ -72,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).
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.

View File

@@ -4,18 +4,17 @@
"homepage": "https://oauth2.thephpleague.com/",
"license": "MIT",
"require": {
"php": ">=5.5.9",
"php": ">=5.6.0",
"ext-openssl": "*",
"league/event": "^2.1",
"lcobucci/jwt": "^3.1",
"paragonie/random_compat": "^1.1 || ^2.0",
"paragonie/random_compat": "^2.0",
"psr/http-message": "^1.0",
"league/openid-connect-claims": "^1.1.0"
"defuse/php-encryption": "^2.1"
},
"require-dev": {
"phpunit/phpunit": "^4.8 || ^5.0",
"zendframework/zend-diactoros": "^1.0",
"indigophp/hash-compat": "^1.1"
"zendframework/zend-diactoros": "^1.0"
},
"repositories": [
{
@@ -60,13 +59,5 @@
"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 1024`
0. Create a private key `openssl genrsa -out private.key 2048`
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,8 +5,9 @@
"require-dev": {
"league/event": "^2.1",
"lcobucci/jwt": "^3.1",
"paragonie/random_compat": "^1.1",
"psr/http-message": "^1.0"
"paragonie/random_compat": "^2.0",
"psr/http-message": "^1.0",
"defuse/php-encryption": "^2.1"
},
"autoload": {
"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",
"This file is @generated automatically"
],
"hash": "48bcb7a3514d7c7f271c554ba1440124",
"content-hash": "e41be75973527cb9d63f27ad14ac8624",
"content-hash": "9813ed7c3b6dcf107f44df9392935b8f",
"packages": [
{
"name": "container-interop/container-interop",
"version": "1.1.0",
"version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/container-interop/container-interop.git",
"reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e"
"reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/container-interop/container-interop/zipball/fc08354828f8fd3245f77a66b9e23a6bca48297e",
"reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e",
"url": "https://api.github.com/repos/container-interop/container-interop/zipball/79cbf1341c22ec75643d841642dd5d6acd83bdb8",
"reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8",
"shasum": ""
},
"require": {
"psr/container": "^1.0"
},
"type": "library",
"autoload": {
"psr-4": {
@@ -32,7 +34,8 @@
"MIT"
],
"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",
@@ -75,7 +78,7 @@
"router",
"routing"
],
"time": "2015-06-18 19:15:47"
"time": "2015-06-18T19:15:47+00:00"
},
{
"name": "pimple/pimple",
@@ -121,20 +124,69 @@
"container",
"dependency injection"
],
"time": "2015-09-11 15:10:35"
"time": "2015-09-11T15:10:35+00:00"
},
{
"name": "psr/http-message",
"version": "1.0",
"name": "psr/container",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298"
"url": "https://github.com/php-fig/container.git",
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/85d63699f0dbedb190bbd4b0d2b9dc707ea4c298",
"reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298",
"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"
},
{
"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": ""
},
"require": {
@@ -162,6 +214,7 @@
}
],
"description": "Common interface for HTTP messages",
"homepage": "https://github.com/php-fig/http-message",
"keywords": [
"http",
"http-message",
@@ -170,7 +223,7 @@
"request",
"response"
],
"time": "2015-05-04 20:22:00"
"time": "2016-08-06T14:39:51+00:00"
},
{
"name": "slim/slim",
@@ -236,22 +289,85 @@
"micro",
"router"
],
"time": "2015-12-07 14:11:09"
"time": "2015-12-07T14:11:09+00:00"
}
],
"packages-dev": [
{
"name": "lcobucci/jwt",
"version": "3.1.1",
"name": "defuse/php-encryption",
"version": "v2.1.0",
"source": {
"type": "git",
"url": "https://github.com/lcobucci/jwt.git",
"reference": "afea8e682e911a21574fd8519321b32522fa25b5"
"url": "https://github.com/defuse/php-encryption.git",
"reference": "5176f5abb38d3ea8a6e3ac6cd3bbb54d8185a689"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/lcobucci/jwt/zipball/afea8e682e911a21574fd8519321b32522fa25b5",
"reference": "afea8e682e911a21574fd8519321b32522fa25b5",
"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",
"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": ""
},
"require": {
@@ -259,7 +375,7 @@
"php": ">=5.5"
},
"require-dev": {
"mdanter/ecc": "~0.3",
"mdanter/ecc": "~0.3.1",
"mikey179/vfsstream": "~1.5",
"phpmd/phpmd": "~2.2",
"phpunit/php-invoker": "~1.1",
@@ -296,7 +412,7 @@
"JWS",
"jwt"
],
"time": "2016-03-24 22:46:13"
"time": "2016-10-31T20:09:32+00:00"
},
{
"name": "league/event",
@@ -346,20 +462,20 @@
"event",
"listener"
],
"time": "2015-05-21 12:24:47"
"time": "2015-05-21T12:24:47+00:00"
},
{
"name": "paragonie/random_compat",
"version": "v1.4.1",
"version": "v2.0.10",
"source": {
"type": "git",
"url": "https://github.com/paragonie/random_compat.git",
"reference": "c7e26a21ba357863de030f0b9e701c7d04593774"
"reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/c7e26a21ba357863de030f0b9e701c7d04593774",
"reference": "c7e26a21ba357863de030f0b9e701c7d04593774",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/634bae8e911eefa89c1abfbf1b66da679ac8f54d",
"reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d",
"shasum": ""
},
"require": {
@@ -394,7 +510,7 @@
"pseudorandom",
"random"
],
"time": "2016-03-18 20:34:03"
"time": "2017-03-13T16:27:32+00:00"
}
],
"aliases": [],

View File

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

View File

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

View File

@@ -30,9 +30,8 @@ $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(
@@ -40,7 +39,7 @@ $app = new App([
$accessTokenRepository,
$scopeRepository,
$privateKey,
$publicKey
'lxZFUEsBCJ2Yb14IF2ygAHI5N4+ZAUXXaSeeJm6+twsUmIen'
);
// Enable the client credentials grant on the server

View File

@@ -32,7 +32,6 @@ $app = new App([
$accessTokenRepository = new AccessTokenRepository();
$privateKeyPath = 'file://' . __DIR__ . '/../private.key';
$publicKeyPath = 'file://' . __DIR__ . '/../public.key';
// Setup the authorization server
$server = new AuthorizationServer(
@@ -40,8 +39,9 @@ $app = new App([
$accessTokenRepository,
$scopeRepository,
$privateKeyPath,
$publicKeyPath
'lxZFUEsBCJ2Yb14IF2ygAHI5N4+ZAUXXaSeeJm6+twsUmIen'
);
$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,6 +12,7 @@ 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;
@@ -37,7 +38,6 @@ $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,
$publicKeyPath
'lxZFUEsBCJ2Yb14IF2ygAHI5N4+ZAUXXaSeeJm6+twsUmIen'
);
// Enable the authentication code grant on the server with a token TTL of 1 hour
@@ -61,7 +61,17 @@ $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('PT1M')
new \DateInterval('P1M')
);
return $server;
},
ResourceServer::class => function () {
$publicKeyPath = 'file://' . __DIR__ . '/../public.key';
$server = new ResourceServer(
new AccessTokenRepository(),
$publicKeyPath
);
return $server;
@@ -94,6 +104,6 @@ $app->group('/api', function () {
return $response->withBody($body);
});
})->add(new ResourceServerMiddleware($app->getContainer()->get(AuthorizationServer::class)));
})->add(new ResourceServerMiddleware($app->getContainer()->get(ResourceServer::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
'file://'.__DIR__.'/../public.key' // path to public key
'file://' . __DIR__ . '/../private.key', // path to private key
'lxZFUEsBCJ2Yb14IF2ygAHI5N4+ZAUXXaSeeJm6+twsUmIen' // encryption key
);
$grant = new PasswordGrant(
@@ -54,19 +54,17 @@ $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);
return $response->withStatus(500)->withBody($body);
}
}
);

View File

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

View File

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

View File

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

View File

@@ -12,6 +12,7 @@ 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;
@@ -26,6 +27,11 @@ class BearerTokenValidator implements AuthorizationValidatorInterface
*/
private $accessTokenRepository;
/**
* @var \League\OAuth2\Server\CryptKey
*/
protected $publicKey;
/**
* @param AccessTokenRepositoryInterface $accessTokenRepository
*/
@@ -34,6 +40,16 @@ class BearerTokenValidator implements AuthorizationValidatorInterface
$this->accessTokenRepository = $accessTokenRepository;
}
/**
* Set the private key
*
* @param \League\OAuth2\Server\CryptKey $key
*/
public function setPublicKey(CryptKey $key)
{
$this->publicKey = $key;
}
/**
* {@inheritdoc}
*/
@@ -75,7 +91,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

@@ -44,6 +44,24 @@ class CryptKey
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
trigger_error(
sprintf(
'Key file "%s" permissions are not correct, should be 600 instead of %s, unable to automatically resolve the issue',
$keyPath,
$keyPathPerms
),
E_USER_NOTICE
);
// @codeCoverageIgnoreEnd
}
}
$this->keyPath = $keyPath;
$this->passPhrase = $passPhrase;
}
@@ -57,15 +75,26 @@ class CryptKey
*/
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)) {
// @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
}
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;
}

View File

@@ -1,47 +1,22 @@
<?php
/**
* Public/private key encryption.
*
* @author Alex Bilbie <hello@alexbilbie.com>
* @copyright Copyright (c) Alex Bilbie
* @license http://mit-license.org/
*
* @link https://github.com/thephpleague/oauth2-server
*/
namespace League\OAuth2\Server;
use Defuse\Crypto\Crypto;
trait CryptTrait
{
/**
* @var CryptKey
* @var string
*/
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;
}
protected $encryptionKey;
/**
* Encrypt data with a private key.
@@ -49,35 +24,15 @@ trait CryptTrait
* @param string $unencryptedData
*
* @throws \LogicException
*
* @return string
*/
protected function encrypt($unencryptedData)
{
$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())
);
try {
return Crypto::encryptWithPassword($unencryptedData, $this->encryptionKey);
} catch (\Exception $e) {
throw new \LogicException($e->getMessage());
}
$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
*
* @throws \LogicException
*
* @return string
*/
protected function decrypt($encryptedData)
{
$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())
);
try {
return Crypto::decryptWithPassword($encryptedData, $this->encryptionKey);
} catch (\Exception $e) {
throw new \LogicException($e->getMessage());
}
}
$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;
/**
* Set the encryption key
*
* @param string $key
*/
public function setEncryptionKey($key = null)
{
$this->encryptionKey = $key;
}
}

View File

@@ -105,7 +105,10 @@ class OAuthServerException extends \Exception
public static function invalidScope($scope, $redirectUri = null)
{
$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);
}
@@ -267,7 +270,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,7 +9,6 @@
namespace League\OAuth2\Server\Exception;
class UniqueTokenIdentifierConstraintViolationException extends OAuthServerException
{
public static function create()

View File

@@ -11,6 +11,7 @@
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;
@@ -75,6 +76,11 @@ abstract class AbstractGrant implements GrantTypeInterface
*/
protected $refreshTokenTTL;
/**
* @var \League\OAuth2\Server\CryptKey
*/
protected $privateKey;
/**
* @param ClientRepositoryInterface $clientRepository
*/
@@ -131,6 +137,16 @@ 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;
}
/**
* Validate the client.
*
@@ -345,6 +361,7 @@ abstract class AbstractGrant implements GrantTypeInterface
$accessToken->setIdentifier($this->generateUniqueIdentifier());
try {
$this->accessTokenRepository->persistNewAccessToken($accessToken);
return $accessToken;
} catch (UniqueTokenIdentifierConstraintViolationException $e) {
if ($maxGenerationAttempts === 0) {
@@ -391,6 +408,7 @@ abstract class AbstractGrant implements GrantTypeInterface
$authCode->setIdentifier($this->generateUniqueIdentifier());
try {
$this->authCodeRepository->persistNewAuthCode($authCode);
return $authCode;
} catch (UniqueTokenIdentifierConstraintViolationException $e) {
if ($maxGenerationAttempts === 0) {
@@ -420,6 +438,7 @@ abstract class AbstractGrant implements GrantTypeInterface
$refreshToken->setIdentifier($this->generateUniqueIdentifier());
try {
$this->refreshTokenRepository->persistNewRefreshToken($refreshToken);
return $refreshToken;
} catch (UniqueTokenIdentifierConstraintViolationException $e) {
if ($maxGenerationAttempts === 0) {

View File

@@ -264,6 +264,13 @@ 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(
@@ -304,6 +311,17 @@ 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(
@@ -311,16 +329,7 @@ class AuthCodeGrant extends AbstractAuthorizeGrant
[
'code' => $this->encrypt(
json_encode(
[
'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(),
]
$payload
)
),
'state' => $authorizationRequest->getState(),

View File

@@ -127,9 +127,9 @@ interface GrantTypeInterface extends EmitterAwareInterface
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

@@ -151,6 +151,13 @@ class ImplicitGrant extends AbstractAuthorizeGrant
: $client->getRedirectUri()
);
// Finalize the requested scopes
$scopes = $this->scopeRepository->finalizeScopes(
$scopes,
$this->getIdentifier(),
$client
);
$stateParameter = $this->getQueryStringParameter('state', $request);
$authorizationRequest = new AuthorizationRequest();

View File

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

View File

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

View File

@@ -11,6 +11,7 @@
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;
@@ -29,6 +30,11 @@ abstract class AbstractResponseType implements ResponseTypeInterface
*/
protected $refreshToken;
/**
* @var CryptKey
*/
protected $privateKey;
/**
* {@inheritdoc}
*/
@@ -44,4 +50,15 @@ 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,6 +68,7 @@ class BearerTokenResponse extends AbstractResponseType
* this class rather than the default.
*
* @param AccessTokenEntityInterface $accessToken
*
* @return array
*/
protected function getExtraParams(AccessTokenEntityInterface $accessToken)

View File

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

View File

@@ -1,46 +0,0 @@
<?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

@@ -1,47 +0,0 @@
<?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

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

View File

@@ -33,7 +33,7 @@ class AuthorizationServerTest extends \PHPUnit_Framework_TestCase
$this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(),
$this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(),
'file://' . __DIR__ . '/Stubs/private.key',
'file://' . __DIR__ . '/Stubs/public.key',
base64_encode(random_bytes(36)),
new StubResponseType()
);
@@ -63,7 +63,7 @@ class AuthorizationServerTest extends \PHPUnit_Framework_TestCase
$accessTokenRepositoryMock,
$scopeRepositoryMock,
'file://' . __DIR__ . '/Stubs/private.key',
'file://' . __DIR__ . '/Stubs/public.key',
base64_encode(random_bytes(36)),
new StubResponseType()
);
@@ -116,9 +116,6 @@ class AuthorizationServerTest extends \PHPUnit_Framework_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();

View File

@@ -8,7 +8,7 @@ use LeagueTests\Stubs\CryptTraitStub;
class CryptTraitTest extends \PHPUnit_Framework_TestCase
{
/**
* CryptTrait stub
* @var \LeagueTests\Stubs\CryptTraitStub
*/
protected $cryptStub;
@@ -26,30 +26,4 @@ class CryptTraitTest extends \PHPUnit_Framework_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

@@ -27,8 +27,6 @@ class AbstractGrantTest extends \PHPUnit_Framework_TestCase
{
/** @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());
}

View File

@@ -137,7 +137,6 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($grant->validateAuthorizationRequest($request) instanceof AuthorizationRequest);
}
public function testValidateAuthorizationRequestCodeChallenge()
{
$client = new ClientEntity();
@@ -165,13 +164,124 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
'response_type' => 'code',
'client_id' => 'foo',
'redirect_uri' => 'http://foo/bar',
'code_challenge' => 'FOOBAR',
'code_challenge' => str_repeat('A', 43),
]
);
$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
* @expectedExceptionCode 3
@@ -400,9 +510,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(),
new \DateInterval('PT10M')
);
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setEncryptionKey($this->cryptStub->getKey());
$this->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse);
}
@@ -427,9 +535,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(),
new \DateInterval('PT10M')
);
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setEncryptionKey($this->cryptStub->getKey());
$grant->completeAuthorizationRequest($authRequest);
}
@@ -464,8 +570,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setEncryptionKey($this->cryptStub->getKey());
$request = new ServerRequest(
[],
@@ -533,8 +638,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setEncryptionKey($this->cryptStub->getKey());
$request = new ServerRequest(
[],
@@ -605,8 +709,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setEncryptionKey($this->cryptStub->getKey());
$request = new ServerRequest(
[],
@@ -663,7 +766,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
new \DateInterval('PT10M')
);
$grant->setClientRepository($clientRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setEncryptionKey($this->cryptStub->getKey());
$request = new ServerRequest(
[],
@@ -710,7 +813,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
new \DateInterval('PT10M')
);
$grant->setClientRepository($clientRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setEncryptionKey($this->cryptStub->getKey());
$request = new ServerRequest(
[],
@@ -763,8 +866,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setEncryptionKey($this->cryptStub->getKey());
$request = new ServerRequest(
[],
@@ -809,8 +911,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setEncryptionKey($this->cryptStub->getKey());
$request = new ServerRequest(
[],
@@ -873,8 +974,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setEncryptionKey($this->cryptStub->getKey());
$request = new ServerRequest(
[],
@@ -934,8 +1034,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setEncryptionKey($this->cryptStub->getKey());
$request = new ServerRequest(
[],
@@ -995,8 +1094,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setEncryptionKey($this->cryptStub->getKey());
$request = new ServerRequest(
[],
@@ -1054,8 +1152,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setEncryptionKey($this->cryptStub->getKey());
$request = new ServerRequest(
[],
@@ -1127,8 +1224,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setEncryptionKey($this->cryptStub->getKey());
$request = new ServerRequest(
[],
@@ -1200,8 +1296,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setEncryptionKey($this->cryptStub->getKey());
$request = new ServerRequest(
[],
@@ -1260,9 +1355,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(),
new \DateInterval('PT10M')
);
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setEncryptionKey($this->cryptStub->getKey());
$this->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse);
}
@@ -1288,9 +1381,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(),
new \DateInterval('PT10M')
);
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setEncryptionKey($this->cryptStub->getKey());
$this->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse);
}
@@ -1317,9 +1408,6 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
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);
}
@@ -1354,8 +1442,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setEncryptionKey($this->cryptStub->getKey());
$request = new ServerRequest(
[],
@@ -1426,8 +1513,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setEncryptionKey($this->cryptStub->getKey());
$request = new ServerRequest(
[],
@@ -1498,8 +1584,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
$grant->setEncryptionKey($this->cryptStub->getKey());
$request = new ServerRequest(
[],

View File

@@ -9,11 +9,13 @@ 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 Zend\Diactoros\ServerRequest;
@@ -86,8 +88,14 @@ class ImplicitGrantTest extends \PHPUnit_Framework_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);
$request = new ServerRequest(
[],
@@ -114,8 +122,14 @@ class ImplicitGrantTest extends \PHPUnit_Framework_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);
$request = new ServerRequest(
[],
@@ -269,7 +283,6 @@ class ImplicitGrantTest extends \PHPUnit_Framework_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->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse);
@@ -293,7 +306,6 @@ class ImplicitGrantTest extends \PHPUnit_Framework_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);
@@ -315,7 +327,6 @@ class ImplicitGrantTest extends \PHPUnit_Framework_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->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse);
@@ -340,7 +351,6 @@ class ImplicitGrantTest extends \PHPUnit_Framework_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);
@@ -365,7 +375,6 @@ class ImplicitGrantTest extends \PHPUnit_Framework_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);

View File

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

View File

@@ -33,7 +33,7 @@ class AuthorizationServerMiddlewareTest extends \PHPUnit_Framework_TestCase
$accessRepositoryMock,
$scopeRepositoryMock,
'file://' . __DIR__ . '/../Stubs/private.key',
'file://' . __DIR__ . '/../Stubs/public.key',
base64_encode(random_bytes(36)),
new StubResponseType()
);
@@ -66,7 +66,7 @@ class AuthorizationServerMiddlewareTest extends \PHPUnit_Framework_TestCase
$this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(),
$this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(),
'file://' . __DIR__ . '/../Stubs/private.key',
'file://' . __DIR__ . '/../Stubs/public.key',
base64_encode(random_bytes(36)),
new StubResponseType()
);
@@ -97,7 +97,8 @@ class AuthorizationServerMiddlewareTest extends \PHPUnit_Framework_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()
@@ -106,6 +107,7 @@ class AuthorizationServerMiddlewareTest extends \PHPUnit_Framework_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

@@ -23,7 +23,7 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase
$responseType = new BearerTokenResponse($accessTokenRepositoryMock);
$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->setIdentifier('clientName');
@@ -67,7 +67,7 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase
$responseType = new BearerTokenResponseWithParams($accessTokenRepositoryMock);
$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->setIdentifier('clientName');
@@ -115,7 +115,7 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase
$responseType = new BearerTokenResponse($accessTokenRepositoryMock);
$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->setIdentifier('clientName');
@@ -141,7 +141,6 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_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 +161,7 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase
$responseType = new BearerTokenResponse($accessTokenRepositoryMock);
$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->setIdentifier('clientName');
@@ -185,7 +184,6 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_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();
@@ -205,7 +203,7 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase
{
$responseType = new BearerTokenResponse();
$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->setIdentifier('clientName');
@@ -231,7 +229,6 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_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();
@@ -253,12 +250,11 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase
$responseType = new BearerTokenResponse($accessTokenRepositoryMock);
$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();
$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();
@@ -280,12 +276,11 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase
$responseType = new BearerTokenResponse($accessTokenRepositoryMock);
$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();
$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

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