Compare commits

...

60 Commits

Author SHA1 Message Date
Andrew Millington
138524984a Merge pull request #918 from Sephster/fix-914
Fix empty issue in PHP 5.4
2018-06-23 17:27:31 +01:00
sephster
8335935854 Fix empty issue in PHP 5.4 2018-06-22 13:47:22 +01:00
Alex Bilbie
3bec591393 Changelog update 2016-09-13 14:42:53 +01:00
Alex Bilbie
084b779cc6 Merge pull request #652 from rickshawhobo/4.1.x
less restrictive on Authorization header check
2016-09-13 14:38:47 +01:00
Guy Huynh
491f3f0e95 less restrictive on Authorization header check 2016-09-08 10:20:34 -04:00
Alex Bilbie
c5db707e69 Updated changelog 2016-01-04 19:56:12 +00:00
Alex Bilbie
ed7f78179a Merge pull request #412 from derrabus/symfony-3
Allow Symfony 3.0
2015-12-20 20:38:02 +00:00
Alexander M. Turek
6e92239dd7 Allow Symfony 3.0. 2015-12-11 15:24:13 +01:00
Alex Bilbie
f5d731def9 Updated changelog 2015-11-13 17:52:27 +00:00
Alex Bilbie
03815cec6d Merge pull request #388 from m4tthumphrey/master
Added priority argument
2015-10-13 11:21:52 +01:00
Matt Humphrey
c71dc47459 Added priority argument 2015-10-13 11:16:49 +01:00
Alex Bilbie
3bcd8fc3f8 Removed runs and increased timeout 2015-09-26 11:26:17 +01:00
Alex Bilbie
db6d4e0dc6 Only send data to Scrutinizer only for PHP 5.6 2015-09-26 11:25:26 +01:00
Alex Bilbie
f19189a999 Merge pull request #345 from mpipet/master
Expose parameter passed to exceptions
2015-09-04 08:38:35 +01:00
Alex Bilbie
ec9c91cc11 Update .scrutinizer.yml 2015-09-04 08:37:12 +01:00
Alex Bilbie
c3457107ee Merge pull request #370 from michaelhogg/fix-bug-hmac-encoding
Fix bug: hash_hmac() should output raw binary data, not hexits
2015-09-04 08:36:33 +01:00
Alex Bilbie
a9f61fd3ed Merge pull request #377 from starJammer/master
AuthCodeGrant and RefreshTokenGrant don't require client_secret
2015-09-04 08:29:39 +01:00
Alex Bilbie
b78d8ca1d8 Merge pull request #364 from apollopy/master
Too idealistic. Should allow the client and server have some time difference.
2015-09-04 08:28:14 +01:00
Jerry Saravia
8f82e8ef86 Added test for setRequireClientSecret 2015-09-03 23:16:09 -04:00
Jerry Saravia
d88e01c7dd Making client secret optional during refresh and access token requsets. 2015-09-03 22:50:35 -04:00
Michael Hogg
d21374fb0b Merge remote-tracking branch 'thephpleague/master' into fix-bug-hmac-encoding 2015-09-02 09:50:46 +01:00
Alex Bilbie
31e5f4d33c Merge pull request #368 from apollopy/mac_token_only_header
Mac token only get to header
2015-09-01 14:33:58 +01:00
Alex Bilbie
a773405adf Merge pull request #369 from joaopramos/mac-refresh-tokens
Mac refresh tokens
2015-09-01 14:32:45 +01:00
Alex Bilbie
ccc845b195 Merge pull request #371 from michaelhogg/fix-bug-base64-regex
Fix bug: regex doesn't match all Base64 characters
2015-09-01 14:30:38 +01:00
Alex Bilbie
21cd917892 Merge pull request #372 from michaelhogg/fix-bug-request-uri
Fix bug: incorrect signature parameter
2015-09-01 14:29:41 +01:00
Michael Hogg
a2c418ee07 Fix bug: incorrect signature parameter 2015-08-28 16:41:12 +01:00
Michael Hogg
b220368583 Fix bug: regex doesn't match all Base64 characters 2015-08-28 14:01:22 +01:00
Michael Hogg
2d26c38d6c Update unit test: testDetermineAccessTokenInHeaderValid() 2015-08-28 13:11:20 +01:00
Michael Hogg
eeaa68400f Fix bug: hash_hmac() should output raw binary data, not hexits 2015-08-28 12:46:53 +01:00
joao
56c73d2427 ISSUE #356: added the refresh token to the mac token type response 2015-08-28 10:40:13 +00:00
joao
f632fcc997 ISSUE #356: added the refresh token to the mac token type response 2015-08-28 10:38:45 +00:00
ApolloPY
618d84ddcf Mac token only get to header 2015-08-22 01:47:59 +08:00
apollopy
ace42e89e0 change to 300 seconds 2015-08-21 20:02:42 +08:00
ApolloPY
c496df98e4 Too idealistic. Should allow the client and server have some time difference. 2015-08-21 17:17:51 +08:00
Alex Bilbie
2496653968 Merge pull request #342 from gaomd/master
Fix #328, strict check Bearer token
2015-08-21 09:00:02 +01:00
Alex Bilbie
abf66ef9c8 Merge pull request #346 from Korri/Korri-patch-removed-duplicate-routing
Removed duplicate routing setup code
2015-08-21 08:59:35 +01:00
Alex Bilbie
4b9ec488f4 Merge pull request #352 from daveblake/master
Fix typo in docblock
2015-07-13 21:55:43 +01:00
DavidBlake
726d879607 Fix typo in docblock 2015-06-18 13:27:58 +01:00
Mathieu Pipet
b256195421 Expose parameter passed to exceptions 2015-06-09 17:42:25 +02:00
Mathieu Pipet
c84ea1ea62 Expose parameter passed to exceptions 2015-06-09 17:30:13 +02:00
Hugo Vacher
16685ccde4 Removed duplicate routing setup code 2015-06-08 15:50:55 -04:00
Mengdi Gao
7934c7bb53 Fix #328, strict check Bearer token 2015-06-01 21:36:44 +08:00
Alex Bilbie
c174b6fc65 Merge pull request #341 from thephpleague/philsturgeon-patch-1
Added integration list to readme
2015-05-20 13:22:42 +01:00
Phil Sturgeon
75ced70248 Added integration list to readme
I figure it's a good idea to let people know where they can find their bridge packages to save em looking or building their own framework specific nonsense.
2015-05-17 13:33:50 -04:00
Alex Bilbie
5b7fdaeece Merge pull request #330 from jakeasmith/patch-1
Just a typo fix
2015-04-16 17:48:00 +01:00
Jake A. Smith
430a752315 Just a typo fix 2015-04-16 10:41:37 -05:00
Alex Bilbie
810544ec0a Changelog update 2015-03-22 23:32:45 +00:00
Alex Bilbie
34a6b66b8c More .travis.yml updates 2015-03-22 23:19:36 +00:00
Alex Bilbie
61738a7fe2 Added fast_finish: true to .travis.yml 2015-03-22 23:13:41 +00:00
Alex Bilbie
51184259d1 Merge pull request #323 from rdohms/interface-docs
Updated Interface Docs
2015-03-20 11:43:47 +00:00
rdohms
b21de11429 Updated Interface Docs
Made phpdocs match expectations like null when not found and using array notation for indicating array of <object>
2015-03-20 11:33:03 +01:00
Alex Bilbie
cf6e86c9d4 Merge pull request #319 from Fuxy22/patch-1
Fixed missing session scope
2015-03-13 11:03:05 +00:00
Alex Bilbie
f6fdbc7142 Added PHP 7.0 testing 2015-03-03 22:00:47 +00:00
Norbert Fuksz
7f7f45662a Fixed missing session scope
Close #297
2015-03-02 17:47:48 +00:00
Alex Bilbie
f92a68cc72 Merge branch 'master' of github.com:thephpleague/oauth2-server 2015-02-22 19:47:44 +00:00
Alex Bilbie
295d8ffa24 Updated league/event to ~2.1. Fixes #311 2015-02-22 19:47:27 +00:00
Alex Bilbie
3d08140651 Merge pull request #300 from vvllaadd/patch-2
Probable bug
2015-02-22 19:45:14 +00:00
Alex Bilbie
ec8a8393ee Merge pull request #310 from ismailbaskin/master
typo
2015-02-10 10:03:53 +00:00
Ismail BASKIN
3869b8f406 typo 2015-02-10 10:28:57 +02:00
Vlad
d43391564c Probable bug
AccessTokenStorage::delete should delete the token, not the scope associated with the token
2015-01-15 14:20:54 +01:00
30 changed files with 264 additions and 45 deletions

View File

@@ -21,8 +21,7 @@ checks:
fix_doc_comments: true
tools:
external_code_coverage:
timeout: 600
runs: 3
timeout: 1800
php_code_coverage: false
php_code_sniffer:
config:
@@ -34,4 +33,4 @@ tools:
excluded_dirs: [vendor, tests, examples]
php_cpd:
enabled: true
excluded_dirs: [vendor, tests, examples]
excluded_dirs: [vendor, tests, examples]

View File

@@ -1,10 +1,22 @@
language: php
sudo: false
cache:
directories:
- vendor
php:
- 5.4
- 5.5
- 5.6
- 7.0
- hhvm
matrix:
allow_failures:
- php: 7.0
fast_finish: true
install:
- travis_retry composer install --no-interaction --prefer-source
@@ -14,8 +26,8 @@ script:
- phpunit --coverage-text --verbose --coverage-clover=coverage.clover --coverage-html coverage
after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- php ocular.phar code-coverage:upload --format=php-clover coverage.clover
- bash -c 'if [ "$TRAVIS_PHP_VERSION" == "5.6" ]; then wget https://scrutinizer-ci.com/ocular.phar; fi;
- bash -c 'if [ "$TRAVIS_PHP_VERSION" == "5.6" ]; then php ocular.phar code-coverage:upload --format=php-clover coverage.clover; fi;
- git config --global user.email "travis@travis-ci.org"
- git config --global user.name "TravisCI"
- cp -R coverage ${HOME}/coverage

View File

@@ -1,5 +1,40 @@
# Changelog
## 4.1.6 (released 2016-09-13)
* Less restrictive on Authorization header check (Issue #652)
## 4.1.5 (released 2016-01-04)
* Enable Symfony 3.0 support (#412)
## 4.1.4 (released 2015-11-13)
* Fix for determining access token in header (Issue #328)
* Refresh tokens are now returned for MAC responses (Issue #356)
* Added integration list to readme (Issue #341)
* Expose parameter passed to exceptions (Issue #345)
* Removed duplicate routing setup code (Issue #346)
* Docs fix (Issues #347, #360, #380)
* Examples fix (Issues #348, #358)
* Fix typo in docblock (Issue #352)
* Improved timeouts for MAC tokens (Issue #364)
* `hash_hmac()` should output raw binary data, not hexits (Issue #370)
* Improved regex for matching all Base64 characters (Issue #371)
* Fix incorrect signature parameter (Issue #372)
* AuthCodeGrant and RefreshTokenGrant don't require client_secret (Issue #377)
* Added priority argument to event listener (Issue #388)
## 4.1.3 (released 2015-03-22)
* Docblock, namespace and inconsistency fixes (Issue #303)
* Docblock type fix (Issue #310)
* Example bug fix (Issue #300)
* Updated league/event to ~2.1 (Issue #311)
* Fixed missing session scope (Issue #319)
* Updated interface docs (Issue #323)
* `.travis.yml` updates
## 4.1.2 (released 2015-01-01)
* Remove side-effects in hash_equals() implementation (Issue #290)

View File

@@ -51,6 +51,11 @@ Contribute to this documentation in the [gh-pages branch](https://github.com/the
Please see [CONTRIBUTING](https://github.com/thephpleague/oauth2-server/blob/master/CONTRIBUTING.md) for details.
## Integration
- [CakePHP 3](https://github.com/uafrica/oauth-server)
- [Laravel](https://github.com/lucadegasperi/oauth2-server-laravel)
## Support
Bugs and feature request are tracked on [GitHub](https://github.com/thephpleague/oauth2-server/issues)

View File

@@ -5,8 +5,8 @@
"license": "MIT",
"require": {
"php": ">=5.4.0",
"symfony/http-foundation": "~2.4",
"league/event": "1.0.*"
"symfony/http-foundation": "~2.4|~3.0",
"league/event": "~2.1"
},
"require-dev": {
"phpunit/phpunit": "4.3.*",

View File

@@ -86,7 +86,7 @@ class AccessTokenStorage extends AbstractStorage implements AccessTokenInterface
*/
public function delete(AccessTokenEntity $token)
{
Capsule::table('oauth_access_token_scopes')
Capsule::table('oauth_access_tokens')
->where('access_token', $token->getId())
->delete();
}

View File

@@ -9,11 +9,6 @@ use RelationalExample\Storage;
include __DIR__.'/vendor/autoload.php';
// Routing setup
$request = (new Request())->createFromGlobals();
$router = new \Orno\Route\RouteCollection();
$router->setStrategy(\Orno\Route\RouteStrategyInterface::RESTFUL_STRATEGY);
// Set up the OAuth 2.0 resource server
$sessionStorage = new Storage\SessionStorage();
$accessTokenStorage = new Storage\AccessTokenStorage();

View File

@@ -122,10 +122,11 @@ abstract class AbstractServer
*
* @param string $eventName Event name
* @param callable $listener Callable function or method
* @param int $priority Priority of event listener
*/
public function addEventListener($eventName, callable $listener)
public function addEventListener($eventName, callable $listener, $priority = Emitter::P_NORMAL)
{
$this->eventEmitter->addListener($eventName, $listener);
$this->eventEmitter->addListener($eventName, $listener, $priority);
}
/**

View File

@@ -20,7 +20,7 @@ use League\OAuth2\Server\TokenType\Bearer;
class AuthorizationServer extends AbstractServer
{
/**
* The delimeter between scopes specified in the scope query string parameter
* The delimiter between scopes specified in the scope query string parameter
* The OAuth 2 specification states it should be a space but most use a comma
*
* @var string

View File

@@ -12,7 +12,7 @@
namespace League\OAuth2\Server\Entity;
/**
* Access token entity class
* Auth Code entity class
*/
class AuthCodeEntity extends AbstractTokenEntity
{

View File

@@ -32,6 +32,7 @@ class InvalidGrantException extends OAuthException
public function __construct($parameter)
{
$this->parameter = $parameter;
parent::__construct(
sprintf(
'The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client. Check the "%s" parameter.',

View File

@@ -32,6 +32,7 @@ class InvalidRequestException extends OAuthException
public function __construct($parameter, $redirectUri = null)
{
$this->parameter = $parameter;
parent::__construct(
sprintf(
'The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Check the "%s" parameter.',

View File

@@ -32,6 +32,7 @@ class InvalidScopeException extends OAuthException
public function __construct($parameter, $redirectUri = null)
{
$this->parameter = $parameter;
parent::__construct(
sprintf(
'The requested scope is invalid, unknown, or malformed. Check the "%s" scope.',

View File

@@ -36,6 +36,11 @@ class OAuthException extends \Exception
*/
public $errorType = '';
/**
* Parameter eventually passed to Exception
*/
public $parameter = '';
/**
* Throw a new exception
*
@@ -72,6 +77,16 @@ class OAuthException extends \Exception
);
}
/**
* Return parameter if set
*
* @return string
*/
public function getParameter()
{
return $this->parameter;
}
/**
* Get all headers that have to be send with the error response
*

View File

@@ -31,7 +31,9 @@ class ServerErrorException extends OAuthException
*/
public function __construct($parameter = null)
{
$this->parameter = $parameter;
$parameter = is_null($parameter) ? 'The authorization server encountered an unexpected condition which prevented it from fulfilling the request.' : $parameter;
parent::__construct($parameter);
}
}

View File

@@ -32,6 +32,7 @@ class UnsupportedGrantTypeException extends OAuthException
public function __construct($parameter)
{
$this->parameter = $parameter;
parent::__construct(
sprintf(
'The authorization grant type "%s" is not supported by the authorization server.',

View File

@@ -31,6 +31,7 @@ class UnsupportedResponseTypeException extends OAuthException
*/
public function __construct($parameter, $redirectUri = null)
{
$this->parameter = $parameter;
parent::__construct('The authorization server does not support obtaining an access token using this method.');
$this->redirectUri = $redirectUri;
}

View File

@@ -60,6 +60,14 @@ class AuthCodeGrant extends AbstractGrant
*/
protected $authTokenTTL = 600;
/**
* Whether to require the client secret when
* completing the flow.
*
* @var boolean
*/
protected $requireClientSecret = true;
/**
* Override the default access token expire time
*
@@ -72,6 +80,27 @@ class AuthCodeGrant extends AbstractGrant
$this->authTokenTTL = $authTokenTTL;
}
/**
*
* @param bool $required True to require client secret during access
* token request. False if not. Default = true
*/
public function setRequireClientSecret($required)
{
$this->requireClientSecret = $required;
}
/**
* True if client secret is required during
* access token request. False if it isn't.
*
* @return bool
*/
public function shouldRequireClientSecret()
{
return $this->requireClientSecret;
}
/**
* Check authorize parameters
*
@@ -148,7 +177,6 @@ class AuthCodeGrant extends AbstractGrant
$session = new SessionEntity($this->server);
$session->setOwner($type, $typeId);
$session->associateClient($authParams['client']);
$session->save();
// Create a new auth code
$authCode = new AuthCodeEntity($this->server);
@@ -158,8 +186,10 @@ class AuthCodeGrant extends AbstractGrant
foreach ($authParams['scopes'] as $scope) {
$authCode->associateScope($scope);
$session->associateScope($scope);
}
$session->save();
$authCode->setSession($session);
$authCode->save();
@@ -183,7 +213,7 @@ class AuthCodeGrant extends AbstractGrant
$clientSecret = $this->server->getRequest()->request->get('client_secret',
$this->server->getRequest()->getPassword());
if (is_null($clientSecret)) {
if ($this->shouldRequireClientSecret() && is_null($clientSecret)) {
throw new Exception\InvalidRequestException('client_secret');
}
@@ -270,4 +300,4 @@ class AuthCodeGrant extends AbstractGrant
return $this->server->getTokenType()->generateResponse();
}
}
}

View File

@@ -19,7 +19,7 @@ use League\OAuth2\Server\Exception;
use League\OAuth2\Server\Util\SecureKey;
/**
* Referesh token grant
* Refresh token grant
*/
class RefreshTokenGrant extends AbstractGrant
{
@@ -42,6 +42,14 @@ class RefreshTokenGrant extends AbstractGrant
*/
protected $refreshTokenRotate = true;
/**
* Whether to require the client secret when
* completing the flow.
*
* @var boolean
*/
protected $requireClientSecret = true;
/**
* Set the TTL of the refresh token
*
@@ -83,6 +91,28 @@ class RefreshTokenGrant extends AbstractGrant
return $this->refreshTokenRotate;
}
/**
*
* @param bool $required True to require client secret during access
* token request. False if not. Default = true
*/
public function setRequireClientSecret($required)
{
$this->requireClientSecret = $required;
}
/**
* True if client secret is required during
* access token request. False if it isn't.
*
* @return bool
*/
public function shouldRequireClientSecret()
{
return $this->requireClientSecret;
}
/**
* {@inheritdoc}
*/
@@ -95,7 +125,7 @@ class RefreshTokenGrant extends AbstractGrant
$clientSecret = $this->server->getRequest()->request->get('client_secret',
$this->server->getRequest()->getPassword());
if (is_null($clientSecret)) {
if ($this->shouldRequireClientSecret() && is_null($clientSecret)) {
throw new Exception\InvalidRequestException('client_secret');
}
@@ -190,4 +220,4 @@ class RefreshTokenGrant extends AbstractGrant
return $this->server->getTokenType()->generateResponse();
}
}
}

View File

@@ -19,6 +19,7 @@ use League\OAuth2\Server\Storage\ClientInterface;
use League\OAuth2\Server\Storage\ScopeInterface;
use League\OAuth2\Server\Storage\SessionInterface;
use League\OAuth2\Server\TokenType\Bearer;
use League\OAuth2\Server\TokenType\MAC;
/**
* OAuth 2.0 Resource Server
@@ -137,9 +138,11 @@ class ResourceServer extends AbstractServer
*/
public function determineAccessToken($headerOnly = false)
{
if ($this->getRequest()->headers->get('Authorization') !== null) {
$authHeader = $this->getRequest()->headers->get('Authorization');
if (!empty($authHeader)) {
$accessToken = $this->getTokenType()->determineAccessTokenInHeader($this->getRequest());
} elseif ($headerOnly === false) {
} elseif ($headerOnly === false && (! $this->getTokenType() instanceof MAC)) {
$accessToken = ($this->getRequest()->server->get('REQUEST_METHOD') === 'GET')
? $this->getRequest()->query->get($this->tokenKey)
: $this->getRequest()->request->get($this->tokenKey);

View File

@@ -24,7 +24,7 @@ interface AccessTokenInterface extends StorageInterface
*
* @param string $token The access token
*
* @return \League\OAuth2\Server\Entity\AccessTokenEntity
* @return \League\OAuth2\Server\Entity\AccessTokenEntity | null
*/
public function get($token);
@@ -33,7 +33,7 @@ interface AccessTokenInterface extends StorageInterface
*
* @param \League\OAuth2\Server\Entity\AccessTokenEntity $token The access token
*
* @return array Array of \League\OAuth2\Server\Entity\ScopeEntity
* @return \League\OAuth2\Server\Entity\ScopeEntity[] Array of \League\OAuth2\Server\Entity\ScopeEntity
*/
public function getScopes(AccessTokenEntity $token);

View File

@@ -24,7 +24,7 @@ interface AuthCodeInterface extends StorageInterface
*
* @param string $code
*
* @return \League\OAuth2\Server\Entity\AuthCodeEntity
* @return \League\OAuth2\Server\Entity\AuthCodeEntity | null
*/
public function get($code);
@@ -45,7 +45,7 @@ interface AuthCodeInterface extends StorageInterface
*
* @param \League\OAuth2\Server\Entity\AuthCodeEntity $token The auth code
*
* @return array Array of \League\OAuth2\Server\Entity\ScopeEntity
* @return \League\OAuth2\Server\Entity\ScopeEntity[] Array of \League\OAuth2\Server\Entity\ScopeEntity
*/
public function getScopes(AuthCodeEntity $token);

View File

@@ -26,7 +26,7 @@ interface ClientInterface extends StorageInterface
* @param string $redirectUri The client's redirect URI (default = "null")
* @param string $grantType The grant type used (default = "null")
*
* @return \League\OAuth2\Server\Entity\ClientEntity
* @return \League\OAuth2\Server\Entity\ClientEntity | null
*/
public function get($clientId, $clientSecret = null, $redirectUri = null, $grantType = null);
@@ -35,7 +35,7 @@ interface ClientInterface extends StorageInterface
*
* @param \League\OAuth2\Server\Entity\SessionEntity $session The session
*
* @return \League\OAuth2\Server\Entity\ClientEntity
* @return \League\OAuth2\Server\Entity\ClientEntity | null
*/
public function getBySession(SessionEntity $session);
}

View File

@@ -23,7 +23,7 @@ interface RefreshTokenInterface extends StorageInterface
*
* @param string $token
*
* @return \League\OAuth2\Server\Entity\RefreshTokenEntity
* @return \League\OAuth2\Server\Entity\RefreshTokenEntity | null
*/
public function get($token);

View File

@@ -23,7 +23,7 @@ interface ScopeInterface extends StorageInterface
* @param string $grantType The grant type used in the request (default = "null")
* @param string $clientId The client sending the request (default = "null")
*
* @return \League\OAuth2\Server\Entity\ScopeEntity
* @return \League\OAuth2\Server\Entity\ScopeEntity | null
*/
public function get($scope, $grantType = null, $clientId = null);
}

View File

@@ -26,7 +26,7 @@ interface SessionInterface extends StorageInterface
*
* @param \League\OAuth2\Server\Entity\AccessTokenEntity $accessToken The access token
*
* @return \League\OAuth2\Server\Entity\SessionEntity
* @return \League\OAuth2\Server\Entity\SessionEntity | null
*/
public function getByAccessToken(AccessTokenEntity $accessToken);
@@ -35,7 +35,7 @@ interface SessionInterface extends StorageInterface
*
* @param \League\OAuth2\Server\Entity\AuthCodeEntity $authCode The auth code
*
* @return \League\OAuth2\Server\Entity\SessionEntity
* @return \League\OAuth2\Server\Entity\SessionEntity | null
*/
public function getByAuthCode(AuthCodeEntity $authCode);
@@ -44,7 +44,7 @@ interface SessionInterface extends StorageInterface
*
* @param \League\OAuth2\Server\Entity\SessionEntity
*
* @return array Array of \League\OAuth2\Server\Entity\ScopeEntity
* @return \League\OAuth2\Server\Entity\ScopeEntity[] Array of \League\OAuth2\Server\Entity\ScopeEntity
*/
public function getScopes(SessionEntity $session);

View File

@@ -38,9 +38,16 @@ class Bearer extends AbstractTokenType implements TokenTypeInterface
*/
public function determineAccessTokenInHeader(Request $request)
{
$header = $request->headers->get('Authorization');
$accessToken = trim(preg_replace('/^(?:\s+)?Bearer\s/', '', $header));
if ($request->headers->has('Authorization') === false) {
return;
}
return ($accessToken === 'Bearer') ? '' : $accessToken;
$header = $request->headers->get('Authorization');
if (substr($header, 0, 7) !== 'Bearer ') {
return;
}
return trim(substr($header, 7));
}
}

View File

@@ -36,6 +36,10 @@ class MAC extends AbstractTokenType implements TokenTypeInterface
'mac_algorithm' => 'hmac-sha-256',
];
if (!is_null($this->getParam('refresh_token'))) {
$response['refresh_token'] = $this->getParam('refresh_token');
}
return $response;
}
@@ -61,7 +65,7 @@ class MAC extends AbstractTokenType implements TokenTypeInterface
array_map(function ($param) use (&$params) {
$param = trim($param);
preg_match_all('/([a-zA-Z]*)="([\w=]*)"/', $param, $matches);
preg_match_all('/([a-zA-Z]*)="([\w=\/+]*)"/', $param, $matches);
// @codeCoverageIgnoreStart
if (count($matches) !== 3) {
@@ -84,7 +88,7 @@ class MAC extends AbstractTokenType implements TokenTypeInterface
return;
}
if ((int) $params->get('ts') !== time()) {
if (abs($params->get('ts') - time()) > 300) {
return;
}
@@ -105,7 +109,7 @@ class MAC extends AbstractTokenType implements TokenTypeInterface
$timestamp,
$nonce,
strtoupper($request->getMethod()),
$request->getUri(),
$request->getRequestUri(),
$request->getHost(),
$request->getPort(),
];
@@ -114,7 +118,14 @@ class MAC extends AbstractTokenType implements TokenTypeInterface
$calculatedSignatureParts[] = $params->get('ext');
}
$calculatedSignature = base64_encode(hash_hmac('sha256', implode("\n", $calculatedSignatureParts), $macKey));
$calculatedSignature = base64_encode(
hash_hmac(
'sha256',
implode("\n", $calculatedSignatureParts),
$macKey,
true // raw_output: outputs raw binary data
)
);
// Return the access token if the signature matches
return ($this->hash_equals($calculatedSignature, $signature)) ? $accessToken : null;

View File

@@ -498,4 +498,73 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
$this->assertTrue(array_key_exists('expires_in', $response));
$this->assertEquals($response['refresh_token'], $_POST['refresh_token']);
}
public function testCompleteFlowShouldRequireClientSecret()
{
$_POST = [
'grant_type' => 'refresh_token',
'client_id' => 'testapp',
'refresh_token' => 'refresh_token',
];
$server = new AuthorizationServer();
$grant = new RefreshTokenGrant();
$grant->setRequireClientSecret(false);
$clientStorage = M::mock('League\OAuth2\Server\Storage\ClientInterface');
$clientStorage->shouldReceive('setServer');
$clientStorage->shouldReceive('get')->andReturn(
(new ClientEntity($server))->hydrate(['id' => 'testapp'])
);
$sessionStorage = M::mock('League\OAuth2\Server\Storage\SessionInterface');
$sessionStorage->shouldReceive('setServer');
$sessionStorage->shouldReceive('getScopes')->shouldReceive('getScopes')->andReturn([]);
$sessionStorage->shouldReceive('associateScope');
$sessionStorage->shouldReceive('getByAccessToken')->andReturn(
(new SessionEntity($server))
);
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$accessTokenStorage->shouldReceive('get')->andReturn(
(new AccessTokenEntity($server))
);
$accessTokenStorage->shouldReceive('delete');
$accessTokenStorage->shouldReceive('create');
$accessTokenStorage->shouldReceive('getScopes')->andReturn([
(new ScopeEntity($server))->hydrate(['id' => 'foo']),
]);
$accessTokenStorage->shouldReceive('associateScope');
$refreshTokenStorage = M::mock('League\OAuth2\Server\Storage\RefreshTokenInterface');
$refreshTokenStorage->shouldReceive('setServer');
$refreshTokenStorage->shouldReceive('associateScope');
$refreshTokenStorage->shouldReceive('delete');
$refreshTokenStorage->shouldReceive('create');
$refreshTokenStorage->shouldReceive('get')->andReturn(
(new RefreshTokenEntity($server))->setId('refresh_token')->setExpireTime(time() + 86400)
);
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$scopeStorage->shouldReceive('get')->andReturn(
(new ScopeEntity($server))->hydrate(['id' => 'foo'])
);
$server->setClientStorage($clientStorage);
$server->setScopeStorage($scopeStorage);
$server->setSessionStorage($sessionStorage);
$server->setAccessTokenStorage($accessTokenStorage);
$server->setRefreshTokenStorage($refreshTokenStorage);
$server->addGrantType($grant);
$response = $server->issueAccessToken();
$this->assertTrue(array_key_exists('access_token', $response));
$this->assertTrue(array_key_exists('refresh_token', $response));
$this->assertTrue(array_key_exists('token_type', $response));
$this->assertTrue(array_key_exists('expires_in', $response));
}
}

View File

@@ -52,12 +52,12 @@ class MacTest extends \PHPUnit_Framework_TestCase
$ts,
'foo',
strtoupper($request->getMethod()),
$request->getUri(),
$request->getRequestUri(),
$request->getHost(),
$request->getPort(),
'ext'
];
$calculatedSignature = base64_encode(hash_hmac('sha256', implode("\n", $calculatedSignatureParts), 'abcdef'));
$calculatedSignature = base64_encode(hash_hmac('sha256', implode("\n", $calculatedSignatureParts), 'abcdef', true));
$request->headers->set('Authorization', sprintf('MAC id="foo", nonce="foo", ts="%s", mac="%s", ext="ext"', $ts, $calculatedSignature));