Merge branch 'V5-WIP' into unify_examples

This commit is contained in:
Julián Gutiérrez 2016-03-08 21:47:02 +01:00
commit 9c66688d19
106 changed files with 3172 additions and 4122 deletions

3
.gitattributes vendored
View File

@ -7,8 +7,7 @@
/.travis.yml export-ignore
.travis.yml export-ignore
.scrutinizer.yml export-ignore
/codeception.yml export-ignore
/phpunit.xml.dist export-ignore
/CHANGELOG.md export-ignore
/CONTRIBUTING.md export-ignore
/README.md export-ignore
/README.md export-ignore

2
.gitignore vendored
View File

@ -3,6 +3,6 @@
phpunit.xml
.idea
/examples/vendor
/tests/_output
examples/public.key
examples/private.key
build

53
.styleci.yml Normal file
View File

@ -0,0 +1,53 @@
preset: psr2
enabled:
- binary_operator_spaces
- blank_line_before_return
- concat_with_spaces
- function_typehint_space
- hash_to_slash_comment
- include
- lowercase_cast
- method_separation
- native_function_casing
- no_blank_lines_after_class_opening
- no_blank_lines_between_uses
- no_duplicate_semicolons
- no_leading_import_slash
- no_leading_namespace_whitespace
- no_multiline_whitespace_before_semicolons
- no_php4_constructor
- no_short_bool_cast
- no_singleline_whitespace_before_semicolons
- no_trailing_comma_in_singleline_array
- no_unreachable_default_argument_value
- no_unused_imports
- no_whitespace_before_comma_in_array
- ordered_imports
- phpdoc_align
- phpdoc_indent
- phpdoc_inline_tag
- phpdoc_no_access
- phpdoc_no_simplified_null_return
- phpdoc_order
- phpdoc_property
- phpdoc_scalar
- phpdoc_separation
- phpdoc_to_comment
- phpdoc_trim
- phpdoc_type_to_var
- phpdoc_types
- phpdoc_var_without_name
- print_to_echo
- short_array_syntax
- short_scalar_cast
- simplified_null_return
- single_quote
- spaces_cast
- standardize_not_equal
- ternary_operator_spaces
- trailing_comma_in_multiline_array
- trim_array_spaces
- unary_operator_spaces
- whitespace_after_comma_in_array
- whitespacy_lines

View File

@ -15,37 +15,10 @@ php:
install:
- travis_retry composer install --no-interaction --prefer-source
before_script:
- cd examples/
- composer install
- cd public/
- php -S localhost:7777 &
- cd ../..
script:
- vendor/bin/codecept build && vendor/bin/codecept run
after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- php ocular.phar code-coverage:upload --format=php-clover coverage.clover
- git config --global user.email "travis@travis-ci.org"
- git config --global user.name "TravisCI"
- cp -R coverage ${HOME}/coverage
- cd ${HOME}
- git clone --quiet --branch=gh-pages https://${GITHUBTOKEN}@github.com/thephpleague/oauth2-server.git gh-pages > /dev/null
- cd gh-pages
- mkdir ${TRAVIS_BRANCH}
- cd ${TRAVIS_BRANCH}
- cp -Rf $HOME/coverage/* .
- git add -f .
- git commit -m "Travis pushed coverage of ${TRAVIS_COMMIT}@${TRAVIS_BRANCH} to gh-pages"
- git push -fq origin gh-pages > /dev/null
- vendor/bin/phpunit
branches:
only:
- master
- v5
env:
global:
secure: "C4wD/BQefKSu9W594iyLp+IBCjlM8kKlmp+nXKXnZGi0L8IkV3m4mmNOb8PExxGMhZ3mlev5DnU4Uoh4oJaUxnkR1FpX4dSEpyzU3VknUzSE2yZOlL+bdCw3o85TGoCcp/+ReJCOw5sncxTskJKHlW1YMa33FznaXwLNoImpjTg="
- V5-WIP

View File

@ -5,18 +5,19 @@
[![Build Status](https://img.shields.io/travis/thephpleague/oauth2-server/master.svg?style=flat-square)](https://travis-ci.org/thephpleague/oauth2-server)
[![Coverage Status](https://img.shields.io/scrutinizer/coverage/g/thephpleague/oauth2-server.svg?style=flat-square)](https://scrutinizer-ci.com/g/thephpleague/oauth2-server/code-structure)
[![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) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/thephpleague/oauth2-server?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
[![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.
It supports out of the box the following grants:
* Authorization code grant
* Implicit grant
* Client credentials grant
* Resource owner password credentials grant
* Refresh grant
You can also define your own grants.
You can also easily define your own grants.
In addition it supports the following token response types:
@ -49,7 +50,9 @@ Please see [CONTRIBUTING.md](https://github.com/thephpleague/oauth2-server/blob/
## Support
Bugs and feature request are tracked on [GitHub](https://github.com/thephpleague/oauth2-server/issues)
Bugs and feature request are tracked on [GitHub](https://github.com/thephpleague/oauth2-server/issues).
If you have any questions about OAuth _please_ open a ticket here; please **don't** email the address below.
## Security

View File

@ -1,10 +0,0 @@
actor: Tester
paths:
tests: tests
log: tests/_output
data: tests/_data
helpers: tests/_support
settings:
bootstrap: _bootstrap.php
colors: true
memory_limit: 1024M

View File

@ -11,10 +11,8 @@
"paragonie/random_compat": "^1.1"
},
"require-dev": {
"phpunit/phpunit": "4.8.*",
"mockery/mockery": "0.9.*",
"codeception/codeception": "~2.0",
"flow/jsonpath": "0.2.*"
"phpunit/phpunit": "^4.8",
"league/plates": "^3.1"
},
"repositories": [
{
@ -57,7 +55,7 @@
},
"autoload-dev": {
"psr-4": {
"LeagueTests\\": "tests/unit/"
"LeagueTests\\": "tests/"
}
},
"extra": {

View File

@ -14,7 +14,7 @@ use Psr\Http\Message\ServerRequestInterface;
use Slim\App;
use Zend\Diactoros\Stream;
include(__DIR__ . '/../vendor/autoload.php');
include __DIR__ . '/../vendor/autoload.php';
$app = new App([
'settings' => [
@ -56,6 +56,22 @@ $app = new App([
},
]);
$app->any('/authorize', function (ServerRequestInterface $request, ResponseInterface $response) use ($app) {
/* @var \League\OAuth2\Server\Server $server */
$server = $app->getContainer()->get(Server::class);
try {
return $server->respondToRequest($request, $response);
} catch (OAuthServerException $exception) {
return $exception->generateHttpResponse($response);
} catch (\Exception $exception) {
$body = new Stream('php://temp', 'r+');
$body->write($exception->getMessage());
return $response->withStatus(500)->withBody($body);
}
});
$app->post('/access_token', function (ServerRequestInterface $request, ResponseInterface $response) use ($app) {
/* @var \League\OAuth2\Server\Server $server */
$server = $app->getContainer()->get(Server::class);

View File

@ -11,7 +11,7 @@ use Psr\Http\Message\ServerRequestInterface;
use Slim\App;
use Zend\Diactoros\Stream;
include(__DIR__ . '/../vendor/autoload.php');
include __DIR__ . '/../vendor/autoload.php';
$app = new App([
'settings' => [
@ -42,7 +42,7 @@ $app = new App([
);
return $server;
}
},
]);
$app->post('/access_token', function (ServerRequestInterface $request, ResponseInterface $response) use ($app) {

View File

@ -16,7 +16,7 @@ use Psr\Http\Message\ServerRequestInterface;
use Slim\App;
use Zend\Diactoros\Stream;
include(__DIR__ . '/../vendor/autoload.php');
include __DIR__ . '/../vendor/autoload.php';
$app = new App([
'settings' => [
@ -61,7 +61,7 @@ $app = new App([
);
return $server;
}
},
]);
// Access token issuer

View File

@ -13,7 +13,7 @@ use Psr\Http\Message\ServerRequestInterface;
use Slim\App;
use Zend\Diactoros\Stream;
include(__DIR__ . '/../vendor/autoload.php');
include __DIR__ . '/../vendor/autoload.php';
$app = new App([
'settings' => [
@ -46,7 +46,7 @@ $app = new App([
);
return $server;
}
},
]);
$app->post('/access_token', function (ServerRequestInterface $request, ResponseInterface $response) use ($app) {

View File

@ -12,7 +12,7 @@ use Psr\Http\Message\ServerRequestInterface;
use Slim\App;
use Zend\Diactoros\Stream;
include(__DIR__ . '/../vendor/autoload.php');
include __DIR__ . '/../vendor/autoload.php';
$app = new App([
'settings' => [

View File

@ -1,72 +0,0 @@
<?php
use League\OAuth2\Server\Exception\OAuthServerException;
use League\OAuth2\Server\Server;
use OAuth2ServerExamples\Repositories\AccessTokenRepository;
use OAuth2ServerExamples\Repositories\ClientRepository;
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');
$app = new App([
'settings' => [
'displayErrorDetails' => true,
],
Server::class => function () {
// Init our repositories
$clientRepository = new ClientRepository();
$accessTokenRepository = new AccessTokenRepository();
$scopeRepository = new ScopeRepository();
$privateKeyPath = 'file://' . __DIR__ . '/../private.key';
$publicKeyPath = 'file://' . __DIR__ . '/../public.key';
// Setup the authorization server
return new Server(
$clientRepository,
$accessTokenRepository,
$scopeRepository,
$privateKeyPath,
$publicKeyPath
);
}
]);
$app->get('/user', function (ServerRequestInterface $request, ResponseInterface $response) use ($app) {
$server = $app->getContainer()->get(Server::class);
$body = new Stream('php://temp', 'r+');
try {
$request = $server->validateRequest($request);
} catch (OAuthServerException $exception) {
return $exception->generateHttpResponse($response);
} catch (\Exception $exception) {
$body->write($exception->getMessage());
return $response->withStatus(500)->withBody($body);
}
$params = [];
if (in_array('basic', $request->getAttribute('oauth_scopes', []))) {
$params = [
'id' => 1,
'name' => 'Alex',
'city' => 'London'
];
}
if (in_array('email', $request->getAttribute('oauth_scopes', []))) {
$params['email'] = 'alex@example.com';
}
$body->write(json_encode($params));
return $response->withBody($body);
});
$app->run();

View File

@ -7,11 +7,12 @@ use League\OAuth2\Server\Entities\Interfaces\UserEntityInterface;
class UserEntity implements UserEntityInterface
{
/**
* Return the user's identifier
* Return the user's identifier.
*
* @return mixed
*/
public function getIdentifier()
{
return 1;
}
}
}

View File

@ -1,4 +1,5 @@
<?php
namespace OAuth2ServerExamples\Repositories;
use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface;
@ -7,7 +8,7 @@ use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
class AccessTokenRepository implements AccessTokenRepositoryInterface
{
/**
* Persists a new access token to permanent storage
* Persists a new access token to permanent storage.
*
* @param \League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface $accessTokenEntity
*/
@ -17,7 +18,7 @@ class AccessTokenRepository implements AccessTokenRepositoryInterface
}
/**
* Revoke an access token
* Revoke an access token.
*
* @param string $tokenId
*/
@ -27,7 +28,7 @@ class AccessTokenRepository implements AccessTokenRepositoryInterface
}
/**
* Check if the access token has been revoked
* Check if the access token has been revoked.
*
* @param string $tokenId
*

View File

@ -7,9 +7,8 @@ use League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface;
class AuthCodeRepository implements AuthCodeRepositoryInterface
{
/**
* Persists a new auth code to permanent storage
* Persists a new auth code to permanent storage.
*
* @param \League\OAuth2\Server\Entities\Interfaces\AuthCodeEntityInterface $authCodeEntity
*/
@ -19,7 +18,7 @@ class AuthCodeRepository implements AuthCodeRepositoryInterface
}
/**
* Revoke an auth code
* Revoke an auth code.
*
* @param string $codeId
*/
@ -29,7 +28,7 @@ class AuthCodeRepository implements AuthCodeRepositoryInterface
}
/**
* Check if the auth code has been revoked
* Check if the auth code has been revoked.
*
* @param string $codeId
*
@ -39,4 +38,4 @@ class AuthCodeRepository implements AuthCodeRepositoryInterface
{
// TODO: Implement isAuthCodeRevoked() method.
}
}
}

View File

@ -1,4 +1,5 @@
<?php
namespace OAuth2ServerExamples\Repositories;
use League\OAuth2\Server\Entities\ClientEntity;
@ -7,7 +8,7 @@ use League\OAuth2\Server\Repositories\ClientRepositoryInterface;
class ClientRepository implements ClientRepositoryInterface
{
/**
* @inheritdoc
* {@inheritdoc}
*/
public function getClientEntity($clientIdentifier, $clientSecret = null, $redirectUri = null, $grantType = null)
{
@ -15,23 +16,23 @@ class ClientRepository implements ClientRepositoryInterface
'myawesomeapp' => [
'secret' => password_hash('abc123', PASSWORD_BCRYPT),
'name' => 'My Awesome App',
'redirect_uri' => 'http://foo/bar'
]
'redirect_uri' => 'http://foo/bar',
],
];
// Check if client is registered
if (array_key_exists($clientIdentifier, $clients) === false) {
return null;
return;
}
// Check if client secret is valid
if ($clientSecret !== null && password_verify($clientSecret, $clients[$clientIdentifier]['secret']) === false) {
return null;
return;
}
// Check if redirect URI is valid
if ($redirectUri !== null && $redirectUri !== $clients[$clientIdentifier]['redirect_uri']) {
return null;
return;
}
$client = new ClientEntity();

View File

@ -7,9 +7,8 @@ use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;
class RefreshTokenRepository implements RefreshTokenRepositoryInterface
{
/**
* Create a new refresh token_name
* Create a new refresh token_name.
*
* @param \League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface $refreshTokenEntityInterface
*/
@ -19,7 +18,7 @@ class RefreshTokenRepository implements RefreshTokenRepositoryInterface
}
/**
* Revoke the refresh token
* Revoke the refresh token.
*
* @param string $tokenId
*/
@ -29,7 +28,7 @@ class RefreshTokenRepository implements RefreshTokenRepositoryInterface
}
/**
* Check if the refresh token has been revoked
* Check if the refresh token has been revoked.
*
* @param string $tokenId
*

View File

@ -1,4 +1,5 @@
<?php
namespace OAuth2ServerExamples\Repositories;
use League\OAuth2\Server\Entities\ScopeEntity;
@ -7,21 +8,21 @@ use League\OAuth2\Server\Repositories\ScopeRepositoryInterface;
class ScopeRepository implements ScopeRepositoryInterface
{
/**
* @inheritdoc
* {@inheritdoc}
*/
public function getScopeEntityByIdentifier($scopeIdentifier, $grantType, $clientId = null)
{
$scopes = [
'basic' => [
'description' => 'Basic details about you'
'description' => 'Basic details about you',
],
'email' => [
'description' => 'Your email address'
]
'description' => 'Your email address',
],
];
if (array_key_exists($scopeIdentifier, $scopes) === false) {
return null;
return;
}
$scope = new ScopeEntity();

View File

@ -1,4 +1,5 @@
<?php
namespace OAuth2ServerExamples\Repositories;
use League\OAuth2\Server\Repositories\UserRepositoryInterface;
@ -7,7 +8,7 @@ use OAuth2ServerExamples\Entities\UserEntity;
class UserRepository implements UserRepositoryInterface
{
/**
* Get a user entity
* Get a user entity.
*
* @param string $username
* @param string $password
@ -20,6 +21,6 @@ class UserRepository implements UserRepositoryInterface
return new UserEntity();
}
return null;
return;
}
}

View File

@ -1,17 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit colors="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" stopOnError="true" stopOnFailure="true" stopOnIncomplete="false" stopOnSkipped="false" bootstrap="tests/unit/Bootstrap.php">
<testsuites>
<testsuite name="Tests">
<directory>./tests/unit/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist addUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src</directory>
</whitelist>
</filter>
<logging>
<!-- <log type="coverage-text" target="php://stdout" title="thephpleague/oauth2-server" charset="UTF-8" yui="true" highlight="true" lowUpperBound="60" highLowerBound="90"/> -->
<log type="coverage-html" target="build/coverage" title="thephpleague/oauth2-server" charset="UTF-8" yui="true" highlight="true" lowUpperBound="60" highLowerBound="90"/>
</logging>
<phpunit colors="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" stopOnError="true"
stopOnFailure="true" stopOnIncomplete="false" stopOnSkipped="false" bootstrap="tests/Bootstrap.php">
<testsuites>
<testsuite name="Tests">
<directory>./tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist addUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src</directory>
<exclude>
<directory suffix=".php">src/ResponseTypes/DefaultTemplates</directory>
</exclude>
</whitelist>
</filter>
<logging>
<log type="coverage-text" target="php://stdout" title="thephpleague/oauth2-server" charset="UTF-8" yui="true"
highlight="true" lowUpperBound="60" highLowerBound="90"/>
<log type="coverage-html" target="build/coverage" title="thephpleague/oauth2-server" charset="UTF-8" yui="true"
highlight="true" lowUpperBound="60" highLowerBound="90"/>
</logging>
</phpunit>

View File

@ -1,6 +1,9 @@
<?php
namespace League\OAuth2\Server\Entities;
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Rsa\Sha256;
use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface;
use League\OAuth2\Server\Entities\Traits\EntityTrait;
use League\OAuth2\Server\Entities\Traits\TokenEntityTrait;
@ -8,4 +11,25 @@ use League\OAuth2\Server\Entities\Traits\TokenEntityTrait;
class AccessTokenEntity implements AccessTokenEntityInterface
{
use EntityTrait, TokenEntityTrait;
/**
* Generate a JWT from the access token
*
* @param string $pathToPrivateKey
*
* @return string
*/
public function convertToJWT($pathToPrivateKey)
{
return (new Builder())
->setAudience($this->getClient()->getIdentifier())
->setId($this->getIdentifier(), true)
->setIssuedAt(time())
->setNotBefore(time())
->setExpiration($this->getExpiryDateTime()->getTimestamp())
->setSubject($this->getUserIdentifier())
->set('scopes', $this->getScopes())
->sign(new Sha256(), new Key($pathToPrivateKey))
->getToken();
}
}

View File

@ -1,4 +1,5 @@
<?php
namespace League\OAuth2\Server\Entities;
use League\OAuth2\Server\Entities\Interfaces\AuthCodeEntityInterface;
@ -6,8 +7,7 @@ use League\OAuth2\Server\Entities\Traits\EntityTrait;
use League\OAuth2\Server\Entities\Traits\TokenEntityTrait;
/**
* Class AuthCodeEntity
* @package League\OAuth2\Server
* Class AuthCodeEntity.
*/
class AuthCodeEntity implements AuthCodeEntityInterface
{

View File

@ -1,79 +0,0 @@
<?php
namespace League\OAuth2\Server\Entities;
class AuthorizationCodeRequestEntity
{
/**
* @var string
*/
private $clientId;
/**
* @var null|string
*/
private $redirectUri;
/**
* @var null|string
*/
private $scope;
/**
* @var null|string
*/
private $state;
/**
* @return string
*/
public function getClientId()
{
return $this->clientId;
}
/**
* @return null|string
*/
public function getRedirectUri()
{
return $this->redirectUri;
}
/**
* @return null|string
*/
public function getScope()
{
return $this->scope;
}
/**
* @return null|string
*/
public function getState()
{
return $this->state;
}
/**
* AuthorizationCodeRequestEntity constructor.
*
* @param string $clientId
* @param string|null $redirectUri
* @param string|null $scope
* @param string|null $state
*/
public function __construct($clientId, $redirectUri = null, $scope = null, $state = null)
{
$this->clientId = $clientId;
$this->redirectUri = $redirectUri;
$this->scope = $scope;
$this->state = $state;
}
public function __sleep()
{
return ['clientId', 'redirectUri', 'scope', 'state'];
}
}

View File

@ -1,4 +1,5 @@
<?php
namespace League\OAuth2\Server\Entities;
use League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface;
@ -6,8 +7,7 @@ use League\OAuth2\Server\Entities\Traits\ClientEntityTrait;
use League\OAuth2\Server\Entities\Traits\EntityTrait;
/**
* Class ClientEntity
* @package League\OAuth2\Server
* Class ClientEntity.
*/
class ClientEntity implements ClientEntityInterface
{

View File

@ -1,7 +1,15 @@
<?php
namespace League\OAuth2\Server\Entities\Interfaces;
interface AccessTokenEntityInterface extends TokenInterface
{
/**
* Generate a JWT from the access token
*
* @param string $pathToPrivateKey
*
* @return string
*/
public function convertToJWT($pathToPrivateKey);
}

View File

@ -1,29 +1,69 @@
<?php
namespace League\OAuth2\Server\Entities\Interfaces;
interface ClientEntityInterface
{
/**
* Get the client's identifier
* Get the client's identifier.
*
* @return string
*/
public function getIdentifier();
/**
* Set the client's identifier
* Set the client's identifier.
*
* @param $identifier
*/
public function setIdentifier($identifier);
/**
* Get the client's name
* Get the client's name.
*
* @return string
*/
public function getName();
/**
* Set the client's name
* Set the client's name.
*
* @param string $name
*/
public function setName($name);
/**
* @param string $secret
*/
public function setSecret($secret);
/**
* Validate the secret provided by the client.
*
* @param string $submittedSecret
*
* @return bool
*/
public function validateSecret($submittedSecret);
/**
* Set the client's redirect uri.
*
* @param string $redirectUri
*/
public function setRedirectUri($redirectUri);
/**
* Returns the registered redirect URI.
*
* @return string
*/
public function getRedirectUri();
/**
* Returns true if the client is capable of keeping it's secrets secret.
*
* @return bool
*/
public function canKeepASecret();
}

View File

@ -1,42 +1,55 @@
<?php
namespace League\OAuth2\Server\Entities\Interfaces;
interface RefreshTokenEntityInterface
{
/**
* Get the token's identifier
* Get the token's identifier.
*
* @return string
*/
public function getIdentifier();
/**
* Set the token's identifier
* Set the token's identifier.
*
* @param $identifier
*/
public function setIdentifier($identifier);
/**
* Get the token's expiry date time
* Get the token's expiry date time.
*
* @return \DateTime
*/
public function getExpiryDateTime();
/**
* Set the date time when the token expires
* Set the date time when the token expires.
*
* @param \DateTime $dateTime
*/
public function setExpiryDateTime(\DateTime $dateTime);
/**
* Set the access token that the refresh token was associated with
* Set the access token that the refresh token was associated with.
*
* @param \League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface $accessToken
*/
public function setAccessToken(AccessTokenEntityInterface $accessToken);
/**
* Get the access token that the refresh token was originally associated with
* Get the access token that the refresh token was originally associated with.
*
* @return \League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface
*/
public function getAccessToken();
/**
* Has the token expired?
*
* @return bool
*/
public function isExpired();
}

View File

@ -1,16 +1,19 @@
<?php
namespace League\OAuth2\Server\Entities\Interfaces;
interface ScopeEntityInterface extends \JsonSerializable
{
/**
* Get the scope's identifier
* Get the scope's identifier.
*
* @return string
*/
public function getIdentifier();
/**
* Set the scope's identifier
* Set the scope's identifier.
*
* @param $identifier
*/
public function setIdentifier($identifier);

View File

@ -1,78 +1,91 @@
<?php
namespace League\OAuth2\Server\Entities\Interfaces;
interface TokenInterface
{
/**
* Get the token's identifier
* Get the token's identifier.
*
* @return string
*/
public function getIdentifier();
/**
* Set the token's identifier
* Set the token's identifier.
*
* @param $identifier
*/
public function setIdentifier($identifier);
/**
* Get the token's expiry date time
* Get the token's expiry date time.
*
* @return \DateTime
*/
public function getExpiryDateTime();
/**
* Set the date time when the token expires
* Set the date time when the token expires.
*
* @param \DateTime $dateTime
*/
public function setExpiryDateTime(\DateTime $dateTime);
/**
* Set the identifier of the user associated with the token
* Set the identifier of the user associated with the token.
*
* @param string|int $identifier The identifier of the user
*/
public function setUserIdentifier($identifier);
/**
* Get the token user's identifier
* Get the token user's identifier.
*
* @return string|int
*/
public function getUserIdentifier();
/**
* Get the client that the token was issued to
* Get the client that the token was issued to.
*
* @return ClientEntityInterface
*/
public function getClient();
/**
* Set the client that the token was issued to
* Set the client that the token was issued to.
*
* @param \League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface $client
*/
public function setClient(ClientEntityInterface $client);
/**
* Associate a scope with the token
* Associate a scope with the token.
*
* @param \League\OAuth2\Server\Entities\Interfaces\ScopeEntityInterface $scope
*/
public function addScope(ScopeEntityInterface $scope);
/**
* Get an associated scope by the scope's identifier
* Get an associated scope by the scope's identifier.
*
* @param string $identifier
* @return ScopeEntityInterface|null The scope or null if not found
*
* @return ScopeEntityInterface|null The scope or null if not found
*/
public function getScopeWithIdentifier($identifier);
/**
* Return an array of scopes associated with the token
* Return an array of scopes associated with the token.
*
* @return ScopeEntityInterface[]
*/
public function getScopes();
/**
* Has the token expired?
*
* @return bool
*/
public function isExpired();

View File

@ -5,7 +5,8 @@ namespace League\OAuth2\Server\Entities\Interfaces;
interface UserEntityInterface
{
/**
* Return the user's identifier
* Return the user's identifier.
*
* @return mixed
*/
public function getIdentifier();

View File

@ -1,4 +1,5 @@
<?php
namespace League\OAuth2\Server\Entities;
use League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface;
@ -6,8 +7,7 @@ use League\OAuth2\Server\Entities\Traits\EntityTrait;
use League\OAuth2\Server\Entities\Traits\RefreshTokenTrait;
/**
* Class RefreshTokenEntity
* @package League\OAuth2\Server
* Class RefreshTokenEntity.
*/
class RefreshTokenEntity implements RefreshTokenEntityInterface
{

View File

@ -1,19 +1,19 @@
<?php
namespace League\OAuth2\Server\Entities;
use League\OAuth2\Server\Entities\Interfaces\ScopeEntityInterface;
use League\OAuth2\Server\Entities\Traits\EntityTrait;
/**
* Class ScopeEntity
* @package League\OAuth2\Server
* Class ScopeEntity.
*/
class ScopeEntity implements ScopeEntityInterface
{
use EntityTrait;
/**
* @inheritdoc
* {@inheritdoc}
*/
public function jsonSerialize()
{

View File

@ -1,4 +1,5 @@
<?php
namespace League\OAuth2\Server\Entities\Traits;
trait ClientEntityTrait
@ -9,8 +10,17 @@ trait ClientEntityTrait
protected $name;
/**
* Get the client's name
* @return string
* @var string
*/
protected $secret;
/**
* @var string
*/
protected $redirectUri;
/**
* {@inheritdoc}
*/
public function getName()
{
@ -18,11 +28,50 @@ trait ClientEntityTrait
}
/**
* Set the client's name
* @param string $name
* {@inheritdoc}
*/
public function setName($name)
{
$this->name = $name;
}
/**
* {@inheritdoc}
*/
public function canKeepASecret()
{
return $this->secret !== null;
}
/**
* {@inheritdoc}
*/
public function setSecret($secret)
{
$this->secret = $secret;
}
/**
* {@inheritdoc}
*/
public function validateSecret($submittedSecret)
{
return strcmp((string) $submittedSecret, $this->secret) === 0;
}
/**
* {@inheritdoc}
*/
public function setRedirectUri($redirectUri)
{
$this->redirectUri = $redirectUri;
}
/**
* {@inheritdoc}
*/
public function getRedirectUri()
{
return $this->redirectUri;
}
}

View File

@ -1,4 +1,5 @@
<?php
namespace League\OAuth2\Server\Entities\Traits;
trait EntityTrait

View File

@ -1,4 +1,5 @@
<?php
namespace League\OAuth2\Server\Entities\Traits;
use DateTime;
@ -17,7 +18,7 @@ trait RefreshTokenTrait
protected $expiryDateTime;
/**
* @inheritdoc
* {@inheritdoc}
*/
public function setAccessToken(AccessTokenEntityInterface $accessToken)
{
@ -25,7 +26,7 @@ trait RefreshTokenTrait
}
/**
* @inheritdoc
* {@inheritdoc}
*/
public function getAccessToken()
{
@ -33,7 +34,8 @@ trait RefreshTokenTrait
}
/**
* Get the token's expiry date time
* Get the token's expiry date time.
*
* @return DateTime
*/
public function getExpiryDateTime()
@ -42,7 +44,7 @@ trait RefreshTokenTrait
}
/**
* Set the date time when the token expires
* Set the date time when the token expires.
*
* @param DateTime $dateTime
*/
@ -50,4 +52,14 @@ trait RefreshTokenTrait
{
$this->expiryDateTime = $dateTime;
}
/**
* Has the token expired?
*
* @return bool
*/
public function isExpired()
{
return (new DateTime()) > $this->getExpiryDateTime();
}
}

View File

@ -1,4 +1,5 @@
<?php
namespace League\OAuth2\Server\Entities\Traits;
use DateTime;
@ -28,7 +29,7 @@ trait TokenEntityTrait
protected $client;
/**
* Associate a scope with the token
* Associate a scope with the token.
*
* @param \League\OAuth2\Server\Entities\Interfaces\ScopeEntityInterface $scope
*/
@ -38,11 +39,11 @@ trait TokenEntityTrait
}
/**
* Get an associated scope by the scope's identifier
* Get an associated scope by the scope's identifier.
*
* @param string $identifier
*
* @return ScopeEntityInterface|null The scope or null if not found
* @return ScopeEntityInterface|null The scope or null if not found
*/
public function getScopeWithIdentifier($identifier)
{
@ -50,7 +51,8 @@ trait TokenEntityTrait
}
/**
* Return an array of scopes associated with the token
* Return an array of scopes associated with the token.
*
* @return ScopeEntityInterface[]
*/
public function getScopes()
@ -59,7 +61,8 @@ trait TokenEntityTrait
}
/**
* Get the token's expiry date time
* Get the token's expiry date time.
*
* @return DateTime
*/
public function getExpiryDateTime()
@ -68,7 +71,7 @@ trait TokenEntityTrait
}
/**
* Set the date time when the token expires
* Set the date time when the token expires.
*
* @param DateTime $dateTime
*/
@ -78,7 +81,7 @@ trait TokenEntityTrait
}
/**
* Set the identifier of the user associated with the token
* Set the identifier of the user associated with the token.
*
* @param string|int $identifier The identifier of the user
*/
@ -88,7 +91,8 @@ trait TokenEntityTrait
}
/**
* Get the token user's identifier
* Get the token user's identifier.
*
* @return string|int
*/
public function getUserIdentifier()
@ -97,7 +101,8 @@ trait TokenEntityTrait
}
/**
* Get the client that the token was issued to
* Get the client that the token was issued to.
*
* @return ClientEntityInterface
*/
public function getClient()
@ -106,7 +111,7 @@ trait TokenEntityTrait
}
/**
* Set the client that the token was issued to
* Set the client that the token was issued to.
*
* @param \League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface $client
*/
@ -117,6 +122,7 @@ trait TokenEntityTrait
/**
* Has the token expired?
*
* @return bool
*/
public function isExpired()

View File

@ -30,17 +30,18 @@ class OAuthServerException extends \Exception
private $redirectUri;
/**
* Throw a new exception
* Throw a new exception.
*
* @param string $message Error message
* @param int $code Error code
* @param string $errorType Error type
* @param int $httpStatusCode HTTP status code to send (default = 400)
* @param null|string $hint A helper hint
* @param null|string $redirectUri A HTTP URI to redirect the user back to
*/
public function __construct($message, $errorType, $httpStatusCode = 400, $hint = null, $redirectUri = null)
public function __construct($message, $code, $errorType, $httpStatusCode = 400, $hint = null, $redirectUri = null)
{
parent::__construct($message);
parent::__construct($message, $code);
$this->httpStatusCode = $httpStatusCode;
$this->errorType = $errorType;
$this->hint = $hint;
@ -48,125 +49,89 @@ class OAuthServerException extends \Exception
}
/**
* Invalid grant type error
*
* @param null|string $localizedError
* @param null|string $localizedHint
* Invalid grant type error.
*
* @return static
*/
public static function invalidGrantType(
$localizedError = null,
$localizedHint = null
) {
$errorMessage = (is_null($localizedError))
? '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.'
: $localizedError;
$hint = (is_null($localizedHint))
? 'Check the `grant_type` parameter'
: $localizedHint;
public static function invalidGrantType()
{
$errorMessage = '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.';
$hint = 'Check the `grant_type` parameter';
return new static($errorMessage, 'invalid_grant', 400, $hint);
return new static($errorMessage, 1, 'invalid_grant', 400, $hint);
}
/**
* Unsupported grant type error
*
* @param null|string $localizedError
* @param null|string $localizedHint
* Unsupported grant type error.
*
* @return static
*/
public static function unsupportedGrantType(
$localizedError = null,
$localizedHint = null
) {
$errorMessage = (is_null($localizedError))
? 'The authorization grant type is not supported by the authorization server.'
: $localizedError;
$hint = (is_null($localizedHint))
? 'Check the `grant_type` parameter'
: $localizedHint;
public static function unsupportedGrantType()
{
$errorMessage = 'The authorization grant type is not supported by the authorization server.';
$hint = 'Check the `grant_type` parameter';
return new static($errorMessage, 'unsupported_grant_type', 400, $hint);
return new static($errorMessage, 2, 'unsupported_grant_type', 400, $hint);
}
/**
* Invalid request error
* Invalid request error.
*
* @param string $parameter The invalid parameter
* @param null|string $localizedError
* @param null|string $localizedHint
* @param string|null $hint
*
* @return static
*/
public static function invalidRequest(
$parameter,
$localizedError = null,
$localizedHint = null
) {
$errorMessage = (is_null($localizedError))
? 'The request is missing a required parameter, includes an invalid parameter value, ' .
'includes a parameter more than once, or is otherwise malformed.'
: $localizedError;
$hint = (is_null($localizedHint))
? sprintf('Check the `%s` parameter', $parameter)
: sprintf($localizedHint, $parameter);
return new static($errorMessage, 'invalid_request', 400, $hint);
}
/**
* Invalid client error
*
* @param null|string $localizedError
*
* @return static
*/
public static function invalidClient($localizedError = null)
public static function invalidRequest($parameter, $hint = null)
{
$errorMessage = (is_null($localizedError))
? 'Client authentication failed'
: $localizedError;
$errorMessage = 'The request is missing a required parameter, includes an invalid parameter value, ' .
'includes a parameter more than once, or is otherwise malformed.';
$hint = ($hint === null) ? sprintf('Check the `%s` parameter', $parameter) : $hint;
return new static($errorMessage, 'invalid_client', 401);
return new static($errorMessage, 3, 'invalid_request', 400, $hint);
}
/**
* Invalid scope error
*
* @param string $scope The bad scope
* @param null|string $localizedError A localized error message
* @param null|string $localizedHint A localized error hint
* @param null|string $redirectUri A HTTP URI to redirect the user back to
* Invalid client error.
*
* @return static
*/
public static function invalidScope($scope, $localizedError = null, $localizedHint = null, $redirectUri = null)
public static function invalidClient()
{
$errorMessage = (is_null($localizedError))
? 'The requested scope is invalid, unknown, or malformed'
: $localizedError;
$hint = (is_null($localizedHint))
? sprintf('Check the `%s` scope', $scope)
: sprintf($localizedHint, $scope);
$errorMessage = 'Client authentication failed';
return new static($errorMessage, 'invalid_scope', 400, $hint, $redirectUri);
return new static($errorMessage, 4, 'invalid_client', 401);
}
/**
* Invalid credentials error
* Invalid scope error.
*
* @param string $scope The bad scope
* @param null|string $redirectUri A HTTP URI to redirect the user back to
*
* @return static
*/
public static function invalidScope($scope, $redirectUri = null)
{
$errorMessage = 'The requested scope is invalid, unknown, or malformed';
$hint = sprintf('Check the `%s` scope', $scope);
return new static($errorMessage, 5, 'invalid_scope', 400, $hint, $redirectUri);
}
/**
* Invalid credentials error.
*
* @return static
*/
public static function invalidCredentials()
{
return new static('The user credentials were incorrect.', 'invalid_credentials', 401);
return new static('The user credentials were incorrect.', 6, 'invalid_credentials', 401);
}
/**
* Server error
* Server error.
*
* @param $hint
*
@ -176,26 +141,27 @@ class OAuthServerException extends \Exception
{
return new static(
'The authorization server encountered an unexpected condition which prevented it from fulfilling'
. 'the request.',
. ' the request: ' . $hint,
7,
'server_error',
500,
$hint
500
);
}
/**
* Invalid refresh token
* Invalid refresh token.
*
* @param string|null $hint
*
* @return static
*/
public static function invalidRefreshToken($hint = null)
{
return new static('The refresh token is invalid.', 'invalid_request', 400, $hint);
return new static('The refresh token is invalid.', 8, 'invalid_request', 400, $hint);
}
/**
* Access denied
* Access denied.
*
* @param string|null $hint
* @param string|null $redirectUri
@ -206,6 +172,7 @@ class OAuthServerException extends \Exception
{
return new static(
'The resource owner or authorization server denied the request.',
9,
'access_denied',
401,
$hint,
@ -222,13 +189,15 @@ class OAuthServerException extends \Exception
}
/**
* Generate a HTTP response
* Generate a HTTP response.
*
* @param \Psr\Http\Message\ResponseInterface $response
* @param bool $useFragment True if errors should be in the URI fragment instead of
* query string
*
* @return \Psr\Http\Message\ResponseInterface
*/
public function generateHttpResponse(ResponseInterface $response = null)
public function generateHttpResponse(ResponseInterface $response = null, $useFragment = false)
{
if (!$response instanceof ResponseInterface) {
$response = new Response();
@ -238,7 +207,7 @@ class OAuthServerException extends \Exception
$payload = [
'error' => $this->errorType,
'message' => $this->getMessage()
'message' => $this->getMessage(),
];
if ($this->hint !== null) {
@ -249,9 +218,15 @@ class OAuthServerException extends \Exception
$redirectUri = new Uri($this->redirectUri);
parse_str($redirectUri->getQuery(), $redirectPayload);
$headers['Location'] = (string) $redirectUri->withQuery(http_build_query(
array_merge($redirectPayload, $payload)
));
if ($useFragment === true) {
$headers['Location'] = (string) $redirectUri->withFragment(http_build_query(
array_merge($redirectPayload, $payload)
));
} else {
$headers['Location'] = (string) $redirectUri->withQuery(http_build_query(
array_merge($redirectPayload, $payload)
));
}
}
foreach ($headers as $header => $content) {
@ -264,14 +239,14 @@ class OAuthServerException extends \Exception
}
/**
* Get all headers that have to be send with the error response
* Get all headers that have to be send with the error response.
*
* @return array Array with header values
*/
public function getHttpHeaders()
{
$headers = [
'Content-type' => 'application/json'
'Content-type' => 'application/json',
];
// Add "WWW-Authenticate" header
@ -312,7 +287,7 @@ class OAuthServerException extends \Exception
}
/**
* Returns the HTTP status code to send when the exceptions is output
* Returns the HTTP status code to send when the exceptions is output.
*
* @return int
*/
@ -320,4 +295,12 @@ class OAuthServerException extends \Exception
{
return $this->httpStatusCode;
}
/**
* @return null|string
*/
public function getHint()
{
return $this->hint;
}
}

View File

@ -1,14 +1,13 @@
<?php
/**
* OAuth 2.0 Abstract grant
* OAuth 2.0 Abstract grant.
*
* @package league/oauth2-server
* @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\Grant;
use League\Event\EmitterAwareTrait;
@ -21,13 +20,15 @@ use League\OAuth2\Server\Entities\RefreshTokenEntity;
use League\OAuth2\Server\Entities\ScopeEntity;
use League\OAuth2\Server\Exception\OAuthServerException;
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
use League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface;
use League\OAuth2\Server\Repositories\ClientRepositoryInterface;
use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;
use League\OAuth2\Server\Repositories\ScopeRepositoryInterface;
use League\OAuth2\Server\Utils\SecureKey;
use OAuth2ServerExamples\Repositories\AuthCodeRepository;
use Psr\Http\Message\ServerRequestInterface;
/**
* Abstract grant class
* Abstract grant class.
*/
abstract class AbstractGrant implements GrantTypeInterface
{
@ -35,13 +36,6 @@ abstract class AbstractGrant implements GrantTypeInterface
const SCOPE_DELIMITER_STRING = ' ';
/**
* Grant responds with
*
* @var string
*/
protected $respondsWith = 'token';
/**
* @var ServerRequestInterface
*/
@ -62,6 +56,16 @@ abstract class AbstractGrant implements GrantTypeInterface
*/
protected $scopeRepository;
/**
* @var \League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface
*/
private $authCodeRepository;
/**
* @var \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface
*/
private $refreshTokenRepository;
/**
* @var string
*/
@ -101,6 +105,22 @@ abstract class AbstractGrant implements GrantTypeInterface
$this->scopeRepository = $scopeRepository;
}
/**
* @param \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface $refreshTokenRepository
*/
public function setRefreshTokenRepository(RefreshTokenRepositoryInterface $refreshTokenRepository)
{
$this->refreshTokenRepository = $refreshTokenRepository;
}
/**
* @param \League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface $authCodeRepository
*/
public function setAuthCodeRepository(AuthCodeRepositoryInterface $authCodeRepository)
{
$this->authCodeRepository = $authCodeRepository;
}
/**
* @param string $pathToPrivateKey
*/
@ -118,7 +138,7 @@ abstract class AbstractGrant implements GrantTypeInterface
}
/**
* @inheritdoc
* {@inheritdoc}
*/
public function setEmitter(EmitterInterface $emitter = null)
{
@ -126,7 +146,7 @@ abstract class AbstractGrant implements GrantTypeInterface
}
/**
* @inheritdoc
* {@inheritdoc}
*/
public function setRefreshTokenTTL(\DateInterval $refreshTokenTTL)
{
@ -134,61 +154,69 @@ abstract class AbstractGrant implements GrantTypeInterface
}
/**
* {@inheritdoc}
* @return AuthCodeRepositoryInterface
*/
public function respondsWith()
protected function getAuthCodeRepository()
{
return $this->respondsWith;
return $this->authCodeRepository;
}
/**
* Validate the client
* @return RefreshTokenRepositoryInterface
*/
protected function getRefreshTokenRepository()
{
return $this->refreshTokenRepository;
}
/**
* Validate the client.
*
* @param \Psr\Http\Message\ServerRequestInterface $request
* @param bool $validateSecret
* @param bool $validateRedirectUri
*
* @throws \League\OAuth2\Server\Exception\OAuthServerException
*
* @return \League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface
* @throws \League\OAuth2\Server\Exception\OAuthServerException
*/
protected function validateClient(
ServerRequestInterface $request,
$validateSecret = true,
$validateRedirectUri = false
) {
protected function validateClient(ServerRequestInterface $request)
{
$clientId = $this->getRequestParameter(
'client_id',
$request,
$this->getServerParameter('PHP_AUTH_USER', $request)
);
if (is_null($clientId)) {
throw OAuthServerException::invalidRequest('client_id', null, '`%s` parameter is missing');
throw OAuthServerException::invalidRequest('client_id', '`%s` parameter is missing');
}
$client = $this->clientRepository->getClientEntity(
$clientId,
$this->getIdentifier()
);
if (!$client instanceof ClientEntityInterface) {
throw OAuthServerException::invalidClient();
}
// If the client is confidential require the client secret
$clientSecret = $this->getRequestParameter(
'client_secret',
$request,
$this->getServerParameter('PHP_AUTH_PW', $request)
);
if (is_null($clientSecret) && $validateSecret === true) {
throw OAuthServerException::invalidRequest('client_secret', null, '`%s` parameter is missing');
if ($client->canKeepASecret() && is_null($clientSecret)) {
throw OAuthServerException::invalidRequest('client_secret', '`%s` parameter is missing');
}
$redirectUri = $this->getRequestParameter('redirect_uri', $request, null);
if (is_null($redirectUri) && $validateRedirectUri === true) {
throw OAuthServerException::invalidRequest('redirect_uri', null, '`%s` parameter is missing');
}
$client = $this->clientRepository->getClientEntity(
$clientId,
$clientSecret,
$redirectUri,
$this->getIdentifier()
);
if (!$client instanceof ClientEntityInterface) {
if ($client->canKeepASecret() && $client->validateSecret($clientSecret) === false) {
$this->getEmitter()->emit(new Event('client.authentication.failed', $request));
throw OAuthServerException::invalidClient();
}
// If a redirect URI is provided ensure it matches what is pre-registered
$redirectUri = $this->getRequestParameter('redirect_uri', $request, null);
if ($redirectUri !== null && (strcmp($client->getRedirectUri(), $redirectUri) !== 0)) {
throw OAuthServerException::invalidClient();
}
@ -196,15 +224,15 @@ abstract class AbstractGrant implements GrantTypeInterface
}
/**
* Validate scopes in the request
* Validate scopes in the request.
*
* @param \Psr\Http\Message\ServerRequestInterface $request
* @param \League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface $client
* @param string $redirectUri
*
* @return \League\OAuth2\Server\Entities\ScopeEntity[]
*
* @throws \League\OAuth2\Server\Exception\OAuthServerException
*
* @return \League\OAuth2\Server\Entities\ScopeEntity[]
*/
public function validateScopes(
ServerRequestInterface $request,
@ -228,7 +256,7 @@ abstract class AbstractGrant implements GrantTypeInterface
);
if (($scope instanceof ScopeEntity) === false) {
throw OAuthServerException::invalidScope($scopeItem, null, null, $redirectUri);
throw OAuthServerException::invalidScope($scopeItem, $redirectUri);
}
$scopes[] = $scope;
@ -294,7 +322,7 @@ abstract class AbstractGrant implements GrantTypeInterface
}
/**
* Issue an access token
* Issue an access token.
*
* @param \DateInterval $tokenTTL
* @param \League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface $client
@ -310,20 +338,27 @@ abstract class AbstractGrant implements GrantTypeInterface
array $scopes = []
) {
$accessToken = new AccessTokenEntity();
$accessToken->setIdentifier(SecureKey::generate());
$accessToken->setIdentifier($this->generateUniqueIdentifier());
$accessToken->setExpiryDateTime((new \DateTime())->add($tokenTTL));
$accessToken->setClient($client);
$accessToken->setUserIdentifier($userIdentifier);
foreach ($scopes as $scope) {
if (is_string($scope)) {
$s = new ScopeEntity();
$s->setIdentifier($scope);
$scope = $s;
}
$accessToken->addScope($scope);
}
$this->accessTokenRepository->persistNewAccessToken($accessToken);
return $accessToken;
}
/**
* Issue an auth code
* Issue an auth code.
*
* @param \DateInterval $tokenTTL
* @param \League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface $client
@ -331,8 +366,9 @@ abstract class AbstractGrant implements GrantTypeInterface
* @param string $redirectUri
* @param array $scopes
*
* @return \League\OAuth2\Server\Entities\AuthCodeEntity
* @throws \League\OAuth2\Server\Exception\OAuthServerException
*
* @return \League\OAuth2\Server\Entities\AuthCodeEntity
*/
protected function issueAuthCode(
\DateInterval $tokenTTL,
@ -342,7 +378,7 @@ abstract class AbstractGrant implements GrantTypeInterface
array $scopes = []
) {
$authCode = new AuthCodeEntity();
$authCode->setIdentifier(SecureKey::generate());
$authCode->setIdentifier($this->generateUniqueIdentifier());
$authCode->setExpiryDateTime((new \DateTime())->add($tokenTTL));
$authCode->setClient($client);
$authCode->setUserIdentifier($userIdentifier);
@ -352,6 +388,8 @@ abstract class AbstractGrant implements GrantTypeInterface
$authCode->addScope($scope);
}
$this->authCodeRepository->persistNewAuthCode($authCode);
return $authCode;
}
@ -363,21 +401,46 @@ abstract class AbstractGrant implements GrantTypeInterface
protected function issueRefreshToken(AccessTokenEntity $accessToken)
{
$refreshToken = new RefreshTokenEntity();
$refreshToken->setIdentifier(SecureKey::generate());
$refreshToken->setIdentifier($this->generateUniqueIdentifier());
$refreshToken->setExpiryDateTime((new \DateTime())->add($this->refreshTokenTTL));
$refreshToken->setAccessToken($accessToken);
$this->refreshTokenRepository->persistNewRefreshToken($refreshToken);
return $refreshToken;
}
/**
* @inheritdoc
* Generate a new unique identifier.
*
* @param int $length
*
* @throws \League\OAuth2\Server\Exception\OAuthServerException
*
* @return string
*/
protected function generateUniqueIdentifier($length = 40)
{
try {
return bin2hex(random_bytes($length));
// @codeCoverageIgnoreStart
} catch (\TypeError $e) {
throw OAuthServerException::serverError('An unexpected error has occurred');
} catch (\Error $e) {
throw OAuthServerException::serverError('An unexpected error has occurred');
} catch (\Exception $e) {
// If you get this message, the CSPRNG failed hard.
throw OAuthServerException::serverError('Could not generate a random string');
}
// @codeCoverageIgnoreEnd
}
/**
* {@inheritdoc}
*/
public function canRespondToRequest(ServerRequestInterface $request)
{
return (
isset($request->getParsedBody()['grant_type'])
&& $request->getParsedBody()['grant_type'] === $this->getIdentifier()
);
return isset($request->getParsedBody()['grant_type'])
&& $request->getParsedBody()['grant_type'] === $this->getIdentifier();
}
}

View File

@ -3,6 +3,7 @@
namespace League\OAuth2\Server\Grant;
use DateInterval;
use League\Event\Event;
use League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface;
use League\OAuth2\Server\Entities\Interfaces\UserEntityInterface;
use League\OAuth2\Server\Exception\OAuthServerException;
@ -12,7 +13,6 @@ use League\OAuth2\Server\Repositories\UserRepositoryInterface;
use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface;
use League\OAuth2\Server\Utils\KeyCrypt;
use League\Plates\Engine;
use League\Event\Event;
use Psr\Http\Message\ServerRequestInterface;
use Zend\Diactoros\Response;
use Zend\Diactoros\Uri;
@ -23,10 +23,6 @@ class AuthCodeGrant extends AbstractGrant
* @var \DateInterval
*/
private $authCodeTTL;
/**
* @var \League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface
*/
private $authCodeRepository;
/**
* @var \League\OAuth2\Server\Repositories\UserRepositoryInterface
@ -43,11 +39,6 @@ class AuthCodeGrant extends AbstractGrant
*/
private $pathToAuthorizeTemplate;
/**
* @var \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface
*/
private $refreshTokenRepository;
/**
* @param \League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface $authCodeRepository
* @param \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface $refreshTokenRepository
@ -64,27 +55,35 @@ class AuthCodeGrant extends AbstractGrant
$pathToLoginTemplate = null,
$pathToAuthorizeTemplate = null
) {
$this->authCodeRepository = $authCodeRepository;
$this->refreshTokenRepository = $refreshTokenRepository;
$this->setAuthCodeRepository($authCodeRepository);
$this->setRefreshTokenRepository($refreshTokenRepository);
$this->userRepository = $userRepository;
$this->authCodeTTL = $authCodeTTL;
$this->pathToLoginTemplate = ($pathToLoginTemplate === null)
? __DIR__ . '/../ResponseTypes/DefaultTemplates/login_user.php'
: $this->pathToLoginTemplate;
$this->pathToAuthorizeTemplate = ($pathToLoginTemplate === null)
? __DIR__ . '/../ResponseTypes/DefaultTemplates/authorize_client.php'
: $this->pathToAuthorizeTemplate;
$this->refreshTokenTTL = new \DateInterval('P1M');
$this->pathToLoginTemplate = __DIR__ . '/../ResponseTypes/DefaultTemplates/login_user';
if ($pathToLoginTemplate !== null) {
$this->pathToLoginTemplate = (substr($pathToLoginTemplate, -4) === '.php')
? substr($pathToLoginTemplate, 0, -4)
: $pathToLoginTemplate;
}
$this->pathToAuthorizeTemplate = __DIR__ . '/../ResponseTypes/DefaultTemplates/authorize_client';
if ($pathToAuthorizeTemplate !== null) {
$this->pathToAuthorizeTemplate = (substr($pathToAuthorizeTemplate, -4) === '.php')
? substr($pathToAuthorizeTemplate, 0, -4)
: $pathToAuthorizeTemplate;
}
}
/**
* Respond to an authorization request
* Respond to an authorization request.
*
* @param \Psr\Http\Message\ServerRequestInterface $request
*
* @return \Psr\Http\Message\ResponseInterface
* @throws \League\OAuth2\Server\Exception\OAuthServerException
*
* @return \Psr\Http\Message\ResponseInterface
*/
protected function respondToAuthorizationRequest(
ServerRequestInterface $request
@ -95,28 +94,26 @@ class AuthCodeGrant extends AbstractGrant
$this->getServerParameter('PHP_AUTH_USER', $request)
);
if (is_null($clientId)) {
throw OAuthServerException::invalidRequest('client_id', null, '`%s` parameter is missing');
}
$redirectUri = $this->getQueryStringParameter('redirect_uri', $request, null);
if (is_null($redirectUri)) {
throw OAuthServerException::invalidRequest('redirect_uri', null, '`%s` parameter is missing');
throw OAuthServerException::invalidRequest('client_id');
}
$client = $this->clientRepository->getClientEntity(
$clientId,
null,
$redirectUri,
$this->getIdentifier()
);
if ($client instanceof ClientEntityInterface === false) {
$this->emitter->emit(new Event('client.authentication.failed', $request));
$this->getEmitter()->emit(new Event('client.authentication.failed', $request));
throw OAuthServerException::invalidClient();
}
$scopes = $this->validateScopes($request, $client, $redirectUri);
$redirectUriParameter = $this->getQueryStringParameter('redirect_uri', $request, $client->getRedirectUri());
if ($redirectUriParameter !== $client->getRedirectUri()) {
throw OAuthServerException::invalidClient();
}
$scopes = $this->validateScopes($request, $client, $client->getRedirectUri());
$queryString = http_build_query($request->getQueryParams());
$postbackUri = new Uri(
sprintf(
@ -168,8 +165,9 @@ class AuthCodeGrant extends AbstractGrant
// The user hasn't logged in yet so show a login form
if ($userId === null) {
$engine = new Engine(dirname($this->pathToLoginTemplate));
$pathParts = explode(DIRECTORY_SEPARATOR, $this->pathToLoginTemplate);
$html = $engine->render(
'login_user',
end($pathParts),
[
'error' => $loginError,
'postback_uri' => (string) $postbackUri->withQuery($queryString),
@ -179,12 +177,12 @@ class AuthCodeGrant extends AbstractGrant
return new Response\HtmlResponse($html);
}
// The user hasn't approved the client yet so show an authorize form
if ($userId !== null && $userHasApprovedClient === null) {
$engine = new Engine(dirname($this->pathToAuthorizeTemplate));
$pathParts = explode(DIRECTORY_SEPARATOR, $this->pathToAuthorizeTemplate);
$html = $engine->render(
'authorize_client',
end($pathParts),
[
'client' => $client,
'scopes' => $scopes,
@ -210,14 +208,16 @@ class AuthCodeGrant extends AbstractGrant
);
}
$stateParameter = $this->getQueryStringParameter('state', $request);
$redirectUri = new Uri($redirectUri);
// The user has either approved or denied the client, so redirect them back
$redirectUri = new Uri($client->getRedirectUri());
parse_str($redirectUri->getQuery(), $redirectPayload);
$stateParameter = $this->getQueryStringParameter('state', $request);
if ($stateParameter !== null) {
$redirectPayload['state'] = $stateParameter;
}
// THe user approved the client, redirect them back with an auth code
if ($userHasApprovedClient === true) {
$authCode = $this->issueAuthCode(
$this->authCodeTTL,
@ -226,12 +226,12 @@ class AuthCodeGrant extends AbstractGrant
$redirectUri,
$scopes
);
$this->authCodeRepository->persistNewAuthCode($authCode);
$redirectPayload['code'] = KeyCrypt::encrypt(
json_encode(
[
'client_id' => $authCode->getClient()->getIdentifier(),
'redirect_uri' => $authCode->getRedirectUri(),
'auth_code_id' => $authCode->getIdentifier(),
'scopes' => $authCode->getScopes(),
'user_id' => $authCode->getUserIdentifier(),
@ -244,25 +244,34 @@ class AuthCodeGrant extends AbstractGrant
return new Response\RedirectResponse($redirectUri->withQuery(http_build_query($redirectPayload)));
}
// The user denied the client, redirect them back with an error
$exception = OAuthServerException::accessDenied('The user denied the request', (string) $redirectUri);
return $exception->generateHttpResponse();
}
/**
* Respond to an access token request
* Respond to an access token request.
*
* @param \Psr\Http\Message\ServerRequestInterface $request
* @param \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface $responseType
* @param \DateInterval $accessTokenTTL
*
* @return \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface
* @throws \League\OAuth2\Server\Exception\OAuthServerException
*
* @return \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface
*/
protected function respondToAccessTokenRequest(
ServerRequestInterface $request,
ResponseTypeInterface $responseType,
DateInterval $accessTokenTTL
) {
// The redirect URI is required in this request
$redirectUri = $this->getRequestParameter('redirect_uri', $request, null);
if (is_null($redirectUri)) {
throw OAuthServerException::invalidRequest('redirect_uri');
}
// Validate request
$client = $this->validateClient($request);
$encryptedAuthCode = $this->getRequestParameter('code', $request, null);
@ -278,15 +287,19 @@ class AuthCodeGrant extends AbstractGrant
throw OAuthServerException::invalidRequest('code', 'Authorization code has expired');
}
if ($this->authCodeRepository->isAuthCodeRevoked($authCodePayload->auth_code_id) === true) {
if ($this->getAuthCodeRepository()->isAuthCodeRevoked($authCodePayload->auth_code_id) === true) {
throw OAuthServerException::invalidRequest('code', 'Authorization code has been revoked');
}
if ($authCodePayload->client_id !== $client->getIdentifier()) {
throw OAuthServerException::invalidRequest('code', 'Authorization code was not issued to this client');
}
if ($authCodePayload->redirect_uri !== $redirectUri) {
throw OAuthServerException::invalidRequest('redirect_uri', 'Invalid redirect URI');
}
} catch (\LogicException $e) {
throw OAuthServerException::invalidRequest('code', null, 'Cannot decrypt the authorization code');
throw OAuthServerException::invalidRequest('code', 'Cannot decrypt the authorization code');
}
// Issue and persist access + refresh tokens
@ -297,8 +310,6 @@ class AuthCodeGrant extends AbstractGrant
$authCodePayload->scopes
);
$refreshToken = $this->issueRefreshToken($accessToken);
$this->accessTokenRepository->persistNewAccessToken($accessToken);
$this->refreshTokenRepository->persistNewRefreshToken($refreshToken);
// Inject tokens into response type
$responseType->setAccessToken($accessToken);
@ -308,21 +319,20 @@ class AuthCodeGrant extends AbstractGrant
}
/**
* @inheritdoc
* {@inheritdoc}
*/
public function canRespondToRequest(ServerRequestInterface $request)
{
return (
return
(
isset($request->getQueryParams()['response_type'])
&& $request->getQueryParams()['response_type'] === 'code'
&& isset($request->getQueryParams()['client_id'])
) || (parent::canRespondToRequest($request))
);
) || (parent::canRespondToRequest($request));
}
/**
* Return the grant identifier that can be used in matching up requests
* Return the grant identifier that can be used in matching up requests.
*
* @return string
*/
@ -332,7 +342,7 @@ class AuthCodeGrant extends AbstractGrant
}
/**
* @inheritdoc
* {@inheritdoc}
*/
public function respondToRequest(
ServerRequestInterface $request,
@ -340,18 +350,12 @@ class AuthCodeGrant extends AbstractGrant
\DateInterval $accessTokenTTL
) {
if (
isset($request->getQueryParams()['response_type'])
array_key_exists('response_type', $request->getQueryParams())
&& $request->getQueryParams()['response_type'] === 'code'
&& isset($request->getQueryParams()['client_id'])
) {
return $this->respondToAuthorizationRequest($request);
} elseif (
isset($request->getParsedBody()['grant_type'])
&& $request->getParsedBody()['grant_type'] === 'authorization_code'
) {
return $this->respondToAccessTokenRequest($request, $responseType, $accessTokenTTL);
} else {
throw OAuthServerException::serverError('respondToRequest() should not have been called');
}
return $this->respondToAccessTokenRequest($request, $responseType, $accessTokenTTL);
}
}

View File

@ -1,26 +1,25 @@
<?php
/**
* OAuth 2.0 Client credentials grant
* OAuth 2.0 Client credentials grant.
*
* @package league/oauth2-server
* @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\Grant;
use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface;
use Psr\Http\Message\ServerRequestInterface;
/**
* Client credentials grant class
* Client credentials grant class.
*/
class ClientCredentialsGrant extends AbstractGrant
{
/**
* @inheritdoc
* {@inheritdoc}
*/
public function respondToRequest(
ServerRequestInterface $request,
@ -33,7 +32,6 @@ class ClientCredentialsGrant extends AbstractGrant
// Issue and persist access token
$accessToken = $this->issueAccessToken($accessTokenTTL, $client, $client->getIdentifier(), $scopes);
$this->accessTokenRepository->persistNewAccessToken($accessToken);
// Inject access token into response type
$responseType->setAccessToken($accessToken);
@ -42,7 +40,7 @@ class ClientCredentialsGrant extends AbstractGrant
}
/**
* @inheritdoc
* {@inheritdoc}
*/
public function getIdentifier()
{

View File

@ -1,14 +1,13 @@
<?php
/**
* OAuth 2.0 Grant type interface
* OAuth 2.0 Grant type interface.
*
* @package league/oauth2-server
* @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\Grant;
use League\Event\EmitterAwareInterface;
@ -19,33 +18,26 @@ use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface;
use Psr\Http\Message\ServerRequestInterface;
/**
* Grant type interface
* Grant type interface.
*/
interface GrantTypeInterface extends EmitterAwareInterface
{
/**
* Set refresh token TTL
* Set refresh token TTL.
*
* @param \DateInterval $refreshTokenTTL
*/
public function setRefreshTokenTTL(\DateInterval $refreshTokenTTL);
/**
* Return the grant identifier that can be used in matching up requests
* Return the grant identifier that can be used in matching up requests.
*
* @return string
*/
public function getIdentifier();
/**
* Details what the grant responds with
*
* @return string
*/
public function respondsWith();
/**
* Respond to an incoming request
* Respond to an incoming request.
*
* @param \Psr\Http\Message\ServerRequestInterface $request
* @param \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface $responseType
@ -69,40 +61,40 @@ interface GrantTypeInterface extends EmitterAwareInterface
*
* @param \Psr\Http\Message\ServerRequestInterface $request
*
* @return boolean
* @return bool
*/
public function canRespondToRequest(ServerRequestInterface $request);
/**
* Set the client repository
* Set the client repository.
*
* @param \League\OAuth2\Server\Repositories\ClientRepositoryInterface $clientRepository
*/
public function setClientRepository(ClientRepositoryInterface $clientRepository);
/**
* Set the access token repository
* Set the access token repository.
*
* @param \League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface $accessTokenRepository
*/
public function setAccessTokenRepository(AccessTokenRepositoryInterface $accessTokenRepository);
/**
* Set the scope repository
* Set the scope repository.
*
* @param \League\OAuth2\Server\Repositories\ScopeRepositoryInterface $scopeRepository
*/
public function setScopeRepository(ScopeRepositoryInterface $scopeRepository);
/**
* Set the path to the private key
* Set the path to the private key.
*
* @param string $pathToPrivateKey
*/
public function setPathToPrivateKey($pathToPrivateKey);
/**
* Set the path to the public key
* Set the path to the public key.
*
* @param string $pathToPublicKey
*/

241
src/Grant/ImplicitGrant.php Normal file
View File

@ -0,0 +1,241 @@
<?php
namespace League\OAuth2\Server\Grant;
use League\Event\Event;
use League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface;
use League\OAuth2\Server\Entities\Interfaces\UserEntityInterface;
use League\OAuth2\Server\Exception\OAuthServerException;
use League\OAuth2\Server\Repositories\UserRepositoryInterface;
use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface;
use League\OAuth2\Server\Utils\KeyCrypt;
use League\Plates\Engine;
use Psr\Http\Message\ServerRequestInterface;
use Zend\Diactoros\Response;
use Zend\Diactoros\Uri;
class ImplicitGrant extends AbstractGrant
{
/**
* @var \League\OAuth2\Server\Repositories\UserRepositoryInterface
*/
private $userRepository;
/**
* @var null|string
*/
private $pathToLoginTemplate;
/**
* @var null|string
*/
private $pathToAuthorizeTemplate;
/**
* @param \League\OAuth2\Server\Repositories\UserRepositoryInterface $userRepository
* @param string|null $pathToLoginTemplate
* @param string|null $pathToAuthorizeTemplate
*/
public function __construct(
UserRepositoryInterface $userRepository,
$pathToLoginTemplate = null,
$pathToAuthorizeTemplate = null
) {
$this->userRepository = $userRepository;
$this->refreshTokenTTL = new \DateInterval('P1M');
$this->pathToLoginTemplate = __DIR__ . '/../ResponseTypes/DefaultTemplates/login_user';
if ($pathToLoginTemplate !== null) {
$this->pathToLoginTemplate = (substr($pathToLoginTemplate, -4) === '.php')
? substr($pathToLoginTemplate, 0, -4)
: $pathToLoginTemplate;
}
$this->pathToAuthorizeTemplate = __DIR__ . '/../ResponseTypes/DefaultTemplates/authorize_client';
if ($pathToAuthorizeTemplate !== null) {
$this->pathToAuthorizeTemplate = (substr($pathToAuthorizeTemplate, -4) === '.php')
? substr($pathToAuthorizeTemplate, 0, -4)
: $pathToAuthorizeTemplate;
}
}
/**
* {@inheritdoc}
*/
public function canRespondToRequest(ServerRequestInterface $request)
{
return (array_key_exists('response_type', $request->getQueryParams())
&& $request->getQueryParams()['response_type'] === 'token');
}
/**
* Return the grant identifier that can be used in matching up requests.
*
* @return string
*/
public function getIdentifier()
{
return 'implicit';
}
/**
* {@inheritdoc}
*/
public function respondToRequest(
ServerRequestInterface $request,
ResponseTypeInterface $responseType,
\DateInterval $accessTokenTTL
) {
$clientId = $this->getQueryStringParameter(
'client_id',
$request,
$this->getServerParameter('PHP_AUTH_USER', $request)
);
if (is_null($clientId)) {
throw OAuthServerException::invalidRequest('client_id');
}
$client = $this->clientRepository->getClientEntity(
$clientId,
$this->getIdentifier()
);
if ($client instanceof ClientEntityInterface === false) {
$this->getEmitter()->emit(new Event('client.authentication.failed', $request));
throw OAuthServerException::invalidClient();
}
$redirectUriParameter = $this->getQueryStringParameter('redirect_uri', $request, $client->getRedirectUri());
if ($redirectUriParameter !== $client->getRedirectUri()) {
$this->getEmitter()->emit(new Event('client.authentication.failed', $request));
throw OAuthServerException::invalidClient();
}
$scopes = $this->validateScopes($request, $client, $client->getRedirectUri());
$queryString = http_build_query($request->getQueryParams());
$postbackUri = new Uri(
sprintf(
'//%s%s',
$request->getServerParams()['HTTP_HOST'],
$request->getServerParams()['REQUEST_URI']
)
);
$userId = null;
$userHasApprovedClient = null;
if ($this->getRequestParameter('action', $request, null) !== null) {
$userHasApprovedClient = ($this->getRequestParameter('action', $request) === 'approve');
}
// Check if the user has been authenticated
$oauthCookie = $this->getCookieParameter('oauth_authorize_request', $request, null);
if ($oauthCookie !== null) {
try {
$oauthCookiePayload = json_decode(KeyCrypt::decrypt($oauthCookie, $this->pathToPublicKey));
if (is_object($oauthCookiePayload)) {
$userId = $oauthCookiePayload->user_id;
}
} catch (\LogicException $e) {
throw OAuthServerException::serverError($e->getMessage());
}
}
// The username + password might be available in $_POST
$usernameParameter = $this->getRequestParameter('username', $request, null);
$passwordParameter = $this->getRequestParameter('password', $request, null);
$loginError = null;
// Assert if the user has logged in already
if ($userId === null && $usernameParameter !== null && $passwordParameter !== null) {
$userEntity = $this->userRepository->getUserEntityByUserCredentials(
$usernameParameter,
$passwordParameter
);
if ($userEntity instanceof UserEntityInterface) {
$userId = $userEntity->getIdentifier();
} else {
$loginError = 'Incorrect username or password';
}
}
// The user hasn't logged in yet so show a login form
if ($userId === null) {
$engine = new Engine(dirname($this->pathToLoginTemplate));
$pathParts = explode(DIRECTORY_SEPARATOR, $this->pathToLoginTemplate);
$html = $engine->render(
end($pathParts),
[
'error' => $loginError,
'postback_uri' => (string) $postbackUri->withQuery($queryString),
]
);
return new Response\HtmlResponse($html);
}
// The user hasn't approved the client yet so show an authorize form
if ($userId !== null && $userHasApprovedClient === null) {
$engine = new Engine(dirname($this->pathToAuthorizeTemplate));
$pathParts = explode(DIRECTORY_SEPARATOR, $this->pathToAuthorizeTemplate);
$html = $engine->render(
end($pathParts),
[
'client' => $client,
'scopes' => $scopes,
'postback_uri' => (string) $postbackUri->withQuery($queryString),
]
);
return new Response\HtmlResponse(
$html,
200,
[
'Set-Cookie' => sprintf(
'oauth_authorize_request=%s; Expires=%s',
urlencode(KeyCrypt::encrypt(
json_encode([
'user_id' => $userId,
]),
$this->pathToPrivateKey
)),
(new \DateTime())->add(new \DateInterval('PT5M'))->format('D, d M Y H:i:s e')
),
]
);
}
// The user has either approved or denied the client, so redirect them back
$redirectUri = new Uri($client->getRedirectUri());
$redirectPayload = [];
$stateParameter = $this->getQueryStringParameter('state', $request);
if ($stateParameter !== null) {
$redirectPayload['state'] = $stateParameter;
}
// THe user approved the client, redirect them back with an access token
if ($userHasApprovedClient === true) {
$accessToken = $this->issueAccessToken(
$accessTokenTTL,
$client,
$userId,
$scopes
);
$redirectPayload['access_token'] = $accessToken->convertToJWT($this->pathToPrivateKey);
$redirectPayload['token_type'] = 'bearer';
$redirectPayload['expires_in'] = time() - $accessToken->getExpiryDateTime()->getTimestamp();
return new Response\RedirectResponse($redirectUri->withFragment(http_build_query($redirectPayload)));
}
// The user denied the client, redirect them back with an error
$exception = OAuthServerException::accessDenied('The user denied the request', (string) $redirectUri);
return $exception->generateHttpResponse(null, true);
}
}

View File

@ -1,14 +1,13 @@
<?php
/**
* OAuth 2.0 Password grant
* OAuth 2.0 Password grant.
*
* @package league/oauth2-server
* @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\Grant;
use League\Event\Event;
@ -20,7 +19,7 @@ use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface;
use Psr\Http\Message\ServerRequestInterface;
/**
* Password grant class
* Password grant class.
*/
class PasswordGrant extends AbstractGrant
{
@ -29,11 +28,6 @@ class PasswordGrant extends AbstractGrant
*/
private $userRepository;
/**
* @var \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface
*/
private $refreshTokenRepository;
/**
* @param \League\OAuth2\Server\Repositories\UserRepositoryInterface $userRepository
* @param \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface $refreshTokenRepository
@ -43,13 +37,13 @@ class PasswordGrant extends AbstractGrant
RefreshTokenRepositoryInterface $refreshTokenRepository
) {
$this->userRepository = $userRepository;
$this->refreshTokenRepository = $refreshTokenRepository;
$this->setRefreshTokenRepository($refreshTokenRepository);
$this->refreshTokenTTL = new \DateInterval('P1M');
}
/**
* @inheritdoc
* {@inheritdoc}
*/
public function respondToRequest(
ServerRequestInterface $request,
@ -58,14 +52,12 @@ class PasswordGrant extends AbstractGrant
) {
// Validate request
$client = $this->validateClient($request);
$user = $this->validateUser($request);
$user = $this->validateUser($request);
$scopes = $this->validateScopes($request, $client);
// Issue and persist new tokens
$accessToken = $this->issueAccessToken($accessTokenTTL, $client, $user->getIdentifier(), $scopes);
$refreshToken = $this->issueRefreshToken($accessToken);
$this->accessTokenRepository->persistNewAccessToken($accessToken);
$this->refreshTokenRepository->persistNewRefreshToken($refreshToken);
// Inject tokens into response
$responseType->setAccessToken($accessToken);
@ -77,9 +69,9 @@ class PasswordGrant extends AbstractGrant
/**
* @param \Psr\Http\Message\ServerRequestInterface $request
*
* @return \League\OAuth2\Server\Entities\Interfaces\UserEntityInterface
*
* @throws \League\OAuth2\Server\Exception\OAuthServerException
*
* @return \League\OAuth2\Server\Entities\Interfaces\UserEntityInterface
*/
protected function validateUser(ServerRequestInterface $request)
{
@ -104,7 +96,7 @@ class PasswordGrant extends AbstractGrant
}
/**
* @inheritdoc
* {@inheritdoc}
*/
public function getIdentifier()
{

View File

@ -1,17 +1,17 @@
<?php
/**
* OAuth 2.0 Refresh token grant
* OAuth 2.0 Refresh token grant.
*
* @package league/oauth2-server
* @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\Grant;
use League\Event\Event;
use League\OAuth2\Server\Entities\ScopeEntity;
use League\OAuth2\Server\Exception\OAuthServerException;
use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;
use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface;
@ -19,27 +19,22 @@ use League\OAuth2\Server\Utils\KeyCrypt;
use Psr\Http\Message\ServerRequestInterface;
/**
* Refresh token grant
* Refresh token grant.
*/
class RefreshTokenGrant extends AbstractGrant
{
/**
* @var \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface
*/
private $refreshTokenRepository;
/**
* @param \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface $refreshTokenRepository
*/
public function __construct(RefreshTokenRepositoryInterface $refreshTokenRepository)
{
$this->refreshTokenRepository = $refreshTokenRepository;
$this->setRefreshTokenRepository($refreshTokenRepository);
$this->refreshTokenTTL = new \DateInterval('P1M');
}
/**
* @inheritdoc
* {@inheritdoc}
*/
public function respondToRequest(
ServerRequestInterface $request,
@ -47,13 +42,18 @@ class RefreshTokenGrant extends AbstractGrant
\DateInterval $accessTokenTTL
) {
// Validate request
$client = $this->validateClient($request);
$client = $this->validateClient($request);
$oldRefreshToken = $this->validateOldRefreshToken($request, $client->getIdentifier());
$scopes = $this->validateScopes($request, $client);
$scopes = $this->validateScopes($request, $client);
// If no new scopes are requested then give the access token the original session scopes
if (count($scopes) === 0) {
$scopes = $oldRefreshToken['scopes'];
$scopes = array_map(function ($scopeId) {
$scope = new ScopeEntity();
$scope->setIdentifier($scopeId);
return $scope;
}, $oldRefreshToken['scopes']);
} else {
// The OAuth spec says that a refreshed access token can have the original scopes or fewer so ensure
// the request doesn't include any new scopes
@ -68,13 +68,13 @@ class RefreshTokenGrant extends AbstractGrant
// Expire old tokens
$this->accessTokenRepository->revokeAccessToken($oldRefreshToken['access_token_id']);
$this->refreshTokenRepository->revokeRefreshToken($oldRefreshToken['refresh_token_id']);
$this->getRefreshTokenRepository()->revokeRefreshToken($oldRefreshToken['refresh_token_id']);
// Issue and persist new tokens
$accessToken = $this->issueAccessToken($accessTokenTTL, $client, $oldRefreshToken['user_id'], $scopes);
$refreshToken = $this->issueRefreshToken($accessToken);
$this->accessTokenRepository->persistNewAccessToken($accessToken);
$this->refreshTokenRepository->persistNewRefreshToken($refreshToken);
$this->getRefreshTokenRepository()->persistNewRefreshToken($refreshToken);
// Inject tokens into response
$responseType->setAccessToken($accessToken);
@ -87,9 +87,9 @@ class RefreshTokenGrant extends AbstractGrant
* @param \Psr\Http\Message\ServerRequestInterface $request
* @param string $clientId
*
* @return array
*
* @throws \League\OAuth2\Server\Exception\OAuthServerException
*
* @return array
*/
protected function validateOldRefreshToken(ServerRequestInterface $request, $clientId)
{
@ -120,7 +120,7 @@ class RefreshTokenGrant extends AbstractGrant
throw OAuthServerException::invalidRefreshToken('Token has expired');
}
if ($this->refreshTokenRepository->isRefreshTokenRevoked($refreshTokenData['refresh_token_id']) === true) {
if ($this->getRefreshTokenRepository()->isRefreshTokenRevoked($refreshTokenData['refresh_token_id']) === true) {
throw OAuthServerException::invalidRefreshToken('Token has been revoked');
}
@ -128,7 +128,7 @@ class RefreshTokenGrant extends AbstractGrant
}
/**
* @inheritdoc
* {@inheritdoc}
*/
public function getIdentifier()
{

View File

@ -1,39 +1,38 @@
<?php
/**
* OAuth 2.0 Access token storage interface
* OAuth 2.0 Access token storage interface.
*
* @package league/oauth2-server
* @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\Repositories;
use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface;
/**
* Access token interface
* Access token interface.
*/
interface AccessTokenRepositoryInterface extends RepositoryInterface
{
/**
* Persists a new access token to permanent storage
* Persists a new access token to permanent storage.
*
* @param \League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface $accessTokenEntity
*/
public function persistNewAccessToken(AccessTokenEntityInterface $accessTokenEntity);
/**
* Revoke an access token
* Revoke an access token.
*
* @param string $tokenId
*/
public function revokeAccessToken($tokenId);
/**
* Check if the access token has been revoked
* Check if the access token has been revoked.
*
* @param string $tokenId
*

View File

@ -1,39 +1,38 @@
<?php
/**
* OAuth 2.0 Auth code storage interface
* OAuth 2.0 Auth code storage interface.
*
* @package league/oauth2-server
* @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\Repositories;
use League\OAuth2\Server\Entities\Interfaces\AuthCodeEntityInterface;
/**
* Auth code storage interface
* Auth code storage interface.
*/
interface AuthCodeRepositoryInterface extends RepositoryInterface
{
/**
* Persists a new auth code to permanent storage
* Persists a new auth code to permanent storage.
*
* @param \League\OAuth2\Server\Entities\Interfaces\AuthCodeEntityInterface $authCodeEntity
*/
public function persistNewAuthCode(AuthCodeEntityInterface $authCodeEntity);
/**
* Revoke an auth code
* Revoke an auth code.
*
* @param string $codeId
*/
public function revokeAuthCode($codeId);
/**
* Check if the auth code has been revoked
* Check if the auth code has been revoked.
*
* @param string $codeId
*

View File

@ -1,30 +1,27 @@
<?php
/**
* OAuth 2.0 Client storage interface
* OAuth 2.0 Client storage interface.
*
* @package league/oauth2-server
* @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\Repositories;
/**
* Client storage interface
* Client storage interface.
*/
interface ClientRepositoryInterface extends RepositoryInterface
{
/**
* Get a client
* Get a client.
*
* @param string $grantType The grant type used
* @param string $clientIdentifier The client's identifier
* @param string|null $clientSecret The client's secret
* @param string|null $redirectUri The client's redirect URI
* @param string $clientIdentifier The client's identifier
* @param string $grantType The grant type used
*
* @return \League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface
*/
public function getClientEntity($grantType, $clientIdentifier, $clientSecret = null, $redirectUri = null);
public function getClientEntity($clientIdentifier, $grantType);
}

View File

@ -1,25 +1,24 @@
<?php
/**
* OAuth 2.0 MAC Token Interface
* OAuth 2.0 MAC Token Interface.
*
* @package league/oauth2-server
* @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\Storage;
use League\OAuth2\Server\Repositories\RepositoryInterface;
/**
* MacTokenInterface
* MacTokenInterface.
*/
interface MacTokenInterface extends RepositoryInterface
{
/**
* Create a MAC key linked to an access token
* Create a MAC key linked to an access token.
*
* @param string $macKey
* @param string $accessToken
@ -27,9 +26,9 @@ interface MacTokenInterface extends RepositoryInterface
public function persistMacTokenEntity($macKey, $accessToken);
/**
* Get a MAC key by access token
* Get a MAC key by access token.
*
* @param string $accessToken
* @param string $accessToken
*
* @return string
*/

View File

@ -1,39 +1,38 @@
<?php
/**
* OAuth 2.0 Refresh token storage interface
* OAuth 2.0 Refresh token storage interface.
*
* @package league/oauth2-server
* @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\Repositories;
use League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface;
/**
* Refresh token interface
* Refresh token interface.
*/
interface RefreshTokenRepositoryInterface extends RepositoryInterface
{
/**
* Create a new refresh token_name
* Create a new refresh token_name.
*
* @param \League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface $refreshTokenEntity
*/
public function persistNewRefreshToken(RefreshTokenEntityInterface $refreshTokenEntity);
/**
* Revoke the refresh token
* Revoke the refresh token.
*
* @param string $tokenId
*/
public function revokeRefreshToken($tokenId);
/**
* Check if the refresh token has been revoked
* Check if the refresh token has been revoked.
*
* @param string $tokenId
*

View File

@ -1,18 +1,17 @@
<?php
/**
* OAuth 2.0 Repository interface
* OAuth 2.0 Repository interface.
*
* @package league/oauth2-server
* @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\Repositories;
/**
* Repository interface
* Repository interface.
*/
interface RepositoryInterface
{

View File

@ -1,23 +1,22 @@
<?php
/**
* OAuth 2.0 Scope storage interface
* OAuth 2.0 Scope storage interface.
*
* @package league/oauth2-server
* @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\Repositories;
/**
* Scope interface
* Scope interface.
*/
interface ScopeRepositoryInterface extends RepositoryInterface
{
/**
* Return information about a scope
* Return information about a scope.
*
* @param string $identifier The scope identifier
* @param string $grantType The grant type used in the request

View File

@ -5,7 +5,7 @@ namespace League\OAuth2\Server\Repositories;
interface UserRepositoryInterface extends RepositoryInterface
{
/**
* Get a user entity
* Get a user entity.
*
* @param string $username
* @param string $password

View File

@ -1,14 +1,13 @@
<?php
/**
* OAuth 2.0 Abstract Response Type
* OAuth 2.0 Abstract Response Type.
*
* @package league/oauth2-server
* @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\ResponseTypes;
use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface;

View File

@ -1,19 +1,16 @@
<?php
/**
* OAuth 2.0 Bearer Token Type
* OAuth 2.0 Bearer Token Type.
*
* @package league/oauth2-server
* @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\ResponseTypes;
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Signer\Rsa\Sha256;
use League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface;
use League\OAuth2\Server\Exception\OAuthServerException;
@ -30,20 +27,11 @@ class BearerTokenResponse extends AbstractResponseType
{
$expireDateTime = $this->accessToken->getExpiryDateTime()->getTimestamp();
$jwtAccessToken = (new Builder())
->setAudience($this->accessToken->getClient()->getIdentifier())
->setId($this->accessToken->getIdentifier(), true)
->setIssuedAt(time())
->setNotBefore(time())
->setExpiration($expireDateTime)
->setSubject($this->accessToken->getUserIdentifier())
->set('scopes', $this->accessToken->getScopes())
->sign(new Sha256(), new Key($this->pathToPrivateKey))
->getToken();
$jwtAccessToken = $this->accessToken->convertToJWT($this->pathToPrivateKey);
$responseParams = [
'token_type' => 'Bearer',
'expires_in' => $expireDateTime - (new \DateTime)->getTimestamp(),
'expires_in' => $expireDateTime - (new \DateTime())->getTimestamp(),
'access_token' => (string) $jwtAccessToken,
];

View File

@ -1,14 +1,13 @@
<?php
/**
* OAuth 2.0 MAC Token Type
* OAuth 2.0 MAC Token Type.
*
* @package league/oauth2-server
* @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\TokenTypes;
use League\OAuth2\Server\Util\SecureKey;
@ -16,7 +15,7 @@ use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Component\HttpFoundation\Request;
/**
* MAC Token Type
* MAC Token Type.
*/
class MAC extends AbstractTokenType implements TokenTypeInterface
{
@ -29,11 +28,11 @@ class MAC extends AbstractTokenType implements TokenTypeInterface
$this->server->getMacStorage()->create($macKey, $this->getParam('access_token'));
$response = [
'access_token' => $this->getParam('access_token'),
'token_type' => 'mac',
'expires_in' => $this->getParam('expires_in'),
'mac_key' => $macKey,
'mac_algorithm' => 'hmac-sha-256',
'access_token' => $this->getParam('access_token'),
'token_type' => 'mac',
'expires_in' => $this->getParam('expires_in'),
'mac_key' => $macKey,
'mac_algorithm' => 'hmac-sha-256',
];
return $response;
@ -121,9 +120,11 @@ class MAC extends AbstractTokenType implements TokenTypeInterface
}
/**
* Prevent timing attack
* @param string $knownString
* @param string $userString
* Prevent timing attack.
*
* @param string $knownString
* @param string $userString
*
* @return bool
*/
private function hash_equals($knownString, $userString)

View File

@ -1,14 +1,13 @@
<?php
/**
* OAuth 2.0 Response Type Interface
* OAuth 2.0 Response Type Interface.
*
* @package league/oauth2-server
* @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\ResponseTypes;
use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface;
@ -30,7 +29,7 @@ interface ResponseTypeInterface
/**
* Determine the access token in the authorization header and append OAUth properties to the request
* as attributes
* as attributes.
*
* @param ServerRequestInterface $request
*

View File

@ -62,7 +62,7 @@ class Server implements EmitterAwareInterface
private $scopeRepository;
/**
* New server instance
* New server instance.
*
* @param \League\OAuth2\Server\Repositories\ClientRepositoryInterface $clientRepository
* @param \League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface $accessTokenRepository
@ -88,7 +88,7 @@ class Server implements EmitterAwareInterface
}
/**
* Enable a grant type on the server
* Enable a grant type on the server.
*
* @param \League\OAuth2\Server\Grant\GrantTypeInterface $grantType
* @param \DateInterval $accessTokenTTL
@ -108,13 +108,14 @@ class Server implements EmitterAwareInterface
}
/**
* Return an access token response
* Return an access token response.
*
* @param \Psr\Http\Message\ServerRequestInterface|null $request
* @param \Psr\Http\Message\ResponseInterface|null $response
*
* @return \Psr\Http\Message\ResponseInterface
* @throws \League\OAuth2\Server\Exception\OAuthServerException
*
* @return \Psr\Http\Message\ResponseInterface
*/
public function respondToRequest(ServerRequestInterface $request = null, ResponseInterface $response = null)
{
@ -149,13 +150,13 @@ class Server implements EmitterAwareInterface
}
/**
* Determine the access token validity
* Determine the access token validity.
*
* @param \Psr\Http\Message\ServerRequestInterface $request
*
* @return \Psr\Http\Message\ServerRequestInterface
*
* @throws \League\OAuth2\Server\Exception\OAuthServerException
*
* @return \Psr\Http\Message\ServerRequestInterface
*/
public function validateRequest(ServerRequestInterface $request)
{
@ -163,7 +164,7 @@ class Server implements EmitterAwareInterface
}
/**
* Get the token type that grants will return in the HTTP response
* Get the token type that grants will return in the HTTP response.
*
* @return ResponseTypeInterface
*/

View File

@ -1,20 +1,19 @@
<?php
/**
* Public/private key encryption
* Public/private key encryption.
*
* @package league/oauth2-server
* @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\Utils;
class KeyCrypt
{
/**
* Encrypt data with a private key
* Encrypt data with a private key.
*
* @param string $unencryptedData
* @param string $pathToPrivateKey
@ -36,7 +35,9 @@ class KeyCrypt
$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;
}
@ -46,7 +47,7 @@ class KeyCrypt
}
/**
* Decrypt data with a public key
* Decrypt data with a public key.
*
* @param string $encryptedData
* @param string $pathToPublicKey
@ -72,7 +73,9 @@ class KeyCrypt
$chunk = substr($encryptedData, 0, $chunkSize);
$encryptedData = substr($encryptedData, $chunkSize);
if (openssl_public_decrypt($chunk, $decrypted, $publicKey) === false) {
// @codeCoverageIgnoreStart
throw new \LogicException('Failed to decrypt data');
// @codeCoverageIgnoreEnd
}
$output .= $decrypted;
}

View File

@ -1,47 +0,0 @@
<?php
/**
* OAuth 2.0 Secure key generator
*
* @package php-loep/oauth2-server
* @author Alex Bilbie <hello@alexbilbie.com>
* @copyright Copyright (c) 2013 PHP League of Extraordinary Packages
* @license http://mit-license.org/
* @link http://github.com/php-loep/oauth2-server
*/
namespace League\OAuth2\Server\Utils;
use League\OAuth2\Server\Exception\OAuthServerException;
/**
* SecureKey class
*/
class SecureKey
{
/**
* Generate a new unique code
*
* @param integer $len Length of the generated code
*
* @return string
* @throws \League\OAuth2\Server\Exception\OAuthServerException
*/
public static function generate($len = 40)
{
try {
$string = random_bytes($len);
} catch (\TypeError $e) {
// Well, it's an integer, so this IS unexpected.
throw OAuthServerException::serverError("An unexpected error has occurred");
} catch (\Error $e) {
// This is also unexpected because 32 is a reasonable integer.
throw OAuthServerException::serverError("An unexpected error has occurred");
} catch (\Exception $e) {
// If you get this message, the CSPRNG failed hard.
throw OAuthServerException::serverError("Could not generate a random string. Is our OS secure?");
}
return bin2hex($string);
}
}

View File

@ -1,5 +1,5 @@
<?php
if (! @include_once __DIR__.'/../../vendor/autoload.php') {
if (!@include_once __DIR__ . '/../vendor/autoload.php') {
exit("You must set up the project dependencies, run the following commands:\n> wget http://getcomposer.org/composer.phar\n> php composer.phar install\n");
}

View File

@ -0,0 +1,388 @@
<?php
namespace LeagueTests\Grant;
use League\Event\Emitter;
use League\OAuth2\Server\Entities\AccessTokenEntity;
use League\OAuth2\Server\Entities\ClientEntity;
use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface;
use League\OAuth2\Server\Entities\Interfaces\AuthCodeEntityInterface;
use League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface;
use League\OAuth2\Server\Entities\ScopeEntity;
use League\OAuth2\Server\Grant\AbstractGrant;
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
use League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface;
use League\OAuth2\Server\Repositories\ClientRepositoryInterface;
use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;
use League\OAuth2\Server\Repositories\ScopeRepositoryInterface;
use Zend\Diactoros\ServerRequest;
class AbstractGrantTest extends \PHPUnit_Framework_TestCase
{
public function testGetSet()
{
/** @var AbstractGrant $grantMock */
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
$grantMock->setPathToPrivateKey('./private.key');
$grantMock->setPathToPublicKey('./public.key');
$grantMock->setEmitter(new Emitter());
}
public function testValidateClientPublic()
{
$client = new ClientEntity();
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
/** @var AbstractGrant $grantMock */
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
$grantMock->setClientRepository($clientRepositoryMock);
$abstractGrantReflection = new \ReflectionClass($grantMock);
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withParsedBody(
[
'client_id' => 'foo',
]
);
$validateClientMethod = $abstractGrantReflection->getMethod('validateClient');
$validateClientMethod->setAccessible(true);
$result = $validateClientMethod->invoke($grantMock, $serverRequest, true, true);
$this->assertEquals($client, $result);
}
public function testValidateClientConfidential()
{
$client = new ClientEntity();
$client->setSecret('bar');
$client->setRedirectUri('http://foo/bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
/** @var AbstractGrant $grantMock */
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
$grantMock->setClientRepository($clientRepositoryMock);
$abstractGrantReflection = new \ReflectionClass($grantMock);
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withParsedBody(
[
'client_id' => 'foo',
'client_secret' => 'bar',
'redirect_uri' => 'http://foo/bar',
]
);
$validateClientMethod = $abstractGrantReflection->getMethod('validateClient');
$validateClientMethod->setAccessible(true);
$result = $validateClientMethod->invoke($grantMock, $serverRequest, true, true);
$this->assertEquals($client, $result);
}
/**
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
*/
public function testValidateClientMissingClientId()
{
$client = new ClientEntity();
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
/** @var AbstractGrant $grantMock */
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
$grantMock->setClientRepository($clientRepositoryMock);
$abstractGrantReflection = new \ReflectionClass($grantMock);
$serverRequest = new ServerRequest();
$validateClientMethod = $abstractGrantReflection->getMethod('validateClient');
$validateClientMethod->setAccessible(true);
$validateClientMethod->invoke($grantMock, $serverRequest, true, true);
}
/**
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
*/
public function testValidateClientMissingClientSecret()
{
$client = new ClientEntity();
$client->setSecret('bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
/** @var AbstractGrant $grantMock */
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
$grantMock->setClientRepository($clientRepositoryMock);
$abstractGrantReflection = new \ReflectionClass($grantMock);
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withParsedBody([
'client_id' => 'foo',
]);
$validateClientMethod = $abstractGrantReflection->getMethod('validateClient');
$validateClientMethod->setAccessible(true);
$validateClientMethod->invoke($grantMock, $serverRequest, true, true);
}
/**
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
*/
public function testValidateClientInvalidClientSecret()
{
$client = new ClientEntity();
$client->setSecret('bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
/** @var AbstractGrant $grantMock */
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
$grantMock->setClientRepository($clientRepositoryMock);
$abstractGrantReflection = new \ReflectionClass($grantMock);
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withParsedBody([
'client_id' => 'foo',
'client_secret' => 'foo',
]);
$validateClientMethod = $abstractGrantReflection->getMethod('validateClient');
$validateClientMethod->setAccessible(true);
$validateClientMethod->invoke($grantMock, $serverRequest, true, true);
}
/**
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
*/
public function testValidateClientInvalidRedirectUri()
{
$client = new ClientEntity();
$client->setRedirectUri('http://foo/bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
/** @var AbstractGrant $grantMock */
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
$grantMock->setClientRepository($clientRepositoryMock);
$abstractGrantReflection = new \ReflectionClass($grantMock);
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withParsedBody([
'client_id' => 'foo',
'redirect_uri' => 'http://bar/foo',
]);
$validateClientMethod = $abstractGrantReflection->getMethod('validateClient');
$validateClientMethod->setAccessible(true);
$validateClientMethod->invoke($grantMock, $serverRequest, true, true);
}
/**
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
*/
public function testValidateClientBadClient()
{
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn(null);
/** @var AbstractGrant $grantMock */
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
$grantMock->setClientRepository($clientRepositoryMock);
$abstractGrantReflection = new \ReflectionClass($grantMock);
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withParsedBody([
'client_id' => 'foo',
'client_secret' => 'bar',
]);
$validateClientMethod = $abstractGrantReflection->getMethod('validateClient');
$validateClientMethod->setAccessible(true);
$validateClientMethod->invoke($grantMock, $serverRequest, true);
}
public function testCanRespondToRequest()
{
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
$grantMock->method('getIdentifier')->willReturn('foobar');
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withParsedBody([
'grant_type' => 'foobar',
]);
$this->assertTrue($grantMock->canRespondToRequest($serverRequest));
}
public function testIssueRefreshToken()
{
$refreshTokenRepoMock = $this->getMock(RefreshTokenRepositoryInterface::class);
/** @var AbstractGrant $grantMock */
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
$grantMock->setRefreshTokenTTL(new \DateInterval('PT1M'));
$grantMock->setRefreshTokenRepository($refreshTokenRepoMock);
$abstractGrantReflection = new \ReflectionClass($grantMock);
$issueRefreshTokenMethod = $abstractGrantReflection->getMethod('issueRefreshToken');
$issueRefreshTokenMethod->setAccessible(true);
$accessToken = new AccessTokenEntity();
/** @var RefreshTokenEntityInterface $refreshToken */
$refreshToken = $issueRefreshTokenMethod->invoke($grantMock, $accessToken);
$this->assertTrue($refreshToken instanceof RefreshTokenEntityInterface);
$this->assertFalse($refreshToken->isExpired());
$this->assertEquals($accessToken, $refreshToken->getAccessToken());
}
public function testIssueAccessToken()
{
$accessTokenRepoMock = $this->getMock(AccessTokenRepositoryInterface::class);
/** @var AbstractGrant $grantMock */
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
$grantMock->setAccessTokenRepository($accessTokenRepoMock);
$abstractGrantReflection = new \ReflectionClass($grantMock);
$issueAccessTokenMethod = $abstractGrantReflection->getMethod('issueAccessToken');
$issueAccessTokenMethod->setAccessible(true);
/** @var AccessTokenEntityInterface $accessToken */
$accessToken = $issueAccessTokenMethod->invoke(
$grantMock,
new \DateInterval('PT1H'),
new ClientEntity(),
123,
[new ScopeEntity()]
);
$this->assertTrue($accessToken instanceof AccessTokenEntityInterface);
$this->assertFalse($accessToken->isExpired());
}
public function testIssueAuthCode()
{
$authCodeRepoMock = $this->getMock(AuthCodeRepositoryInterface::class);
/** @var AbstractGrant $grantMock */
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
$grantMock->setAuthCodeRepository($authCodeRepoMock);
$abstractGrantReflection = new \ReflectionClass($grantMock);
$issueAuthCodeMethod = $abstractGrantReflection->getMethod('issueAuthCode');
$issueAuthCodeMethod->setAccessible(true);
$this->assertTrue(
$issueAuthCodeMethod->invoke(
$grantMock,
new \DateInterval('PT1H'),
new ClientEntity(),
123,
'http://foo/bar',
[new ScopeEntity()]
) instanceof AuthCodeEntityInterface
);
}
public function testGetCookieParameter()
{
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
$grantMock->method('getIdentifier')->willReturn('foobar');
$abstractGrantReflection = new \ReflectionClass($grantMock);
$method = $abstractGrantReflection->getMethod('getCookieParameter');
$method->setAccessible(true);
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withCookieParams([
'foo' => 'bar',
]);
$this->assertEquals('bar', $method->invoke($grantMock, 'foo', $serverRequest));
$this->assertEquals('foo', $method->invoke($grantMock, 'bar', $serverRequest, 'foo'));
}
public function testGetQueryStringParameter()
{
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
$grantMock->method('getIdentifier')->willReturn('foobar');
$abstractGrantReflection = new \ReflectionClass($grantMock);
$method = $abstractGrantReflection->getMethod('getQueryStringParameter');
$method->setAccessible(true);
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withQueryParams([
'foo' => 'bar',
]);
$this->assertEquals('bar', $method->invoke($grantMock, 'foo', $serverRequest));
$this->assertEquals('foo', $method->invoke($grantMock, 'bar', $serverRequest, 'foo'));
}
public function testValidateScopes()
{
$scope = new ScopeEntity();
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
$scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scope);
/** @var AbstractGrant $grantMock */
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
$grantMock->setScopeRepository($scopeRepositoryMock);
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withParsedBody(
[
'scope' => 'basic ',
]
);
$this->assertEquals([$scope], $grantMock->validateScopes($serverRequest, new ClientEntity()));
}
/**
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
*/
public function testValidateScopesBadScope()
{
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
$scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn(null);
/** @var AbstractGrant $grantMock */
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
$grantMock->setScopeRepository($scopeRepositoryMock);
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withParsedBody(
[
'scope' => 'basic ',
]
);
$grantMock->validateScopes($serverRequest, new ClientEntity());
}
public function testGenerateUniqueIdentifier()
{
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
$abstractGrantReflection = new \ReflectionClass($grantMock);
$method = $abstractGrantReflection->getMethod('generateUniqueIdentifier');
$method->setAccessible(true);
$this->assertTrue(is_string($method->invoke($grantMock)));
}
}

View File

@ -0,0 +1,981 @@
<?php
namespace LeagueTests\Grant;
use League\OAuth2\Server\Entities\ClientEntity;
use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface;
use League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface;
use League\OAuth2\Server\Exception\OAuthServerException;
use League\OAuth2\Server\Grant\AuthCodeGrant;
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
use League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface;
use League\OAuth2\Server\Repositories\ClientRepositoryInterface;
use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;
use League\OAuth2\Server\Repositories\UserRepositoryInterface;
use League\OAuth2\Server\Utils\KeyCrypt;
use LeagueTests\Stubs\StubResponseType;
use LeagueTests\Stubs\UserEntity;
use Psr\Http\Message\ResponseInterface;
use Zend\Diactoros\ServerRequest;
class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
{
public function testGetIdentifier()
{
$grant = new AuthCodeGrant(
$this->getMock(AuthCodeRepositoryInterface::class),
$this->getMock(RefreshTokenRepositoryInterface::class),
$this->getMock(UserRepositoryInterface::class),
new \DateInterval('PT10M'),
'foo/bar.php',
'foo/bar.php'
);
$this->assertEquals('authorization_code', $grant->getIdentifier());
}
public function testCanRespondToRequest()
{
$grant = new AuthCodeGrant(
$this->getMock(AuthCodeRepositoryInterface::class),
$this->getMock(RefreshTokenRepositoryInterface::class),
$this->getMock(UserRepositoryInterface::class),
new \DateInterval('PT10M')
);
$request = new ServerRequest(
[],
[],
null,
null,
'php://input',
$headers = [],
$cookies = [],
$queryParams = [
'response_type' => 'code',
'client_id' => 'foo',
]
);
$this->assertTrue($grant->canRespondToRequest($request));
}
public function testRespondToAuthorizationRequest()
{
$client = new ClientEntity();
$client->setRedirectUri('http://foo/bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
$userEntity = new UserEntity();
$userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity);
$grant = new AuthCodeGrant(
$this->getMock(AuthCodeRepositoryInterface::class),
$this->getMock(RefreshTokenRepositoryInterface::class),
$userRepositoryMock,
new \DateInterval('PT10M'),
'',
''
);
$grant->setClientRepository($clientRepositoryMock);
$grant->setPathToPublicKey('file://' . __DIR__ . '/../Utils/public.key');
$grant->setPathToPrivateKey('file://' . __DIR__ . '/../Utils/private.key');
$request = new ServerRequest(
[
'HTTP_HOST' => 'auth-server.tld',
'REQUEST_URI' => '/authorize',
],
[],
null,
'POST',
'php://input',
[],
[
'oauth_authorize_request' => KeyCrypt::encrypt(
json_encode(['user_id' => 123]),
'file://' . __DIR__ . '/../Utils/private.key'
),
],
[
'response_type' => 'code',
'client_id' => 'foo',
'state' => 'foobar',
],
[
'username' => 'alex',
'password' => 'whisky',
'action' => 'approve',
]
);
$response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
$this->assertTrue($response instanceof ResponseInterface);
$this->assertTrue(strstr($response->getHeader('location')[0], 'http://foo/bar') !== false);
}
public function testRespondToAuthorizationRequestUserDenied()
{
$client = new ClientEntity();
$client->setRedirectUri('http://foo/bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
$userEntity = new UserEntity();
$userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity);
$grant = new AuthCodeGrant(
$this->getMock(AuthCodeRepositoryInterface::class),
$this->getMock(RefreshTokenRepositoryInterface::class),
$userRepositoryMock,
new \DateInterval('PT10M'),
'',
''
);
$grant->setClientRepository($clientRepositoryMock);
$grant->setPathToPublicKey('file://' . __DIR__ . '/../Utils/public.key');
$grant->setPathToPrivateKey('file://' . __DIR__ . '/../Utils/private.key');
$request = new ServerRequest(
[
'HTTP_HOST' => 'auth-server.tld',
'REQUEST_URI' => '/authorize',
],
[],
null,
'POST',
'php://input',
[],
[
'oauth_authorize_request' => KeyCrypt::encrypt(
json_encode(['user_id' => 123]),
'file://' . __DIR__ . '/../Utils/private.key'
),
],
[
'response_type' => 'code',
'client_id' => 'foo',
'state' => 'foobar',
],
[
'username' => 'alex',
'password' => 'whisky',
'action' => 'denied',
]
);
$response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
$this->assertTrue($response instanceof ResponseInterface);
$this->assertTrue(strstr($response->getHeader('location')[0], 'http://foo/bar') !== false);
$this->assertTrue(strstr($response->getHeader('location')[0], 'access_denied') !== false);
}
/**
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
* @expectedExceptionCode 3
*/
public function testRespondToAuthorizationRequestMissingClientId()
{
$client = new ClientEntity();
$client->setRedirectUri('http://foo/bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
$userEntity = new UserEntity();
$userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity);
$grant = new AuthCodeGrant(
$this->getMock(AuthCodeRepositoryInterface::class),
$this->getMock(RefreshTokenRepositoryInterface::class),
$userRepositoryMock,
new \DateInterval('PT10M'),
'',
''
);
$grant->setClientRepository($clientRepositoryMock);
$grant->setPathToPublicKey('file://' . __DIR__ . '/../Utils/public.key');
$grant->setPathToPrivateKey('file://' . __DIR__ . '/../Utils/private.key');
$request = new ServerRequest(
[
'HTTP_HOST' => 'auth-server.tld',
'REQUEST_URI' => '/authorize',
],
[],
null,
'POST',
'php://input',
[],
[
'oauth_authorize_request' => KeyCrypt::encrypt(
json_encode(['user_id' => 123]),
'file://' . __DIR__ . '/../Utils/private.key'
),
],
[
'response_type' => 'code',
],
[
'username' => 'alex',
'password' => 'whisky',
'action' => 'approve',
]
);
$response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
$this->assertTrue($response instanceof ResponseInterface);
}
public function testRespondToAuthorizationRequestBadClient()
{
$client = null;
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
$userEntity = new UserEntity();
$userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity);
$grant = new AuthCodeGrant(
$this->getMock(AuthCodeRepositoryInterface::class),
$this->getMock(RefreshTokenRepositoryInterface::class),
$userRepositoryMock,
new \DateInterval('PT10M')
);
$grant->setClientRepository($clientRepositoryMock);
$grant->setPathToPublicKey('file://' . __DIR__ . '/../Utils/public.key');
$grant->setPathToPrivateKey('file://' . __DIR__ . '/../Utils/private.key');
$request = new ServerRequest(
[
'HTTP_HOST' => 'auth-server.tld',
'REQUEST_URI' => '/authorize',
],
[],
null,
'POST',
'php://input',
[],
[
'oauth_authorize_request' => KeyCrypt::encrypt(
json_encode(['user_id' => 123]),
'file://' . __DIR__ . '/../Utils/private.key'
),
],
[
'response_type' => 'code',
'client_id' => 'foo',
],
[
'username' => 'alex',
'password' => 'whisky',
'action' => 'approve',
]
);
try {
/* @var StubResponseType $response */
$grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
} catch (OAuthServerException $e) {
$this->assertEquals($e->getMessage(), 'Client authentication failed');
}
}
public function testRespondToAuthorizationRequestBadRedirectUri()
{
$client = new ClientEntity();
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
$userEntity = new UserEntity();
$userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity);
$grant = new AuthCodeGrant(
$this->getMock(AuthCodeRepositoryInterface::class),
$this->getMock(RefreshTokenRepositoryInterface::class),
$userRepositoryMock,
new \DateInterval('PT10M')
);
$grant->setClientRepository($clientRepositoryMock);
$grant->setPathToPublicKey('file://' . __DIR__ . '/../Utils/public.key');
$grant->setPathToPrivateKey('file://' . __DIR__ . '/../Utils/private.key');
$request = new ServerRequest(
[
'HTTP_HOST' => 'auth-server.tld',
'REQUEST_URI' => '/authorize',
],
[],
null,
'POST',
'php://input',
[],
[
'oauth_authorize_request' => KeyCrypt::encrypt(
json_encode(['user_id' => 123]),
'file://' . __DIR__ . '/../Utils/private.key'
),
],
[
'response_type' => 'code',
'client_id' => 'foo',
'redirect_uri' => 'sdfsdf',
],
[
'username' => 'alex',
'password' => 'whisky',
'action' => 'approve',
]
);
try {
/* @var StubResponseType $response */
$grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
} catch (OAuthServerException $e) {
$this->assertEquals($e->getMessage(), 'Client authentication failed');
}
}
/**
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
* @expectedExceptionCode 7
*/
public function testRespondToAuthorizationRequestBadCookie()
{
$client = new ClientEntity();
$client->setRedirectUri('http://foo/bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
$userEntity = new UserEntity();
$userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity);
$grant = new AuthCodeGrant(
$this->getMock(AuthCodeRepositoryInterface::class),
$this->getMock(RefreshTokenRepositoryInterface::class),
$userRepositoryMock,
new \DateInterval('PT10M'),
'',
''
);
$grant->setClientRepository($clientRepositoryMock);
$grant->setPathToPublicKey('file://' . __DIR__ . '/../Utils/public.key');
$grant->setPathToPrivateKey('file://' . __DIR__ . '/../Utils/private.key');
$request = new ServerRequest(
[
'HTTP_HOST' => 'auth-server.tld',
'REQUEST_URI' => '/authorize',
],
[],
null,
'POST',
'php://input',
[],
[
'oauth_authorize_request' => 'blah',
],
[
'response_type' => 'code',
'client_id' => 'foo',
],
[
'username' => 'alex',
'password' => 'whisky',
'action' => 'approve',
]
);
$response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
$this->assertTrue($response instanceof ResponseInterface);
}
public function testRespondToAuthorizationRequestTryLogin()
{
$client = new ClientEntity();
$client->setRedirectUri('http://foo/bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
$userEntity = new UserEntity();
$userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity);
$grant = new AuthCodeGrant(
$this->getMock(AuthCodeRepositoryInterface::class),
$this->getMock(RefreshTokenRepositoryInterface::class),
$userRepositoryMock,
new \DateInterval('PT10M'),
'',
''
);
$grant->setClientRepository($clientRepositoryMock);
$grant->setPathToPublicKey('file://' . __DIR__ . '/../Utils/public.key');
$grant->setPathToPrivateKey('file://' . __DIR__ . '/../Utils/private.key');
$request = new ServerRequest(
[
'HTTP_HOST' => 'auth-server.tld',
'REQUEST_URI' => '/authorize',
],
[],
null,
'POST',
'php://input',
[],
[
'oauth_authorize_request' => KeyCrypt::encrypt(
json_encode(['user_id' => null]),
'file://' . __DIR__ . '/../Utils/private.key'
),
],
[
'response_type' => 'code',
'client_id' => 'foo',
],
[
'username' => 'alex',
'password' => 'whisky',
'action' => 'approve',
]
);
$response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
$this->assertTrue($response instanceof ResponseInterface);
$this->assertTrue(strstr($response->getHeader('location')[0], 'http://foo/bar') !== false);
}
public function testRespondToAuthorizationRequestShowLoginForm()
{
$client = new ClientEntity();
$client->setRedirectUri('http://foo/bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
$userEntity = null;
$userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity);
$grant = new AuthCodeGrant(
$this->getMock(AuthCodeRepositoryInterface::class),
$this->getMock(RefreshTokenRepositoryInterface::class),
$userRepositoryMock,
new \DateInterval('PT10M')
);
$grant->setClientRepository($clientRepositoryMock);
$grant->setPathToPublicKey('file://' . __DIR__ . '/../Utils/public.key');
$grant->setPathToPrivateKey('file://' . __DIR__ . '/../Utils/private.key');
$request = new ServerRequest(
[
'HTTP_HOST' => 'auth-server.tld',
'REQUEST_URI' => '/authorize',
],
[],
null,
'POST',
'php://input',
[],
[
'oauth_authorize_request' => KeyCrypt::encrypt(
json_encode(['user_id' => null]),
'file://' . __DIR__ . '/../Utils/private.key'
),
],
[
'response_type' => 'code',
'client_id' => 'foo',
],
[
'username' => 'alex',
'password' => 'whisky',
'action' => 'approve',
]
);
$response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
$this->assertTrue($response instanceof ResponseInterface);
$this->assertTrue(strstr($response->getHeader('content-type')[0], 'text/html') !== false);
$this->assertTrue(strstr($response->getBody()->getContents(), 'Incorrect username or password') !== false);
}
public function testRespondToAuthorizationRequestShowAuthorizeForm()
{
$client = new ClientEntity();
$client->setRedirectUri('http://foo/bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
$userEntity = new UserEntity();
$userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity);
$grant = new AuthCodeGrant(
$this->getMock(AuthCodeRepositoryInterface::class),
$this->getMock(RefreshTokenRepositoryInterface::class),
$userRepositoryMock,
new \DateInterval('PT10M')
);
$grant->setClientRepository($clientRepositoryMock);
$grant->setPathToPublicKey('file://' . __DIR__ . '/../Utils/public.key');
$grant->setPathToPrivateKey('file://' . __DIR__ . '/../Utils/private.key');
$request = new ServerRequest(
[
'HTTP_HOST' => 'auth-server.tld',
'REQUEST_URI' => '/authorize',
],
[],
null,
'POST',
'php://input',
[],
[
'oauth_authorize_request' => KeyCrypt::encrypt(
json_encode(['user_id' => 123]),
'file://' . __DIR__ . '/../Utils/private.key'
),
],
[
'response_type' => 'code',
'client_id' => 'foo',
],
[
'username' => 'alex',
'password' => 'whisky',
]
);
$response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
$this->assertTrue($response instanceof ResponseInterface);
$this->assertTrue(strstr($response->getHeader('set-cookie')[0], 'oauth_authorize_request') !== false);
}
public function testRespondToAccessTokenRequest()
{
$client = new ClientEntity();
$client->setIdentifier('foo');
$client->setRedirectUri('http://foo/bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
$userEntity = new UserEntity();
$userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity);
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
$refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
$refreshTokenRepositoryMock->method('persistNewRefreshToken')->willReturnSelf();
$grant = new AuthCodeGrant(
$this->getMock(AuthCodeRepositoryInterface::class),
$this->getMock(RefreshTokenRepositoryInterface::class),
$userRepositoryMock,
new \DateInterval('PT10M')
);
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPathToPublicKey('file://' . __DIR__ . '/../Utils/public.key');
$grant->setPathToPrivateKey('file://' . __DIR__ . '/../Utils/private.key');
$request = new ServerRequest(
[],
[],
null,
'POST',
'php://input',
[],
[],
[],
[
'grant_type' => 'authorization_code',
'client_id' => 'foo',
'redirect_uri' => 'http://foo/bar',
'code' => KeyCrypt::encrypt(
json_encode(
[
'auth_code_id' => uniqid(),
'expire_time' => time() + 3600,
'client_id' => 'foo',
'user_id' => 123,
'scopes' => ['foo'],
'redirect_uri' => 'http://foo/bar',
]
),
'file://' . __DIR__ . '/../Utils/private.key'
),
]
);
/** @var StubResponseType $response */
$response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
$this->assertTrue($response->getAccessToken() instanceof AccessTokenEntityInterface);
$this->assertTrue($response->getRefreshToken() instanceof RefreshTokenEntityInterface);
}
/**
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
* @expectedExceptionCode 3
*/
public function testRespondToAccessTokenRequestMissingRedirectUri()
{
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
$refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
$grant = new AuthCodeGrant(
$this->getMock(AuthCodeRepositoryInterface::class),
$this->getMock(RefreshTokenRepositoryInterface::class),
$userRepositoryMock,
new \DateInterval('PT10M')
);
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPathToPublicKey('file://' . __DIR__ . '/../Utils/public.key');
$grant->setPathToPrivateKey('file://' . __DIR__ . '/../Utils/private.key');
$request = new ServerRequest(
[],
[],
null,
'POST',
'php://input',
[],
[],
[],
[
'grant_type' => 'authorization_code',
]
);
/* @var StubResponseType $response */
$grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
}
/**
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
* @expectedExceptionCode 3
*/
public function testRespondToAccessTokenRequestMissingCode()
{
$client = new ClientEntity();
$client->setSecret('bar');
$client->setRedirectUri('http://foo/bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
$refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
$grant = new AuthCodeGrant(
$this->getMock(AuthCodeRepositoryInterface::class),
$this->getMock(RefreshTokenRepositoryInterface::class),
$userRepositoryMock,
new \DateInterval('PT10M')
);
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPathToPublicKey('file://' . __DIR__ . '/../Utils/public.key');
$grant->setPathToPrivateKey('file://' . __DIR__ . '/../Utils/private.key');
$request = new ServerRequest(
[],
[],
null,
'POST',
'php://input',
[],
[],
[],
[
'grant_type' => 'authorization_code',
'client_id' => 'foo',
'client_secret' => 'bar',
'redirect_uri' => 'http://foo/bar',
]
);
/* @var StubResponseType $response */
$grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
}
public function testRespondToAccessTokenRequestExpiredCode()
{
$client = new ClientEntity();
$client->setIdentifier('foo');
$client->setRedirectUri('http://foo/bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
$userEntity = new UserEntity();
$userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity);
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
$refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
$refreshTokenRepositoryMock->method('persistNewRefreshToken')->willReturnSelf();
$grant = new AuthCodeGrant(
$this->getMock(AuthCodeRepositoryInterface::class),
$this->getMock(RefreshTokenRepositoryInterface::class),
$userRepositoryMock,
new \DateInterval('PT10M')
);
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPathToPublicKey('file://' . __DIR__ . '/../Utils/public.key');
$grant->setPathToPrivateKey('file://' . __DIR__ . '/../Utils/private.key');
$request = new ServerRequest(
[],
[],
null,
'POST',
'php://input',
[],
[],
[],
[
'grant_type' => 'authorization_code',
'client_id' => 'foo',
'redirect_uri' => 'http://foo/bar',
'code' => KeyCrypt::encrypt(
json_encode(
[
'auth_code_id' => uniqid(),
'expire_time' => time() - 3600,
'client_id' => 'foo',
'user_id' => 123,
'scopes' => ['foo'],
'redirect_uri' => 'http://foo/bar',
]
),
'file://' . __DIR__ . '/../Utils/private.key'
),
]
);
try {
/* @var StubResponseType $response */
$grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
} catch (OAuthServerException $e) {
$this->assertEquals($e->getHint(), 'Authorization code has expired');
}
}
public function testRespondToAccessTokenRequestRevokedCode()
{
$client = new ClientEntity();
$client->setIdentifier('foo');
$client->setRedirectUri('http://foo/bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
$userEntity = new UserEntity();
$userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity);
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
$refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
$refreshTokenRepositoryMock->method('persistNewRefreshToken')->willReturnSelf();
$authCodeRepositoryMock = $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock();
$authCodeRepositoryMock->method('isAuthCodeRevoked')->willReturn(true);
$grant = new AuthCodeGrant(
$authCodeRepositoryMock,
$this->getMock(RefreshTokenRepositoryInterface::class),
$userRepositoryMock,
new \DateInterval('PT10M')
);
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPathToPublicKey('file://' . __DIR__ . '/../Utils/public.key');
$grant->setPathToPrivateKey('file://' . __DIR__ . '/../Utils/private.key');
$request = new ServerRequest(
[],
[],
null,
'POST',
'php://input',
[],
[],
[],
[
'grant_type' => 'authorization_code',
'client_id' => 'foo',
'redirect_uri' => 'http://foo/bar',
'code' => KeyCrypt::encrypt(
json_encode(
[
'auth_code_id' => uniqid(),
'expire_time' => time() + 3600,
'client_id' => 'foo',
'user_id' => 123,
'scopes' => ['foo'],
'redirect_uri' => 'http://foo/bar',
]
),
'file://' . __DIR__ . '/../Utils/private.key'
),
]
);
try {
/* @var StubResponseType $response */
$grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
} catch (OAuthServerException $e) {
$this->assertEquals($e->getHint(), 'Authorization code has been revoked');
}
}
public function testRespondToAccessTokenRequestClientMismatch()
{
$client = new ClientEntity();
$client->setIdentifier('foo');
$client->setRedirectUri('http://foo/bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
$userEntity = new UserEntity();
$userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity);
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
$refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
$refreshTokenRepositoryMock->method('persistNewRefreshToken')->willReturnSelf();
$grant = new AuthCodeGrant(
$this->getMock(AuthCodeRepositoryInterface::class),
$this->getMock(RefreshTokenRepositoryInterface::class),
$userRepositoryMock,
new \DateInterval('PT10M')
);
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPathToPublicKey('file://' . __DIR__ . '/../Utils/public.key');
$grant->setPathToPrivateKey('file://' . __DIR__ . '/../Utils/private.key');
$request = new ServerRequest(
[],
[],
null,
'POST',
'php://input',
[],
[],
[],
[
'grant_type' => 'authorization_code',
'client_id' => 'foo',
'redirect_uri' => 'http://foo/bar',
'code' => KeyCrypt::encrypt(
json_encode(
[
'auth_code_id' => uniqid(),
'expire_time' => time() + 3600,
'client_id' => 'bar',
'user_id' => 123,
'scopes' => ['foo'],
'redirect_uri' => 'http://foo/bar',
]
),
'file://' . __DIR__ . '/../Utils/private.key'
),
]
);
try {
/* @var StubResponseType $response */
$grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
} catch (OAuthServerException $e) {
$this->assertEquals($e->getHint(), 'Authorization code was not issued to this client');
}
}
public function testRespondToAccessTokenRequestBadCodeEncryption()
{
$client = new ClientEntity();
$client->setIdentifier('foo');
$client->setRedirectUri('http://foo/bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
$userEntity = new UserEntity();
$userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity);
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
$refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
$refreshTokenRepositoryMock->method('persistNewRefreshToken')->willReturnSelf();
$grant = new AuthCodeGrant(
$this->getMock(AuthCodeRepositoryInterface::class),
$this->getMock(RefreshTokenRepositoryInterface::class),
$userRepositoryMock,
new \DateInterval('PT10M')
);
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
$grant->setPathToPublicKey('file://' . __DIR__ . '/../Utils/public.key');
$grant->setPathToPrivateKey('file://' . __DIR__ . '/../Utils/private.key');
$request = new ServerRequest(
[],
[],
null,
'POST',
'php://input',
[],
[],
[],
[
'grant_type' => 'authorization_code',
'client_id' => 'foo',
'redirect_uri' => 'http://foo/bar',
'code' => 'sdfsfsd',
]
);
try {
/* @var StubResponseType $response */
$grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
} catch (OAuthServerException $e) {
$this->assertEquals($e->getHint(), 'Cannot decrypt the authorization code');
}
}
}

View File

@ -0,0 +1,48 @@
<?php
namespace LeagueTests\Grant;
use League\OAuth2\Server\Entities\ClientEntity;
use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface;
use League\OAuth2\Server\Grant\ClientCredentialsGrant;
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
use League\OAuth2\Server\Repositories\ClientRepositoryInterface;
use LeagueTests\Stubs\StubResponseType;
use Zend\Diactoros\ServerRequest;
class ClientCredentialsGrantTest extends \PHPUnit_Framework_TestCase
{
public function testGetIdentifier()
{
$grant = new ClientCredentialsGrant();
$this->assertEquals('client_credentials', $grant->getIdentifier());
}
public function testRespondToRequest()
{
$client = new ClientEntity();
$client->setSecret('bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
$grant = new ClientCredentialsGrant();
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withParsedBody(
[
'client_id' => 'foo',
'client_secret' => 'bar',
]
);
$responseType = new StubResponseType();
$grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
$this->assertTrue($responseType->getAccessToken() instanceof AccessTokenEntityInterface);
}
}

View File

@ -0,0 +1,165 @@
<?php
namespace LeagueTests\Grant;
use League\OAuth2\Server\Entities\ClientEntity;
use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface;
use League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface;
use League\OAuth2\Server\Grant\PasswordGrant;
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
use League\OAuth2\Server\Repositories\ClientRepositoryInterface;
use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;
use League\OAuth2\Server\Repositories\UserRepositoryInterface;
use LeagueTests\Stubs\StubResponseType;
use LeagueTests\Stubs\UserEntity;
use Zend\Diactoros\ServerRequest;
class PasswordGrantTest extends \PHPUnit_Framework_TestCase
{
public function testGetIdentifier()
{
$userRepositoryMock = $this->getMock(UserRepositoryInterface::class);
$refreshTokenRepositoryMock = $this->getMock(RefreshTokenRepositoryInterface::class);
$grant = new PasswordGrant($userRepositoryMock, $refreshTokenRepositoryMock);
$this->assertEquals('password', $grant->getIdentifier());
}
public function testRespondToRequest()
{
$client = new ClientEntity();
$client->setSecret('bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
$userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
$userEntity = new UserEntity();
$userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity);
$refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
$refreshTokenRepositoryMock->method('persistNewRefreshToken')->willReturnSelf();
$grant = new PasswordGrant($userRepositoryMock, $refreshTokenRepositoryMock);
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withParsedBody(
[
'client_id' => 'foo',
'client_secret' => 'bar',
'username' => 'foo',
'password' => 'bar',
]
);
$responseType = new StubResponseType();
$grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
$this->assertTrue($responseType->getAccessToken() instanceof AccessTokenEntityInterface);
$this->assertTrue($responseType->getRefreshToken() instanceof RefreshTokenEntityInterface);
}
/**
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
*/
public function testRespondToRequestMissingUsername()
{
$client = new ClientEntity();
$client->setSecret('bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
$userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
$refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
$grant = new PasswordGrant($userRepositoryMock, $refreshTokenRepositoryMock);
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withParsedBody(
[
'client_id' => 'foo',
'client_secret' => 'bar',
]
);
$responseType = new StubResponseType();
$grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
}
/**
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
*/
public function testRespondToRequestMissingPassword()
{
$client = new ClientEntity();
$client->setSecret('bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
$userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
$refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
$grant = new PasswordGrant($userRepositoryMock, $refreshTokenRepositoryMock);
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withParsedBody(
[
'client_id' => 'foo',
'client_secret' => 'bar',
'username' => 'alex',
]
);
$responseType = new StubResponseType();
$grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
}
/**
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
*/
public function testRespondToRequestBadCredentials()
{
$client = new ClientEntity();
$client->setSecret('bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
$userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
$userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn(null);
$refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
$grant = new PasswordGrant($userRepositoryMock, $refreshTokenRepositoryMock);
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withParsedBody(
[
'client_id' => 'foo',
'client_secret' => 'bar',
'username' => 'alex',
'password' => 'whisky',
]
);
$responseType = new StubResponseType();
$grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
}
}

View File

@ -0,0 +1,410 @@
<?php
namespace LeagueTests\Grant;
use League\OAuth2\Server\Entities\ClientEntity;
use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface;
use League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface;
use League\OAuth2\Server\Entities\ScopeEntity;
use League\OAuth2\Server\Grant\RefreshTokenGrant;
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\Utils\KeyCrypt;
use LeagueTests\Stubs\StubResponseType;
use Zend\Diactoros\ServerRequest;
class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
{
public function testGetIdentifier()
{
$refreshTokenRepositoryMock = $this->getMock(RefreshTokenRepositoryInterface::class);
$grant = new RefreshTokenGrant($refreshTokenRepositoryMock);
$this->assertEquals('refresh_token', $grant->getIdentifier());
}
public function testRespondToRequest()
{
$client = new ClientEntity();
$client->setIdentifier('foo');
$client->setSecret('bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$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->setPathToPublicKey('file://' . __DIR__ . '/../Utils/public.key');
$grant->setPathToPrivateKey('file://' . __DIR__ . '/../Utils/private.key');
$oldRefreshToken = KeyCrypt::encrypt(
json_encode(
[
'client_id' => 'foo',
'refresh_token_id' => 'zyxwvu',
'access_token_id' => 'abcdef',
'scopes' => ['foo'],
'user_id' => 123,
'expire_time' => time() + 3600,
]
),
'file://' . __DIR__ . '/../Utils/private.key'
);
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withParsedBody(
[
'client_id' => 'foo',
'client_secret' => 'bar',
'refresh_token' => $oldRefreshToken,
]
);
$responseType = new StubResponseType();
$grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
$this->assertTrue($responseType->getAccessToken() instanceof AccessTokenEntityInterface);
$this->assertTrue($responseType->getRefreshToken() instanceof RefreshTokenEntityInterface);
}
public function testRespondToReducedScopes()
{
$client = new ClientEntity();
$client->setIdentifier('foo');
$client->setSecret('bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
$refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
$refreshTokenRepositoryMock->method('persistNewRefreshToken')->willReturnSelf();
$scope = new ScopeEntity();
$scope->setIdentifier('foo');
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
$scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scope);
$grant = new RefreshTokenGrant($refreshTokenRepositoryMock);
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setPathToPublicKey('file://' . __DIR__ . '/../Utils/public.key');
$grant->setPathToPrivateKey('file://' . __DIR__ . '/../Utils/private.key');
$oldRefreshToken = KeyCrypt::encrypt(
json_encode(
[
'client_id' => 'foo',
'refresh_token_id' => 'zyxwvu',
'access_token_id' => 'abcdef',
'scopes' => ['foo', 'bar'],
'user_id' => 123,
'expire_time' => time() + 3600,
]
),
'file://' . __DIR__ . '/../Utils/private.key'
);
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withParsedBody(
[
'client_id' => 'foo',
'client_secret' => 'bar',
'refresh_token' => $oldRefreshToken,
'scope' => 'foo',
]
);
$responseType = new StubResponseType();
$grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
$this->assertTrue($responseType->getAccessToken() instanceof AccessTokenEntityInterface);
$this->assertTrue($responseType->getRefreshToken() instanceof RefreshTokenEntityInterface);
}
/**
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
* @expectedExceptionCode 5
*/
public function testRespondToUnexpectedScope()
{
$client = new ClientEntity();
$client->setIdentifier('foo');
$client->setSecret('bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
$refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
$refreshTokenRepositoryMock->method('persistNewRefreshToken')->willReturnSelf();
$scope = new ScopeEntity();
$scope->setIdentifier('foobar');
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
$scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scope);
$grant = new RefreshTokenGrant($refreshTokenRepositoryMock);
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setScopeRepository($scopeRepositoryMock);
$grant->setPathToPublicKey('file://' . __DIR__ . '/../Utils/public.key');
$grant->setPathToPrivateKey('file://' . __DIR__ . '/../Utils/private.key');
$oldRefreshToken = KeyCrypt::encrypt(
json_encode(
[
'client_id' => 'foo',
'refresh_token_id' => 'zyxwvu',
'access_token_id' => 'abcdef',
'scopes' => ['foo', 'bar'],
'user_id' => 123,
'expire_time' => time() + 3600,
]
),
'file://' . __DIR__ . '/../Utils/private.key'
);
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withParsedBody(
[
'client_id' => 'foo',
'client_secret' => 'bar',
'refresh_token' => $oldRefreshToken,
'scope' => 'foobar',
]
);
$responseType = new StubResponseType();
$grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
}
/**
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
* @expectedExceptionCode 3
*/
public function testRespondToRequestMissingOldToken()
{
$client = new ClientEntity();
$client->setIdentifier('foo');
$client->setSecret('bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
$refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
$grant = new RefreshTokenGrant($refreshTokenRepositoryMock);
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setPathToPublicKey('file://' . __DIR__ . '/../Utils/public.key');
$grant->setPathToPrivateKey('file://' . __DIR__ . '/../Utils/private.key');
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withParsedBody(
[
'client_id' => 'foo',
'client_secret' => 'bar',
]
);
$responseType = new StubResponseType();
$grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
}
/**
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
* @expectedExceptionCode 8
*/
public function testRespondToRequestInvalidOldToken()
{
$client = new ClientEntity();
$client->setIdentifier('foo');
$client->setSecret('bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
$refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
$grant = new RefreshTokenGrant($refreshTokenRepositoryMock);
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setPathToPublicKey('file://' . __DIR__ . '/../Utils/public.key');
$grant->setPathToPrivateKey('file://' . __DIR__ . '/../Utils/private.key');
$oldRefreshToken = 'foobar';
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withParsedBody(
[
'client_id' => 'foo',
'client_secret' => 'bar',
'refresh_token' => $oldRefreshToken,
]
);
$responseType = new StubResponseType();
$grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
}
/**
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
* @expectedExceptionCode 8
*/
public function testRespondToRequestClientMismatch()
{
$client = new ClientEntity();
$client->setIdentifier('foo');
$client->setSecret('bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$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->setPathToPublicKey('file://' . __DIR__ . '/../Utils/public.key');
$grant->setPathToPrivateKey('file://' . __DIR__ . '/../Utils/private.key');
$oldRefreshToken = KeyCrypt::encrypt(
json_encode(
[
'client_id' => 'bar',
'refresh_token_id' => 'zyxwvu',
'access_token_id' => 'abcdef',
'scopes' => ['foo'],
'user_id' => 123,
'expire_time' => time() + 3600,
]
),
'file://' . __DIR__ . '/../Utils/private.key'
);
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withParsedBody(
[
'client_id' => 'foo',
'client_secret' => 'bar',
'refresh_token' => $oldRefreshToken,
]
);
$responseType = new StubResponseType();
$grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
}
/**
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
* @expectedExceptionCode 8
*/
public function testRespondToRequestExpiredToken()
{
$client = new ClientEntity();
$client->setIdentifier('foo');
$client->setSecret('bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
$refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
$grant = new RefreshTokenGrant($refreshTokenRepositoryMock);
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setPathToPublicKey('file://' . __DIR__ . '/../Utils/public.key');
$grant->setPathToPrivateKey('file://' . __DIR__ . '/../Utils/private.key');
$oldRefreshToken = KeyCrypt::encrypt(
json_encode(
[
'client_id' => 'foo',
'refresh_token_id' => 'zyxwvu',
'access_token_id' => 'abcdef',
'scopes' => ['foo'],
'user_id' => 123,
'expire_time' => time() - 3600,
]
),
'file://' . __DIR__ . '/../Utils/private.key'
);
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withParsedBody(
[
'client_id' => 'foo',
'client_secret' => 'bar',
'refresh_token' => $oldRefreshToken,
]
);
$responseType = new StubResponseType();
$grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
}
/**
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
* @expectedExceptionCode 8
*/
public function testRespondToRequestRevokedToken()
{
$client = new ClientEntity();
$client->setIdentifier('foo');
$client->setSecret('bar');
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
$refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
$refreshTokenRepositoryMock->method('isRefreshTokenRevoked')->willReturn(true);
$grant = new RefreshTokenGrant($refreshTokenRepositoryMock);
$grant->setClientRepository($clientRepositoryMock);
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
$grant->setPathToPublicKey('file://' . __DIR__ . '/../Utils/public.key');
$grant->setPathToPrivateKey('file://' . __DIR__ . '/../Utils/private.key');
$oldRefreshToken = KeyCrypt::encrypt(
json_encode(
[
'client_id' => 'foo',
'refresh_token_id' => 'zyxwvu',
'access_token_id' => 'abcdef',
'scopes' => ['foo'],
'user_id' => 123,
'expire_time' => time() + 3600,
]
),
'file://' . __DIR__ . '/../Utils/private.key'
);
$serverRequest = new ServerRequest();
$serverRequest = $serverRequest->withParsedBody(
[
'client_id' => 'foo',
'client_secret' => 'bar',
'refresh_token' => $oldRefreshToken,
]
);
$responseType = new StubResponseType();
$grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
}
}

56
tests/ServerTest.php Normal file
View File

@ -0,0 +1,56 @@
<?php
namespace LeagueTests;
use League\OAuth2\Server\Entities\ClientEntity;
use League\OAuth2\Server\Grant\ClientCredentialsGrant;
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
use League\OAuth2\Server\Repositories\ClientRepositoryInterface;
use League\OAuth2\Server\Repositories\ScopeRepositoryInterface;
use League\OAuth2\Server\Server;
use LeagueTests\Stubs\StubResponseType;
use Psr\Http\Message\ResponseInterface;
class ServerTest extends \PHPUnit_Framework_TestCase
{
public function testRespondToRequestInvalidGrantType()
{
$server = new Server(
$this->getMock(ClientRepositoryInterface::class),
$this->getMock(AccessTokenRepositoryInterface::class),
$this->getMock(ScopeRepositoryInterface::class),
'',
'',
new StubResponseType()
);
$server->enableGrantType(new ClientCredentialsGrant(), new \DateInterval('PT1M'));
$response = $server->respondToRequest();
$this->assertTrue($response instanceof ResponseInterface);
$this->assertEquals(400, $response->getStatusCode());
}
public function testRespondToRequest()
{
$clientRepository = $this->getMock(ClientRepositoryInterface::class);
$clientRepository->method('getClientEntity')->willReturn(new ClientEntity());
$server = new Server(
$clientRepository,
$this->getMock(AccessTokenRepositoryInterface::class),
$this->getMock(ScopeRepositoryInterface::class),
'',
'',
new StubResponseType()
);
$server->enableGrantType(new ClientCredentialsGrant(), new \DateInterval('PT1M'));
$_POST['grant_type'] = 'client_credentials';
$_POST['client_id'] = 'foo';
$_POST['client_secret'] = 'bar';
$response = $server->respondToRequest();
$this->assertEquals(200, $response->getStatusCode());
}
}

View File

@ -0,0 +1,63 @@
<?php
namespace LeagueTests\Stubs;
use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface;
use League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface;
use League\OAuth2\Server\ResponseTypes\AbstractResponseType;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Zend\Diactoros\Response;
class StubResponseType extends AbstractResponseType
{
public function __construct()
{
}
public function getAccessToken()
{
return $this->accessToken;
}
public function getRefreshToken()
{
return $this->refreshToken;
}
/**
* @param \League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface $accessToken
*/
public function setAccessToken(AccessTokenEntityInterface $accessToken)
{
$this->accessToken = $accessToken;
}
/**
* @param \League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface $refreshToken
*/
public function setRefreshToken(RefreshTokenEntityInterface $refreshToken)
{
$this->refreshToken = $refreshToken;
}
/**
* @param ServerRequestInterface $request
*
* @return ServerRequestInterface
*/
public function determineAccessTokenInHeader(ServerRequestInterface $request)
{
// TODO: Implement determineAccessTokenInHeader() method.
}
/**
* @param ResponseInterface $response
*
* @return ResponseInterface
*/
public function generateHttpResponse(ResponseInterface $response)
{
return new Response();
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace LeagueTests\Stubs;
use League\OAuth2\Server\Entities\Interfaces\UserEntityInterface;
class UserEntity implements UserEntityInterface
{
public function getIdentifier()
{
return 123;
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace LeagueTests\Utils;
use League\OAuth2\Server\Utils\KeyCrypt;
class KeyCryptTest extends \PHPUnit_Framework_TestCase
{
public function testEncryptDecrypt()
{
$payload = 'alex loves whisky';
$encrypted = KeyCrypt::encrypt($payload, 'file://' . __DIR__ . '/private.key');
$plainText = KeyCrypt::decrypt($encrypted, 'file://' . __DIR__ . '/public.key');
$this->assertNotEquals($payload, $encrypted);
$this->assertEquals($payload, $plainText);
}
/**
* @expectedException \LogicException
*/
public function testBadPrivateKey()
{
KeyCrypt::encrypt('', 'file://' . __DIR__ . '/public.key');
}
/**
* @expectedException \LogicException
*/
public function testBadPublicKey()
{
KeyCrypt::decrypt('', 'file://' . __DIR__ . '/private.key');
}
}

15
tests/Utils/private.key Normal file
View File

@ -0,0 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQDOBcFjGUlo3BJ9zjwQLgAHn6Oy5Si0uB7MublTiPob8rWTiCE4
weAFqzPoAB07vB0t0f8c1R8rmwHMD5ljWPBgJ8FewtwAUzprOBcau6DWukd/TKxX
WeVLAl/NZxijI+jR5QDBYLNBtj1G4LBVHMmINd3ryCycbf9ac3rcC8zhrQIDAQAB
AoGADfOJ0wIlXHp6rhZHLvlOezWuSjEGfqZxP3/cMvH1rerTrPfs+AD5AKlFTJKl
aCQm/bFYy0ULZVKL3pu30Wh2bo1nh/wLuLSI9Nz3O8jqAP3z0i07SoRoQmb8fRnn
dwoDFqnk3uGqcOenheSqheIgl9vdW/3avhD6nkMKZGxPYwECQQDoSj/xHogEzMqB
1Z2E5H/exeE9GQ7+dGITRR2MSgo9WvcKdRhGaQ44dsnTmqiZWAfqAPJjTQIIA/Cn
YRRTeBbNAkEA4w0iEvCIygGQOAnWuvVzlh+pxIB+BTeGkbiBG7nkYYc9b6B/Tw1B
GWGRddBr/FIfPvy1X2ip/TBpH+9bHnE2YQJBAIbZw/EYhmIy+UUSW9WwSUNsoOu1
Rm0V53HEZ/jvaq5fxpa9j5AgoO7KlzROzp3m6wE/93cKV6mLkAO7ae9jAekCQQCf
B6DZIS6+RrAMACAt3SOzf8P6BYG/B7Ayusd7cw2ang4S9JiW9xKkw2kN2wj3t1F5
XalwBTAjTdgj7ROmU+ehAkEAkOyXKONGBoVfaixRHgBP6jIBSSPbB2Aosi0QAURX
6GOY7wOS1pCSntTOBQxV7wVjqFwYAR10MSxFSNfpJ7RkzA==
-----END RSA PRIVATE KEY-----

6
tests/Utils/public.key Normal file
View File

@ -0,0 +1,6 @@
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOBcFjGUlo3BJ9zjwQLgAHn6Oy
5Si0uB7MublTiPob8rWTiCE4weAFqzPoAB07vB0t0f8c1R8rmwHMD5ljWPBgJ8Fe
wtwAUzprOBcau6DWukd/TKxXWeVLAl/NZxijI+jR5QDBYLNBtj1G4LBVHMmINd3r
yCycbf9ac3rcC8zhrQIDAQAB
-----END PUBLIC KEY-----

View File

@ -1,2 +0,0 @@
<?php
// This is global bootstrap for autoloading

View File

View File

@ -1,10 +0,0 @@
<?php
namespace Codeception\Module;
// here you can define custom actions
// all public methods declared in helper class will be available in $I
class ApiHelper extends \Codeception\Module
{
}

View File

@ -1,8 +0,0 @@
class_name: ApiTester
modules:
enabled: [PhpBrowser, REST]
config:
PhpBrowser:
url: 'http://localhost:7777/'
REST:
url: 'http://localhost:7777/'

View File

@ -1,17 +0,0 @@
<?php
$I = new ApiTester($scenario);
$I->wantTo('get an access token using the client credentials grant');
$I->sendPOST(
'client_credentials.php/access_token',
[
'grant_type' => 'client_credentials',
'client_id' => 'myawesomeapp',
'client_secret' => 'abc123',
'scope' => 'basic'
]
);
$I->canSeeResponseCodeIs(200);
$I->canSeeResponseIsJson();
$I->seeResponseJsonMatchesJsonPath('$.token_type');
$I->seeResponseJsonMatchesJsonPath('$.expires_in');
$I->seeResponseJsonMatchesJsonPath('$.access_token');

View File

@ -1,17 +0,0 @@
<?php
$I = new ApiTester($scenario);
$I->wantTo('get an access token using the client credentials grant, invalid client id');
$I->sendPOST(
'client_credentials.php/access_token',
[
'grant_type' => 'client_credentials',
'client_id' => 'myawesomeapp-wrong',
'client_secret' => 'foobar'
]
);
$I->canSeeResponseCodeIs(401);
$I->canSeeResponseIsJson();
$I->seeResponseContainsJson([
'error' => 'invalid_client',
'message' => 'Client authentication failed.'
]);

View File

@ -1,17 +0,0 @@
<?php
$I = new ApiTester($scenario);
$I->wantTo('get an access token using the client credentials grant, invalid client secret');
$I->sendPOST(
'client_credentials.php/access_token',
[
'grant_type' => 'client_credentials',
'client_id' => 'myawesomeapp',
'client_secret' => 'foobar'
]
);
$I->canSeeResponseCodeIs(401);
$I->canSeeResponseIsJson();
$I->seeResponseContainsJson([
'error' => 'invalid_client',
'message' => 'Client authentication failed.'
]);

View File

@ -1,15 +0,0 @@
<?php
$I = new ApiTester($scenario);
$I->wantTo('get an access token using the client credentials grant, missing client id');
$I->sendPOST(
'client_credentials.php/access_token',
[
'grant_type' => 'client_credentials'
]
);
$I->canSeeResponseCodeIs(400);
$I->canSeeResponseIsJson();
$I->seeResponseContainsJson([
'error' => 'invalid_request',
'message' => 'The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Check the "client_id" parameter.'
]);

View File

@ -1,16 +0,0 @@
<?php
$I = new ApiTester($scenario);
$I->wantTo('get an access token using the client credentials grant, missing client secret');
$I->sendPOST(
'client_credentials.php/access_token',
[
'grant_type' => 'client_credentials',
'client_id' => 'myawesomeapp'
]
);
$I->canSeeResponseCodeIs(400);
$I->canSeeResponseIsJson();
$I->seeResponseContainsJson([
'error' => 'invalid_request',
'message' => 'The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Check the "client_secret" parameter.'
]);

View File

@ -1,2 +0,0 @@
<?php
// Here you can initialize variables that will be available to your tests

View File

@ -1,26 +0,0 @@
<?php
namespace LeagueTests;
use LeagueTests\Stubs\StubAbstractServer;
class AbstractServerTest extends \PHPUnit_Framework_TestCase
{
public function testSetGet()
{
$server = new StubAbstractServer();
$var = 0;
$server->addEventListener('event.name', function () use ($var) {
$var++;
$this->assertSame(1, $var);
});
$server->getEventEmitter()->emit('event.name');
$this->assertTrue($server->getRequest() instanceof \Symfony\Component\HttpFoundation\Request);
$this->assertTrue($server->getEventEmitter() instanceof \League\Event\Emitter);
$server2 = new StubAbstractServer();
$server2->setRequest((new \Symfony\Component\HttpFoundation\Request()));
$server2->setEventEmitter(1);
$this->assertTrue($server2->getRequest() instanceof \Symfony\Component\HttpFoundation\Request);
}
}

View File

@ -1,82 +0,0 @@
<?php
namespace LeagueTests;
use League\OAuth2\Server\AuthorizationServer;
use League\OAuth2\Server\Grant\GrantTypeInterface;
use League\OAuth2\Server\Storage\ScopeInterface;
use Mockery as M;
class AuthorizationServerTest extends \PHPUnit_Framework_TestCase
{
public function testSetGet()
{
$server = new AuthorizationServer();
$server->requireScopeParam(true);
$server->requireStateParam(true);
$server->setDefaultScope('foobar');
$server->setScopeDelimiter(',');
$server->setAccessTokenTTL(1);
$grant = M::mock('League\OAuth2\Server\Grant\GrantTypeInterface');
$grant->shouldReceive('getIdentifier')->andReturn('foobar');
$grant->shouldReceive('getResponseType')->andReturn('foobar');
$grant->shouldReceive('setAuthorizationServer');
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$server->addGrantType($grant);
$server->setScopeStorage($scopeStorage);
$this->assertTrue($server->hasGrantType('foobar'));
$this->assertTrue($server->getGrantType('foobar') instanceof GrantTypeInterface);
$this->assertSame($server->getResponseTypes(), ['foobar']);
$this->assertTrue($server->scopeParamRequired());
$this->assertTrue($server->stateParamRequired());
$this->assertTrue($server->getScopeStorage() instanceof ScopeInterface);
$this->assertEquals('foobar', $server->getDefaultScope());
$this->assertEquals(',', $server->getScopeDelimiter());
$this->assertEquals(1, $server->getAccessTokenTTL());
}
public function testInvalidGrantType()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidGrantException');
$server = new AuthorizationServer();
$server->getGrantType('foobar');
}
public function testIssueAccessToken()
{
$grant = M::mock('League\OAuth2\Server\Grant\GrantTypeInterface');
$grant->shouldReceive('getIdentifier')->andReturn('foobar');
$grant->shouldReceive('getResponseType')->andReturn('foobar');
$grant->shouldReceive('setAuthorizationServer');
$grant->shouldReceive('completeFlow')->andReturn(true);
$_POST['grant_type'] = 'foobar';
$server = new AuthorizationServer();
$server->addGrantType($grant);
$this->assertTrue($server->issueAccessToken());
}
public function testIssueAccessTokenEmptyGrantType()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidRequestException');
$server = new AuthorizationServer();
$this->assertTrue($server->issueAccessToken());
}
public function testIssueAccessTokenInvalidGrantType()
{
$this->setExpectedException('League\OAuth2\Server\Exception\UnsupportedGrantTypeException');
$_POST['grant_type'] = 'foobar';
$server = new AuthorizationServer();
$this->assertTrue($server->issueAccessToken());
}
}

View File

@ -1,116 +0,0 @@
<?php
namespace LeagueTests\Entity;
use League\OAuth2\Server\AuthorizationServer;
use League\OAuth2\Server\Entity\ScopeEntity;
use League\OAuth2\Server\Entity\SessionEntity;
use LeagueTests\Stubs\StubAbstractTokenEntity;
use Mockery as M;
class AbstractTokenEntityTest extends \PHPUnit_Framework_TestCase
{
public function testSetGet()
{
$server = M::mock('League\OAuth2\Server\AbstractServer');
$time = time();
$entity = new StubAbstractTokenEntity($server);
$entity->setId('foobar');
$entity->setExpireTime($time);
$entity->setSession((new SessionEntity($server)));
$entity->associateScope((new ScopeEntity($server))->hydrate(['id' => 'foo']));
$this->assertEquals('foobar', $entity->getId());
$this->assertEquals($time, $entity->getExpireTime());
// $this->assertTrue($entity->getSession() instanceof SessionEntity);
// $this->assertTrue($entity->hasScope('foo'));
// $result = $entity->getScopes();
// $this->assertTrue(isset($result['foo']));
}
/*public function testGetSession()
{
$server = M::mock('League\OAuth2\Server\AuthorizationServer');
$server->shouldReceive('setSessionStorage');
$sessionStorage = M::mock('League\OAuth2\Server\Storage\SessionInterface');
$sessionStorage->shouldReceive('getByAccessToken')->andReturn(
(new SessionEntity($server))
);
$sessionStorage->shouldReceive('setServer');
$server->shouldReceive('getStorage')->andReturn($sessionStorage);
$server->setSessionStorage($sessionStorage);
$entity = new StubAbstractTokenEntity($server);
$this->assertTrue($entity->getSession() instanceof SessionEntity);
}*/
/*public function testGetScopes()
{
$server = M::mock('League\OAuth2\Server\AuthorizationServer');
$server->shouldReceive('setAccessTokenStorage');
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('getScopes')->andReturn(
[]
);
$accessTokenStorage->shouldReceive('setServer');
$server->setAccessTokenStorage($accessTokenStorage);
$entity = new StubAbstractTokenEntity($server);
$this->assertEquals($entity->getScopes(), []);
}*/
/*public function testHasScopes()
{
$server = M::mock('League\OAuth2\Server\AuthorizationServer');
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('getScopes')->andReturn(
[]
);
$accessTokenStorage''>shouldReceive('setServer');
$server->setAccessTokenStorage($accessTokenStorage);
$entity = new StubAbstractTokenEntity($server);
$this->assertFalse($entity->hasScope('foo'));
}*/
public function testFormatScopes()
{
$server = M::mock('League\OAuth2\Server\AbstractServer');
$entity = new StubAbstractTokenEntity($server);
$reflectedEntity = new \ReflectionClass('LeagueTests\Stubs\StubAbstractTokenEntity');
$method = $reflectedEntity->getMethod('formatScopes');
$method->setAccessible(true);
$scopes = [
(new ScopeEntity($server))->hydrate(['id' => 'scope1', 'description' => 'foo']),
(new ScopeEntity($server))->hydrate(['id' => 'scope2', 'description' => 'bar']),
];
$result = $method->invokeArgs($entity, [$scopes]);
$this->assertTrue(isset($result['scope1']));
$this->assertTrue(isset($result['scope2']));
$this->assertTrue($result['scope1'] instanceof ScopeEntity);
$this->assertTrue($result['scope2'] instanceof ScopeEntity);
}
public function test__toString()
{
$server = M::mock('League\OAuth2\Server\AbstractServer');
$entity = new StubAbstractTokenEntity($server);
$this->assertEquals('', (string) $entity);
$entity->setId('foobar');
$this->assertEquals('foobar', (string) $entity);
}
}

View File

@ -1,59 +0,0 @@
<?php
namespace LeagueTests\Entity;
use League\OAuth2\Server\Entity\AccessTokenEntity;
use League\OAuth2\Server\Entity\ScopeEntity;
use League\OAuth2\Server\Entity\SessionEntity;
use Mockery as M;
class AccessTokenEntityTest extends \PHPUnit_Framework_TestCase
{
public function testSave()
{
$server = M::mock('League\OAuth2\Server\AbstractServer');
$server->shouldReceive('setAccessTokenStorage');
$server->shouldReceive('setSessionStorage');
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('create');
$accessTokenStorage->shouldReceive('associateScope');
$accessTokenStorage->shouldReceive('setServer');
$accessTokenStorage->shouldReceive('getScopes')->andReturn([
(new ScopeEntity($server))->hydrate(['id' => 'foo']),
]);
$sessionStorage = M::mock('League\OAuth2\Server\Storage\SessionInterface');
$sessionStorage->shouldReceive('getByAccessToken')->andReturn(
(new SessionEntity($server))
);
$sessionStorage->shouldReceive('setServer');
$server->shouldReceive('getSessionStorage')->andReturn($sessionStorage);
$server->shouldReceive('getAccessTokenStorage')->andReturn($accessTokenStorage);
$server->setAccessTokenStorage($accessTokenStorage);
$server->setSessionStorage($sessionStorage);
$entity = new AccessTokenEntity($server);
$this->assertTrue($entity->save() instanceof AccessTokenEntity);
}
public function testExpire()
{
$server = M::mock('League\OAuth2\Server\AbstractServer');
$server->shouldReceive('setAccessTokenStorage');
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('delete');
$accessTokenStorage->shouldReceive('setServer');
$server->shouldReceive('getAccessTokenStorage')->andReturn($accessTokenStorage);
$server->setAccessTokenStorage($accessTokenStorage);
$entity = new AccessTokenEntity($server);
$this->assertSame($entity->expire(), null);
}
}

View File

@ -1,73 +0,0 @@
<?php
namespace LeagueTests\Entity;
use League\OAuth2\Server\AuthorizationServer;
use League\OAuth2\Server\Entity\AuthCodeEntity;
use League\OAuth2\Server\Entity\ScopeEntity;
use League\OAuth2\Server\Entity\SessionEntity;
use Mockery as M;
class AuthCodeEntityTest extends \PHPUnit_Framework_TestCase
{
public function testSetGet()
{
$server = M::mock('League\OAuth2\Server\AbstractServer');
$session = M::mock('League\OAuth2\Server\Entity\SessionEntity');
$code = new AuthCodeEntity($server);
$code->setRedirectUri('http://foo/bar');
$code->setId('foobar');
$code->setSession($session);
$this->assertEquals('http://foo/bar', $code->getRedirectUri());
$this->assertEquals('http://foo/bar?code=foobar', $code->generateRedirectUri());
$this->assertTrue($code->getSession() instanceof \League\OAuth2\Server\Entity\SessionEntity);
}
public function testSave()
{
$server = M::mock('League\OAuth2\Server\AbstractServer');
$server->shouldReceive('setAuthCodeStorage');
$server->shouldReceive('setSessionStorage');
$authCodeStorage = M::mock('League\OAuth2\Server\Storage\AuthCodeInterface');
$authCodeStorage->shouldReceive('create');
$authCodeStorage->shouldReceive('associateScope');
$authCodeStorage->shouldReceive('setServer');
$authCodeStorage->shouldReceive('getScopes')->andReturn([
(new ScopeEntity($server))->hydrate(['id' => 'foo']),
]);
$server->shouldReceive('getAuthCodeStorage')->andReturn($authCodeStorage);
$sessionStorage = M::mock('League\OAuth2\Server\Storage\SessionInterface');
$sessionStorage->shouldReceive('getByAuthCode')->andReturn(
(new SessionEntity($server))
);
$sessionStorage->shouldReceive('setServer');
$server->shouldReceive('getSessionStorage')->andReturn($sessionStorage);
$server->setAuthCodeStorage($authCodeStorage);
$server->setSessionStorage($sessionStorage);
$entity = new AuthCodeEntity($server);
$this->assertTrue($entity->save() instanceof AuthCodeEntity);
}
public function testExpire()
{
$server = new AuthorizationServer();
$authCodeStorage = M::mock('League\OAuth2\Server\Storage\AuthCodeInterface');
$authCodeStorage->shouldReceive('delete');
$authCodeStorage->shouldReceive('setServer');
$server->setAuthCodeStorage($authCodeStorage);
$entity = new AuthCodeEntity($server);
$this->assertSame($entity->expire(), null);
}
}

View File

@ -1,25 +0,0 @@
<?php
namespace LeagueTests\Entity;
use League\OAuth2\Server\Entity\ClientEntity;
use Mockery as M;
class ClientEntityTest extends \PHPUnit_Framework_TestCase
{
public function testSetGet()
{
$server = M::mock('League\OAuth2\Server\AbstractServer');
$client = (new ClientEntity($server))->hydrate([
'id' => 'foobar',
'secret' => 'barfoo',
'name' => 'Test Client',
'redirectUri' => 'http://foo/bar',
]);
$this->assertEquals('foobar', $client->getId());
$this->assertEquals('barfoo', $client->getSecret());
$this->assertEquals('Test Client', $client->getName());
$this->assertEquals('http://foo/bar', $client->getRedirectUri());
}
}

View File

@ -1,94 +0,0 @@
<?php
namespace LeagueTests\Entity;
use League\OAuth2\Server\Entity\AccessTokenEntity;
use League\OAuth2\Server\Entity\RefreshTokenEntity;
use League\OAuth2\Server\Entity\ScopeEntity;
use League\OAuth2\Server\Entity\SessionEntity;
use Mockery as M;
class RefreshTokenEntityTest extends \PHPUnit_Framework_TestCase
{
public function testSetAccessTokenId()
{
$server = M::mock('League\OAuth2\Server\AbstractServer');
$entity = new RefreshTokenEntity($server);
$entity->setAccessTokenId('foobar');
$reflector = new \ReflectionClass($entity);
$accessTokenProperty = $reflector->getProperty('accessTokenId');
$accessTokenProperty->setAccessible(true);
$this->assertSame($accessTokenProperty->getValue($entity), 'foobar');
}
public function testSetAccessToken()
{
$server = M::mock('League\OAuth2\Server\AbstractServer');
$entity = new RefreshTokenEntity($server);
$entity->setAccessToken((new AccessTokenEntity($server)));
$reflector = new \ReflectionClass($entity);
$accessTokenProperty = $reflector->getProperty('accessTokenEntity');
$accessTokenProperty->setAccessible(true);
$this->assertTrue($accessTokenProperty->getValue($entity) instanceof AccessTokenEntity);
}
public function testSave()
{
$server = M::mock('League\OAuth2\Server\AbstractServer');
$server->shouldReceive('setAccessTokenStorage');
$server->shouldReceive('setRefreshTokenStorage');
$refreshTokenStorage = M::mock('League\OAuth2\Server\Storage\RefreshTokenInterface');
$refreshTokenStorage->shouldReceive('create');
$refreshTokenStorage->shouldReceive('setServer');
$refreshTokenStorage->shouldReceive('associateScope');
$server->shouldReceive('getRefreshTokenStorage')->andReturn($refreshTokenStorage);
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$accessTokenStorage->shouldReceive('get')->andReturn(
(new AccessTokenEntity($server))->setId('foobar')
);
$accessTokenStorage->shouldReceive('getScopes')->andReturn([
(new ScopeEntity($server))->hydrate(['id' => 'foo']),
]);
$server->shouldReceive('getAccessTokenStorage')->andReturn($accessTokenStorage);
$sessionStorage = M::mock('League\OAuth2\Server\Storage\SessionInterface');
$sessionStorage->shouldReceive('getByAccessToken')->andReturn(
(new SessionEntity($server))
);
$sessionStorage->shouldReceive('setServer');
$server->shouldReceive('getSessionStorage')->andReturn($sessionStorage);
$server->setAccessTokenStorage($accessTokenStorage);
$server->setRefreshTokenStorage($refreshTokenStorage);
$entity = new RefreshTokenEntity($server);
$this->assertSame(null, $entity->save());
}
public function testExpire()
{
$server = M::mock('League\OAuth2\Server\AbstractServer');
$server->shouldReceive('setRefreshTokenStorage');
$refreshTokenStorage = M::mock('League\OAuth2\Server\Storage\RefreshTokenInterface');
$refreshTokenStorage->shouldReceive('delete');
$refreshTokenStorage->shouldReceive('setServer');
$server->shouldReceive('getRefreshTokenStorage')->andReturn($refreshTokenStorage);
$server->setRefreshTokenStorage($refreshTokenStorage);
$entity = new RefreshTokenEntity($server);
$this->assertSame($entity->expire(), null);
}
}

View File

@ -1,23 +0,0 @@
<?php
namespace LeagueTests\Entity;
use League\OAuth2\Server\Entity\ScopeEntity;
use Mockery as M;
class ScopeEntityTest extends \PHPUnit_Framework_TestCase
{
public function testSetGet()
{
$server = M::mock('League\OAuth2\Server\AbstractServer');
$scope = (new ScopeEntity($server))->hydrate([
'id' => 'foobar',
'description' => 'barfoo',
]);
$this->assertEquals('foobar', $scope->getId());
$this->assertEquals('barfoo', $scope->getDescription());
$this->assertTrue(is_array($scope->jsonSerialize()));
}
}

View File

@ -1,154 +0,0 @@
<?php
namespace LeagueTests\Entity;
use League\OAuth2\Server\AuthorizationServer;
use League\OAuth2\Server\Entity\AccessTokenEntity;
use League\OAuth2\Server\Entity\ClientEntity;
use League\OAuth2\Server\Entity\RefreshTokenEntity;
use League\OAuth2\Server\Entity\ScopeEntity;
use League\OAuth2\Server\Entity\SessionEntity;
use Mockery as M;
class SessionEntityTest extends \PHPUnit_Framework_TestCase
{
public function testSetGet()
{
$emitter = M::mock('League\Event\Emitter');
$emitter->shouldReceive('emit');
$server = M::mock('League\OAuth2\Server\AbstractServer');
$server->shouldReceive('setEventEmitter');
$server->shouldReceive('getEventEmitter')->andReturn($emitter);
$server->setEventEmitter($emitter);
$entity = new SessionEntity($server);
$entity->setId('foobar');
$entity->setOwner('user', 123);
$entity->associateAccessToken((new AccessTokenEntity($server)));
$entity->associateRefreshToken((new RefreshTokenEntity($server)));
$entity->associateClient((new ClientEntity($server)));
$entity->associateScope(
(new ScopeEntity($server))->hydrate(['id' => 'foo'])
);
// $entity->associateAuthCode((new AuthCode($server)));
$this->assertEquals('foobar', $entity->getId());
$this->assertEquals('user', $entity->getOwnerType());
$this->assertEquals(123, $entity->getOwnerId());
$this->assertTrue($entity->getClient() instanceof ClientEntity);
$this->assertTrue($entity->hasScope('foo'));
$reflector = new \ReflectionClass($entity);
$accessTokenProperty = $reflector->getProperty('accessToken');
$accessTokenProperty->setAccessible(true);
$refreshTokenProperty = $reflector->getProperty('refreshToken');
$refreshTokenProperty->setAccessible(true);
$this->assertTrue($accessTokenProperty->getValue($entity) instanceof AccessTokenEntity);
$this->assertTrue($refreshTokenProperty->getValue($entity) instanceof RefreshTokenEntity);
// $this->assertTrue($reader($entity, 'authCode') instanceof AuthCode);
}
public function testFormatScopes()
{
$server = M::mock('League\OAuth2\Server\AbstractServer');
$entity = new SessionEntity($server);
$reflectedEntity = new \ReflectionClass('League\OAuth2\Server\Entity\SessionEntity');
$method = $reflectedEntity->getMethod('formatScopes');
$method->setAccessible(true);
$scopes = [
(new ScopeEntity($server))->hydrate(['id' => 'scope1']),
(new ScopeEntity($server))->hydrate(['id' => 'scope2']),
];
$result = $method->invokeArgs($entity, [$scopes]);
$this->assertTrue(isset($result['scope1']));
$this->assertTrue(isset($result['scope2']));
$this->assertTrue($result['scope1'] instanceof ScopeEntity);
$this->assertTrue($result['scope2'] instanceof ScopeEntity);
}
public function testGetScopes()
{
$server = M::mock('League\OAuth2\Server\AuthorizationServer');
$server->shouldReceive('setAccessTokenStorage');
$server->shouldReceive('setSessionStorage');
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$server->setAccessTokenStorage($accessTokenStorage);
$server->shouldReceive('getAccessTokenStorage')->andReturn($accessTokenStorage);
$sessionStorage = M::mock('League\OAuth2\Server\Storage\SessionInterface');
$sessionStorage->shouldReceive('getScopes')->andReturn(
[]
);
$sessionStorage->shouldReceive('setServer');
$server->setSessionStorage($sessionStorage);
$server->shouldReceive('getSessionStorage')->andReturn($sessionStorage);
$entity = new SessionEntity($server);
$this->assertEquals($entity->getScopes(), []);
}
public function testHasScopes()
{
$server = M::mock('League\OAuth2\Server\AuthorizationServer');
$server->shouldReceive('setAccessTokenStorage');
$server->shouldReceive('setSessionStorage');
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$server->setAccessTokenStorage($accessTokenStorage);
$server->shouldReceive('getAccessTokenStorage')->andReturn($accessTokenStorage);
$sessionStorage = M::mock('League\OAuth2\Server\Storage\SessionInterface');
$sessionStorage->shouldReceive('getScopes')->andReturn(
[]
);
$sessionStorage->shouldReceive('setServer');
$server->setSessionStorage($sessionStorage);
$server->shouldReceive('getSessionStorage')->andReturn($sessionStorage);
$entity = new SessionEntity($server);
$this->assertFalse($entity->hasScope('foo'));
}
public function testSave()
{
$server = M::mock('League\OAuth2\Server\AuthorizationServer');
$server->shouldReceive('setSessionStorage');
$server->shouldReceive('setClientStorage');
$sessionStorage = M::mock('League\OAuth2\Server\Storage\SessionInterface');
$sessionStorage->shouldReceive('create');
$sessionStorage->shouldReceive('associateScope');
$sessionStorage->shouldReceive('setServer');
$sessionStorage->shouldReceive('getScopes')->andReturn([
(new ScopeEntity($server))->hydrate(['id' => 'foo']),
]);
$server->shouldReceive('getSessionStorage')->andReturn($sessionStorage);
$clientStorage = M::mock('League\OAuth2\Server\Storage\ClientInterface');
$clientStorage->shouldReceive('getBySession')->andReturn(
(new ClientEntity($server))->hydrate(['id' => 'foo'])
);
$clientStorage->shouldReceive('setServer');
$server->shouldReceive('getClientStorage')->andReturn($clientStorage);
$server->setSessionStorage($sessionStorage);
$server->setClientStorage($clientStorage);
$entity = new SessionEntity($server);
$this->assertEquals(null, $entity->save());
}
}

View File

@ -1,34 +0,0 @@
<?php
namespace LeagueTests;
use League\OAuth2\Server\Exception\OAuthException;
class OAuthExceptionTest extends \PHPUnit_Framework_TestCase
{
public function testGetHttpHeaders()
{
$exception = new OAuthException();
$exception->httpStatusCode = 400;
$this->assertSame($exception->getHttpHeaders(), ['HTTP/1.1 400 Bad Request']);
$exception->httpStatusCode = 401;
$this->assertSame($exception->getHttpHeaders(), ['HTTP/1.1 401 Unauthorized']);
$exception->httpStatusCode = 500;
$this->assertSame($exception->getHttpHeaders(), ['HTTP/1.1 500 Internal Server Error']);
$exception->httpStatusCode = 501;
$this->assertSame($exception->getHttpHeaders(), ['HTTP/1.1 501 Not Implemented']);
}
public function testShouldRedirect()
{
$exception = new OAuthException();
$exception->redirectUri = 'http://example.com/';
$exception->errorType = 'Error';
$this->assertTrue($exception->shouldRedirect());
$this->assertEquals('http://example.com/?error=Error&message=An+error+occured', $exception->getRedirectUri());
}
}

View File

@ -1,160 +0,0 @@
<?php
namespace LeagueTests\Grant;
use League\OAuth2\Server\AuthorizationServer;
use League\OAuth2\Server\Entity\ClientEntity;
use League\OAuth2\Server\Entity\ScopeEntity;
use League\OAuth2\Server\Exception\InvalidRequestException;
use League\OAuth2\Server\Grant;
use LeagueTests\Stubs\StubAbstractGrant;
use Mockery as M;
class AbstractGrantTest extends \PHPUnit_Framework_TestCase
{
public function testSetGet()
{
$server = new AuthorizationServer();
$grant = new StubAbstractGrant();
$grant->setIdentifier('foobar');
$grant->setAccessTokenTTL(300);
$grant->setAuthorizationServer($server);
$this->assertEquals('foobar', $grant->getIdentifier());
$this->assertEquals('foobar', $grant->getResponseType());
$this->assertEquals(300, $grant->getAccessTokenTTL());
$this->assertTrue($grant->getAuthorizationServer() instanceof AuthorizationServer);
}
public function testFormatScopes()
{
$server = M::mock('League\OAuth2\Server\AbstractServer');
$grant = new StubAbstractGrant();
$reflectedGrant = new \ReflectionClass('LeagueTests\Stubs\StubAbstractGrant');
$method = $reflectedGrant->getMethod('formatScopes');
$method->setAccessible(true);
$scopes = [
(new ScopeEntity($server))->hydrate(['id' => 'scope1', 'description' => 'foo']),
(new ScopeEntity($server))->hydrate(['id' => 'scope2', 'description' => 'bar']),
];
$result = $method->invokeArgs($grant, [$scopes]);
$this->assertTrue(isset($result['scope1']));
$this->assertTrue(isset($result['scope2']));
$this->assertTrue($result['scope1'] instanceof ScopeEntity);
$this->assertTrue($result['scope2'] instanceof ScopeEntity);
}
public function testValidateScopes()
{
$server = new AuthorizationServer();
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$scopeStorage->shouldReceive('get')->andReturn(
(new ScopeEntity($server))->hydrate(['id' => 'foo'])
);
$server->setScopeStorage($scopeStorage);
$grant = new StubAbstractGrant();
$grant->setAuthorizationServer($server);
$client = (new ClientEntity($server))->hydrate(['id' => 'testapp']);
$this->assertEquals(
[
'foo' => (new ScopeEntity($server))->hydrate(['id' => 'foo']),
],
$grant->validateScopes('foo', $client)
);
}
public function testValidateScopesMissingScope()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidRequestException');
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$server = new AuthorizationServer();
$server->requireScopeParam(true);
$server->setScopeStorage($scopeStorage);
$grant = new StubAbstractGrant();
$grant->setAuthorizationServer($server);
$client = (new ClientEntity($server))->hydrate(['id' => 'testapp']);
$grant->validateScopes(null, $client);
}
public function testValidateScopesInvalidScope()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidScopeException');
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$scopeStorage->shouldReceive('get')->andReturn(null);
$server = new AuthorizationServer();
$server->setScopeStorage($scopeStorage);
$grant = new StubAbstractGrant();
$grant->setAuthorizationServer($server);
$client = (new ClientEntity($server))->hydrate(['id' => 'testapp']);
$grant->validateScopes('blah', $client);
}
public function testValidateScopesDefaultScope()
{
$server = new AuthorizationServer();
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$scopeStorage->shouldReceive('get')->andReturn(
(new ScopeEntity($server))->hydrate(['id' => 'foo'])
);
$server->setScopeStorage($scopeStorage);
$server->requireScopeParam(true);
$server->setScopeStorage($scopeStorage);
$server->setDefaultScope('foo');
$grant = new StubAbstractGrant();
$grant->setAuthorizationServer($server);
$client = (new ClientEntity($server))->hydrate(['id' => 'testapp']);
$grant->validateScopes(null, $client);
}
public function testValidateScopesDefaultScopeArray()
{
$server = new AuthorizationServer();
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$scopeStorage->shouldReceive('get')->andReturn(
(new ScopeEntity($server))->hydrate(['id' => 'foo'])
);
$server->setScopeStorage($scopeStorage);
$server->requireScopeParam(true);
$server->setScopeStorage($scopeStorage);
$server->setDefaultScope(['foo', 'bar']);
$grant = new StubAbstractGrant();
$grant->setAuthorizationServer($server);
$client = (new ClientEntity($server))->hydrate(['id' => 'testapp']);
$grant->validateScopes(null, $client);
}
}

View File

@ -1,696 +0,0 @@
<?php
namespace LeagueTests\Grant;
use League\OAuth2\Server\AuthorizationServer;
use League\OAuth2\Server\Entity\AuthCodeEntity;
use League\OAuth2\Server\Entity\ClientEntity;
use League\OAuth2\Server\Entity\ScopeEntity;
use League\OAuth2\Server\Entity\SessionEntity;
use League\OAuth2\Server\Exception\InvalidRequestException;
use League\OAuth2\Server\Grant\AuthCodeGrant;
use League\OAuth2\Server\Grant\RefreshTokenGrant;
use Mockery as M;
class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
{
public function testSetAuthTokenTTL()
{
$grant = new AuthCodeGrant();
$grant->setAuthTokenTTL(100);
$class = new \ReflectionClass($grant);
$property = $class->getProperty('authTokenTTL');
$property->setAccessible(true);
$this->assertEquals(100, $property->getValue($grant));
}
public function testCheckAuthoriseParamsMissingClientId()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidRequestException');
$_GET = [];
$server = new AuthorizationServer();
$grant = new AuthCodeGrant();
$server->addGrantType($grant);
$grant->checkAuthorizeParams();
}
public function testCheckAuthoriseParamsMissingRedirectUri()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidRequestException');
$server = new AuthorizationServer();
$_GET = [
'client_id' => 'testapp',
];
$grant = new AuthCodeGrant();
$server->addGrantType($grant);
$grant->checkAuthorizeParams();
}
public function testCheckAuthoriseParamsInvalidClient()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidClientException');
$_GET = [
'client_id' => 'testapp',
'redirect_uri' => 'http://foo/bar',
'response_type' => 'code',
];
$server = new AuthorizationServer();
$grant = new AuthCodeGrant();
$clientStorage = M::mock('League\OAuth2\Server\Storage\ClientInterface');
$clientStorage->shouldReceive('setServer');
$clientStorage->shouldReceive('get')->andReturn(null);
$server->setClientStorage($clientStorage);
$server->addGrantType($grant);
$grant->checkAuthorizeParams();
}
public function testCheckAuthoriseParamsMissingStateParam()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidRequestException');
$_GET = [
'client_id' => 'testapp',
'redirect_uri' => 'http://foo/bar',
];
$server = new AuthorizationServer();
$clientStorage = M::mock('League\OAuth2\Server\Storage\ClientInterface');
$clientStorage->shouldReceive('setServer');
$clientStorage->shouldReceive('get')->andReturn(
(new ClientEntity($server))->hydrate(['id' => 'testapp'])
);
$server->setClientStorage($clientStorage);
$grant = new AuthCodeGrant();
$server->requireStateParam(true);
$server->addGrantType($grant);
$grant->checkAuthorizeParams();
}
public function testCheckAuthoriseParamsMissingResponseType()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidRequestException');
$_GET = [
'client_id' => 'testapp',
'redirect_uri' => 'http://foo/bar',
];
$server = new AuthorizationServer();
$clientStorage = M::mock('League\OAuth2\Server\Storage\ClientInterface');
$clientStorage->shouldReceive('setServer');
$clientStorage->shouldReceive('get')->andReturn(
(new ClientEntity($server))->hydrate(['id' => 'testapp'])
);
$server->setClientStorage($clientStorage);
$grant = new AuthCodeGrant();
$server->addGrantType($grant);
$grant->checkAuthorizeParams();
}
public function testCheckAuthoriseParamsInvalidResponseType()
{
$this->setExpectedException('League\OAuth2\Server\Exception\UnsupportedResponseTypeException');
$_GET = [
'client_id' => 'testapp',
'redirect_uri' => 'http://foo/bar',
'response_type' => 'foobar',
];
$server = new AuthorizationServer();
$clientStorage = M::mock('League\OAuth2\Server\Storage\ClientInterface');
$clientStorage->shouldReceive('setServer');
$clientStorage->shouldReceive('get')->andReturn(
(new ClientEntity($server))->hydrate(['id' => 'testapp'])
);
$server->setClientStorage($clientStorage);
$grant = new AuthCodeGrant();
$server->addGrantType($grant);
$grant->checkAuthorizeParams();
}
public function testCheckAuthoriseParamsInvalidScope()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidScopeException');
$_GET = [
'response_type' => 'code',
'client_id' => 'testapp',
'redirect_uri' => 'http://foo/bar',
'scope' => 'foo',
];
$server = new AuthorizationServer();
$grant = new AuthCodeGrant();
$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('create');
$sessionStorage->shouldReceive('getScopes')->andReturn([]);
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$accessTokenStorage->shouldReceive('create');
$accessTokenStorage->shouldReceive('getScopes')->andReturn([]);
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$scopeStorage->shouldReceive('get')->andReturn(null);
$server->setClientStorage($clientStorage);
$server->setScopeStorage($scopeStorage);
$server->setSessionStorage($sessionStorage);
$server->setAccessTokenStorage($accessTokenStorage);
$server->addGrantType($grant);
$grant->checkAuthorizeParams();
}
public function testCheckAuthoriseParams()
{
$_GET = [
'response_type' => 'code',
'client_id' => 'testapp',
'redirect_uri' => 'http://foo/bar',
'scope' => 'foo',
];
$server = new AuthorizationServer();
$grant = new AuthCodeGrant();
$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('create')->andreturn(123);
$sessionStorage->shouldReceive('getScopes')->shouldReceive('getScopes')->andReturn([
(new ScopeEntity($server))->hydrate(['id' => 'foo']),
]);
$sessionStorage->shouldReceive('associateScope');
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$accessTokenStorage->shouldReceive('create');
$accessTokenStorage->shouldReceive('getScopes')->andReturn([
(new ScopeEntity($server))->hydrate(['id' => 'foo']),
]);
$accessTokenStorage->shouldReceive('associateScope');
$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->addGrantType($grant);
$result = $grant->checkAuthorizeParams();
$this->assertTrue($result['client'] instanceof ClientEntity);
$this->assertTrue($result['redirect_uri'] === $_GET['redirect_uri']);
$this->assertTrue($result['state'] === null);
$this->assertTrue($result['response_type'] === 'code');
$this->assertTrue($result['scopes']['foo'] instanceof ScopeEntity);
}
public function testNewAuthoriseRequest()
{
$server = new AuthorizationServer();
$client = (new ClientEntity($server))->hydrate(['id' => 'testapp']);
$scope = (new ScopeEntity($server))->hydrate(['id' => 'foo']);
$grant = new AuthCodeGrant();
$server->addGrantType($grant);
$sessionStorage = M::mock('League\OAuth2\Server\Storage\SessionInterface');
$sessionStorage->shouldReceive('setServer');
$sessionStorage->shouldReceive('create')->andreturn(123);
$sessionStorage->shouldReceive('getScopes')->shouldReceive('getScopes')->andReturn([$scope]);
$sessionStorage->shouldReceive('associateScope');
$server->setSessionStorage($sessionStorage);
$authCodeStorage = M::mock('League\OAuth2\Server\Storage\AuthCodeInterface');
$authCodeStorage->shouldReceive('setServer');
$authCodeStorage->shouldReceive('get');
$authCodeStorage->shouldReceive('create');
$authCodeStorage->shouldReceive('associateScope');
$server->setAuthCodeStorage($authCodeStorage);
$grant->newAuthorizeRequest('user', 123, [
'client' => $client,
'redirect_uri' => 'http://foo/bar',
'scopes' => [$scope],
'state' => 'foobar'
]);
}
public function testCompleteFlowMissingClientId()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidRequestException');
$_POST['grant_type'] = 'authorization_code';
$server = new AuthorizationServer();
$grant = new AuthCodeGrant();
$server->addGrantType($grant);
$server->issueAccessToken();
}
public function testCompleteFlowMissingClientSecret()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidRequestException');
$_POST = [
'grant_type' => 'authorization_code',
'client_id' => 'testapp',
];
$server = new AuthorizationServer();
$grant = new AuthCodeGrant();
$server->addGrantType($grant);
$server->issueAccessToken();
}
public function testCompleteFlowMissingRedirectUri()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidRequestException');
$_POST = [
'grant_type' => 'authorization_code',
'client_id' => 'testapp',
'client_secret' => 'foobar',
];
$server = new AuthorizationServer();
$grant = new AuthCodeGrant();
$server->addGrantType($grant);
$server->issueAccessToken();
}
public function testCompleteFlowInvalidClient()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidClientException');
$_POST = [
'grant_type' => 'authorization_code',
'client_id' => 'testapp',
'client_secret' => 'foobar',
'redirect_uri' => 'http://foo/bar',
];
$server = new AuthorizationServer();
$grant = new AuthCodeGrant();
$clientStorage = M::mock('League\OAuth2\Server\Storage\ClientInterface');
$clientStorage->shouldReceive('setServer');
$clientStorage->shouldReceive('get')->andReturn(null);
$server->setClientStorage($clientStorage);
$server->addGrantType($grant);
$server->issueAccessToken();
}
public function testCompleteFlowMissingCode()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidRequestException');
$_POST = [
'grant_type' => 'authorization_code',
'client_id' => 'testapp',
'client_secret' => 'foobar',
'redirect_uri' => 'http://foo/bar',
];
$server = new AuthorizationServer();
$grant = new AuthCodeGrant();
$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('create');
$sessionStorage->shouldReceive('getScopes')->andReturn([]);
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$accessTokenStorage->shouldReceive('create');
$accessTokenStorage->shouldReceive('getScopes')->andReturn([]);
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$scopeStorage->shouldReceive('get')->andReturn(null);
$authCodeStorage = M::mock('League\OAuth2\Server\Storage\AuthCodeInterface');
$authCodeStorage->shouldReceive('setServer');
$authCodeStorage->shouldReceive('get');
$server->setClientStorage($clientStorage);
$server->setScopeStorage($scopeStorage);
$server->setSessionStorage($sessionStorage);
$server->setAccessTokenStorage($accessTokenStorage);
$server->setAuthCodeStorage($authCodeStorage);
$server->addGrantType($grant);
$server->issueAccessToken();
}
public function testCompleteFlowInvalidCode()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidRequestException');
$_POST = [
'grant_type' => 'authorization_code',
'client_id' => 'testapp',
'client_secret' => 'foobar',
'redirect_uri' => 'http://foo/bar',
'code' => 'foobar',
];
$server = new AuthorizationServer();
$grant = new AuthCodeGrant();
$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('create');
$sessionStorage->shouldReceive('getScopes')->andReturn([]);
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$accessTokenStorage->shouldReceive('create');
$accessTokenStorage->shouldReceive('getScopes')->andReturn([]);
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$scopeStorage->shouldReceive('get')->andReturn(null);
$authCodeStorage = M::mock('League\OAuth2\Server\Storage\AuthCodeInterface');
$authCodeStorage->shouldReceive('setServer');
$authCodeStorage->shouldReceive('get');
$server->setClientStorage($clientStorage);
$server->setScopeStorage($scopeStorage);
$server->setSessionStorage($sessionStorage);
$server->setAccessTokenStorage($accessTokenStorage);
$server->setAuthCodeStorage($authCodeStorage);
$server->addGrantType($grant);
$server->issueAccessToken();
}
public function testCompleteFlowExpiredCode()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidRequestException');
$_POST = [
'grant_type' => 'authorization_code',
'client_id' => 'testapp',
'client_secret' => 'foobar',
'redirect_uri' => 'http://foo/bar',
'code' => 'foobar',
];
$server = new AuthorizationServer();
$grant = new AuthCodeGrant();
$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('create');
$sessionStorage->shouldReceive('getScopes')->andReturn([]);
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$accessTokenStorage->shouldReceive('create');
$accessTokenStorage->shouldReceive('getScopes')->andReturn([]);
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$scopeStorage->shouldReceive('get')->andReturn(null);
$authCodeStorage = M::mock('League\OAuth2\Server\Storage\AuthCodeInterface');
$authCodeStorage->shouldReceive('setServer');
$authCodeStorage->shouldReceive('get')->andReturn(
(new AuthCodeEntity($server))->setId('foobar')->setExpireTime(time() - 300)->setRedirectUri('http://foo/bar')
);
$server->setClientStorage($clientStorage);
$server->setScopeStorage($scopeStorage);
$server->setSessionStorage($sessionStorage);
$server->setAccessTokenStorage($accessTokenStorage);
$server->setAuthCodeStorage($authCodeStorage);
$server->addGrantType($grant);
$server->issueAccessToken();
}
public function testCompleteFlowRedirectUriMismatch()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidRequestException');
$_POST = [
'grant_type' => 'authorization_code',
'client_id' => 'testapp',
'client_secret' => 'foobar',
'redirect_uri' => 'http://foo/bar',
'code' => 'foobar',
];
$server = new AuthorizationServer();
$grant = new AuthCodeGrant();
$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('create');
$sessionStorage->shouldReceive('getScopes')->andReturn([]);
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$accessTokenStorage->shouldReceive('create');
$accessTokenStorage->shouldReceive('getScopes')->andReturn([]);
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$scopeStorage->shouldReceive('get')->andReturn(null);
$authCodeStorage = M::mock('League\OAuth2\Server\Storage\AuthCodeInterface');
$authCodeStorage->shouldReceive('setServer');
$authCodeStorage->shouldReceive('get')->andReturn(
(new AuthCodeEntity($server))->setId('foobar')->setExpireTime(time() + 300)->setRedirectUri('http://fail/face')
);
$server->setClientStorage($clientStorage);
$server->setScopeStorage($scopeStorage);
$server->setSessionStorage($sessionStorage);
$server->setAccessTokenStorage($accessTokenStorage);
$server->setAuthCodeStorage($authCodeStorage);
$server->addGrantType($grant);
$server->issueAccessToken();
}
public function testCompleteFlow()
{
$_POST = [
'grant_type' => 'authorization_code',
'client_id' => 'testapp',
'client_secret' => 'foobar',
'redirect_uri' => 'http://foo/bar',
'code' => 'foo',
];
$server = new AuthorizationServer();
$grant = new AuthCodeGrant();
$clientStorage = M::mock('League\OAuth2\Server\Storage\ClientInterface');
$clientStorage->shouldReceive('setServer');
$clientStorage->shouldReceive('getBySession')->andReturn(
(new ClientEntity($server))->hydrate(['id' => 'testapp'])
);
$clientStorage->shouldReceive('get')->andReturn(
(new ClientEntity($server))->hydrate(['id' => 'testapp'])
);
$sessionStorage = M::mock('League\OAuth2\Server\Storage\SessionInterface');
$sessionStorage->shouldReceive('setServer');
$sessionStorage->shouldReceive('create')->andreturn(123);
$sessionStorage->shouldReceive('associateScope');
$sessionStorage->shouldReceive('getByAuthCode')->andReturn(
(new SessionEntity($server))->setId('foobar')
);
$sessionStorage->shouldReceive('getByAccessToken')->andReturn(
(new SessionEntity($server))->setId('foobar')
);
$sessionStorage->shouldReceive('getScopes')->andReturn([
(new ScopeEntity($server))->hydrate(['id' => 'foo']),
]);
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$accessTokenStorage->shouldReceive('create');
$accessTokenStorage->shouldReceive('associateScope');
$accessTokenStorage->shouldReceive('getScopes')->andReturn([
(new ScopeEntity($server))->hydrate(['id' => 'foo']),
]);
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$scopeStorage->shouldReceive('get')->andReturn(
(new ScopeEntity($server))->hydrate(['id' => 'foo'])
);
$authCodeStorage = M::mock('League\OAuth2\Server\Storage\AuthCodeInterface');
$authCodeStorage->shouldReceive('setServer');
$authCodeStorage->shouldReceive('delete');
$authCodeStorage->shouldReceive('get')->andReturn(
(new AuthCodeEntity($server))->setId('foobar')->setRedirectUri('http://foo/bar')->setExpireTime(time() + 300)
);
$authCodeStorage->shouldReceive('getScopes')->andReturn([
(new ScopeEntity($server))->hydrate(['id' => 'foo']),
]);
$server->setClientStorage($clientStorage);
$server->setScopeStorage($scopeStorage);
$server->setSessionStorage($sessionStorage);
$server->setAccessTokenStorage($accessTokenStorage);
$server->setAuthCodeStorage($authCodeStorage);
$server->addGrantType($grant);
$server->issueAccessToken();
}
public function testCompleteFlowWithRefreshToken()
{
$_POST = [
'grant_type' => 'authorization_code',
'client_id' => 'testapp',
'client_secret' => 'foobar',
'redirect_uri' => 'http://foo/bar',
'code' => 'foo',
];
$server = new AuthorizationServer();
$grant = new AuthCodeGrant();
$rtgrant = new RefreshTokenGrant();
$clientStorage = M::mock('League\OAuth2\Server\Storage\ClientInterface');
$clientStorage->shouldReceive('setServer');
$clientStorage->shouldReceive('getBySession')->andReturn(
(new ClientEntity($server))->hydrate(['id' => 'testapp'])
);
$clientStorage->shouldReceive('get')->andReturn(
(new ClientEntity($server))->hydrate(['id' => 'testapp'])
);
$sessionStorage = M::mock('League\OAuth2\Server\Storage\SessionInterface');
$sessionStorage->shouldReceive('setServer');
$sessionStorage->shouldReceive('create')->andreturn(123);
$sessionStorage->shouldReceive('associateScope');
$sessionStorage->shouldReceive('getByAuthCode')->andReturn(
(new SessionEntity($server))->setId('foobar')
);
$sessionStorage->shouldReceive('getByAccessToken')->andReturn(
(new SessionEntity($server))->setId('foobar')
);
$sessionStorage->shouldReceive('getScopes')->andReturn([
(new ScopeEntity($server))->hydrate(['id' => 'foo']),
]);
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$accessTokenStorage->shouldReceive('create');
$accessTokenStorage->shouldReceive('associateScope');
$accessTokenStorage->shouldReceive('getScopes')->andReturn([
(new ScopeEntity($server))->hydrate(['id' => 'foo']),
]);
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$scopeStorage->shouldReceive('get')->andReturn(
(new ScopeEntity($server))->hydrate(['id' => 'foo'])
);
$authCodeStorage = M::mock('League\OAuth2\Server\Storage\AuthCodeInterface');
$authCodeStorage->shouldReceive('setServer');
$authCodeStorage->shouldReceive('delete');
$authCodeStorage->shouldReceive('get')->andReturn(
(new AuthCodeEntity($server))->setId('foobar')->setRedirectUri('http://foo/bar')->setExpireTime(time() + 300)
);
$authCodeStorage->shouldReceive('getScopes')->andReturn([
(new ScopeEntity($server))->hydrate(['id' => 'foo']),
]);
$refreshTokenStorage = M::mock('League\OAuth2\Server\Storage\RefreshTokenInterface');
$refreshTokenStorage->shouldReceive('setServer');
$refreshTokenStorage->shouldReceive('create');
$refreshTokenStorage->shouldReceive('associateScope');
$server->setClientStorage($clientStorage);
$server->setScopeStorage($scopeStorage);
$server->setSessionStorage($sessionStorage);
$server->setAccessTokenStorage($accessTokenStorage);
$server->setAuthCodeStorage($authCodeStorage);
$server->setRefreshTokenStorage($refreshTokenStorage);
$server->addGrantType($grant);
$server->addGrantType($rtgrant);
$server->issueAccessToken();
}
}

View File

@ -1,251 +0,0 @@
<?php
namespace LeagueTests\Grant;
use League\OAuth2\Server\AuthorizationServer;
use League\OAuth2\Server\Entity\ClientEntity;
use League\OAuth2\Server\Entity\ScopeEntity;
use League\OAuth2\Server\Entity\SessionEntity;
use League\OAuth2\Server\Grant\ClientCredentialsGrant;
use Mockery as M;
class ClientCredentialsGrantTest extends \PHPUnit_Framework_TestCase
{
public function testCompleteFlowMissingClientId()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidRequestException');
$_POST['grant_type'] = 'client_credentials';
$server = new AuthorizationServer();
$grant = new ClientCredentialsGrant();
$server->addGrantType($grant);
$server->issueAccessToken();
}
public function testCompleteFlowMissingClientSecret()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidRequestException');
$_POST = [
'grant_type' => 'client_credentials',
'client_id' => 'testapp',
];
$server = new AuthorizationServer();
$grant = new ClientCredentialsGrant();
$server->addGrantType($grant);
$server->issueAccessToken();
}
public function testCompleteFlowInvalidClient()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidClientException');
$_POST = [
'grant_type' => 'client_credentials',
'client_id' => 'testapp',
'client_secret' => 'foobar',
];
$server = new AuthorizationServer();
$grant = new ClientCredentialsGrant();
$clientStorage = M::mock('League\OAuth2\Server\Storage\ClientInterface');
$clientStorage->shouldReceive('setServer');
$clientStorage->shouldReceive('get')->andReturn(null);
$server->setClientStorage($clientStorage);
$server->addGrantType($grant);
$server->issueAccessToken();
}
public function testCompleteFlowInvalidScope()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidScopeException');
$_POST = [
'grant_type' => 'client_credentials',
'client_id' => 'testapp',
'client_secret' => 'foobar',
'scope' => 'foo',
];
$server = new AuthorizationServer();
$grant = new ClientCredentialsGrant();
$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('create');
$sessionStorage->shouldReceive('getScopes')->andReturn([]);
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$accessTokenStorage->shouldReceive('create');
$accessTokenStorage->shouldReceive('getScopes')->andReturn([]);
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$scopeStorage->shouldReceive('get')->andReturn(null);
$server->setClientStorage($clientStorage);
$server->setScopeStorage($scopeStorage);
$server->setSessionStorage($sessionStorage);
$server->setAccessTokenStorage($accessTokenStorage);
$server->addGrantType($grant);
$server->issueAccessToken();
}
public function testCompleteFlowNoScopes()
{
$_POST = [
'grant_type' => 'client_credentials',
'client_id' => 'testapp',
'client_secret' => 'foobar',
];
$server = new AuthorizationServer();
$grant = new ClientCredentialsGrant();
$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('create')->andreturn(123);
$sessionStorage->shouldReceive('getScopes')->shouldReceive('getScopes')->andReturn([]);
$sessionStorage->shouldReceive('getByAccessToken')->andReturn(
(new SessionEntity($server))->setId('foobar')
);
$sessionStorage->shouldReceive('associateScope');
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$accessTokenStorage->shouldReceive('create');
$accessTokenStorage->shouldReceive('getScopes')->andReturn([]);
$accessTokenStorage->shouldReceive('associateScope');
$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->addGrantType($grant);
$server->issueAccessToken();
}
public function testCompleteFlow()
{
$_POST = [
'grant_type' => 'client_credentials',
'client_id' => 'testapp',
'client_secret' => 'foobar',
'scope' => 'foo',
];
$server = new AuthorizationServer();
$grant = new ClientCredentialsGrant();
$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('create')->andreturn(123);
$sessionStorage->shouldReceive('getScopes')->shouldReceive('getScopes')->andReturn([
(new ScopeEntity($server))->hydrate(['id' => 'foo']),
]);
$sessionStorage->shouldReceive('getByAccessToken')->andReturn(
(new SessionEntity($server))->setId('foobar')
);
$sessionStorage->shouldReceive('associateScope');
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$accessTokenStorage->shouldReceive('create');
$accessTokenStorage->shouldReceive('getScopes')->andReturn([
(new ScopeEntity($server))->hydrate(['id' => 'foo']),
]);
$accessTokenStorage->shouldReceive('associateScope');
$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->addGrantType($grant);
$server->issueAccessToken();
}
public function testClientNotAuthorizedToUseGrant()
{
$this->setExpectedException('\League\OAuth2\Server\Exception\UnauthorizedClientException');
$_POST = [
'grant_type' => 'client_credentials',
'client_id' => 'testapp',
'client_secret' => 'foobar',
'scope' => 'foo',
];
$server = new AuthorizationServer();
$grant = new ClientCredentialsGrant();
$clientStorage = M::mock('League\OAuth2\Server\Storage\ClientInterface');
$clientStorage->shouldReceive('setServer');
$clientStorage->shouldReceive('get')->andThrow(
new \League\OAuth2\Server\Exception\UnauthorizedClientException()
);
$sessionStorage = M::mock('League\OAuth2\Server\Storage\SessionInterface');
$sessionStorage->shouldReceive('setServer');
$sessionStorage->shouldReceive('getByAccessToken')->andReturn(
(new SessionEntity($server))->setId('foobar')
);
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$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->addGrantType($grant);
$server->issueAccessToken();
}
}

View File

@ -1,479 +0,0 @@
<?php
namespace LeagueTests\Grant;
use League\OAuth2\Server\AuthorizationServer;
use League\OAuth2\Server\Entity\ClientEntity;
use League\OAuth2\Server\Entity\ScopeEntity;
use League\OAuth2\Server\Entity\SessionEntity;
use League\OAuth2\Server\Grant\PasswordGrant;
use League\OAuth2\Server\Grant\RefreshTokenGrant;
use Mockery as M;
class PasswordGrantTest extends \PHPUnit_Framework_TestCase
{
public function testCompleteFlowMissingClientId()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidRequestException');
$_POST['grant_type'] = 'password';
$server = new AuthorizationServer();
$grant = new PasswordGrant();
$server->addGrantType($grant);
$server->issueAccessToken();
}
public function testCompleteFlowMissingClientSecret()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidRequestException');
$_POST = [
'grant_type' => 'password',
'client_id' => 'testapp',
];
$server = new AuthorizationServer();
$grant = new PasswordGrant();
$server->addGrantType($grant);
$server->issueAccessToken();
}
public function testCompleteFlowInvalidClient()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidClientException');
$_POST = [
'grant_type' => 'password',
'client_id' => 'testapp',
'client_secret' => 'foobar',
];
$server = new AuthorizationServer();
$grant = new PasswordGrant();
$clientStorage = M::mock('League\OAuth2\Server\Storage\ClientInterface');
$clientStorage->shouldReceive('setServer');
$clientStorage->shouldReceive('get')->andReturn(null);
$server->setClientStorage($clientStorage);
$server->addGrantType($grant);
$server->issueAccessToken();
}
public function testNoUsername()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidRequestException');
$_POST = [
'grant_type' => 'password',
'client_id' => 'testapp',
'client_secret' => 'foobar',
];
$server = new AuthorizationServer();
$grant = new PasswordGrant();
$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('create');
$sessionStorage->shouldReceive('getScopes')->andReturn([]);
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$accessTokenStorage->shouldReceive('create');
$accessTokenStorage->shouldReceive('getScopes')->andReturn([]);
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$scopeStorage->shouldReceive('get')->andReturn(null);
$server->setClientStorage($clientStorage);
$server->setScopeStorage($scopeStorage);
$server->setSessionStorage($sessionStorage);
$server->setAccessTokenStorage($accessTokenStorage);
$server->addGrantType($grant);
$server->issueAccessToken();
}
public function testNoPassword()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidRequestException');
$_POST = [
'grant_type' => 'password',
'client_id' => 'testapp',
'client_secret' => 'foobar',
'username' => 'foo',
];
$server = new AuthorizationServer();
$grant = new PasswordGrant();
$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('create');
$sessionStorage->shouldReceive('getScopes')->andReturn([]);
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$accessTokenStorage->shouldReceive('create');
$accessTokenStorage->shouldReceive('getScopes')->andReturn([]);
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$scopeStorage->shouldReceive('get')->andReturn(null);
$server->setClientStorage($clientStorage);
$server->setScopeStorage($scopeStorage);
$server->setSessionStorage($sessionStorage);
$server->setAccessTokenStorage($accessTokenStorage);
$server->addGrantType($grant);
$server->issueAccessToken();
}
public function testNoCallable()
{
$this->setExpectedException('League\OAuth2\Server\Exception\ServerErrorException');
$_POST = [
'grant_type' => 'password',
'client_id' => 'testapp',
'client_secret' => 'foobar',
'username' => 'foo',
'password' => 'foobar',
];
$server = new AuthorizationServer();
$grant = new PasswordGrant();
$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('create');
$sessionStorage->shouldReceive('getScopes')->andReturn([]);
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$accessTokenStorage->shouldReceive('create');
$accessTokenStorage->shouldReceive('getScopes')->andReturn([]);
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$scopeStorage->shouldReceive('get')->andReturn(null);
$server->setClientStorage($clientStorage);
$server->setScopeStorage($scopeStorage);
$server->setSessionStorage($sessionStorage);
$server->setAccessTokenStorage($accessTokenStorage);
$server->addGrantType($grant);
$server->issueAccessToken();
}
public function testCompleteFlowInvalidScope()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidScopeException');
$_POST = [
'grant_type' => 'password',
'client_id' => 'testapp',
'client_secret' => 'foobar',
'username' => 'foo',
'password' => 'foobar',
'scope' => 'foo',
];
$server = new AuthorizationServer();
$grant = new PasswordGrant();
$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('create');
$sessionStorage->shouldReceive('getScopes')->andReturn([]);
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$accessTokenStorage->shouldReceive('create');
$accessTokenStorage->shouldReceive('getScopes')->andReturn([]);
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$scopeStorage->shouldReceive('get')->andReturn(null);
$server->setClientStorage($clientStorage);
$server->setScopeStorage($scopeStorage);
$server->setSessionStorage($sessionStorage);
$server->setAccessTokenStorage($accessTokenStorage);
$grant->setVerifyCredentialsCallback(function () {
return 123;
});
$server->addGrantType($grant);
$server->issueAccessToken();
}
public function testCompleteFlowNoScopes()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidRequestException');
$_POST = [
'grant_type' => 'password',
'client_id' => 'testapp',
'client_secret' => 'foobar',
'username' => 'username',
'password' => 'password',
];
$server = new AuthorizationServer();
$grant = new PasswordGrant();
$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('create')->andreturn(123);
$sessionStorage->shouldReceive('getScopes')->shouldReceive('getScopes')->andReturn([]);
$sessionStorage->shouldReceive('associateScope');
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$accessTokenStorage->shouldReceive('create');
$accessTokenStorage->shouldReceive('getScopes')->andReturn([]);
$accessTokenStorage->shouldReceive('associateScope');
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$server->setClientStorage($clientStorage);
$server->setScopeStorage($scopeStorage);
$server->setSessionStorage($sessionStorage);
$server->setAccessTokenStorage($accessTokenStorage);
$server->requireScopeParam(true);
$grant->setVerifyCredentialsCallback(function () {
return 123;
});
$server->addGrantType($grant);
$server->issueAccessToken();
}
public function testCompleteFlowInvalidCredentials()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidCredentialsException');
$_POST = [
'grant_type' => 'password',
'client_id' => 'testapp',
'client_secret' => 'foobar',
'scope' => 'foo',
'username' => 'username',
'password' => 'password',
];
$server = new AuthorizationServer();
$grant = new PasswordGrant();
$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('create')->andreturn(123);
$sessionStorage->shouldReceive('getScopes')->shouldReceive('getScopes')->andReturn([
(new ScopeEntity($server))->hydrate(['id' => 'foo']),
]);
$sessionStorage->shouldReceive('associateScope');
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$accessTokenStorage->shouldReceive('create');
$accessTokenStorage->shouldReceive('getScopes')->andReturn([
(new ScopeEntity($server))->hydrate(['id' => 'foo']),
]);
$accessTokenStorage->shouldReceive('associateScope');
$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);
$grant->setVerifyCredentialsCallback(function () {
return false;
});
$server->addGrantType($grant);
$server->issueAccessToken();
}
public function testCompleteFlow()
{
$_POST = [
'grant_type' => 'password',
'client_id' => 'testapp',
'client_secret' => 'foobar',
'scope' => 'foo',
'username' => 'username',
'password' => 'password',
];
$server = new AuthorizationServer();
$grant = new PasswordGrant();
$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('create')->andreturn(123);
$sessionStorage->shouldReceive('getScopes')->shouldReceive('getScopes')->andReturn([
(new ScopeEntity($server))->hydrate(['id' => 'foo']),
]);
$sessionStorage->shouldReceive('getByAccessToken')->andReturn(
(new SessionEntity($server))->setId('foobar')
);
$sessionStorage->shouldReceive('associateScope');
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$accessTokenStorage->shouldReceive('create');
$accessTokenStorage->shouldReceive('getScopes')->andReturn([
(new ScopeEntity($server))->hydrate(['id' => 'foo']),
]);
$accessTokenStorage->shouldReceive('associateScope');
$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);
$grant->setVerifyCredentialsCallback(function () {
return 123;
});
$server->addGrantType($grant);
$response = $server->issueAccessToken();
$this->assertTrue(array_key_exists('access_token', $response));
$this->assertTrue(array_key_exists('token_type', $response));
$this->assertTrue(array_key_exists('expires_in', $response));
}
public function testCompleteFlowRefreshToken()
{
$_POST = [
'grant_type' => 'password',
'client_id' => 'testapp',
'client_secret' => 'foobar',
'scope' => 'foo',
'username' => 'username',
'password' => 'password',
];
$server = new AuthorizationServer();
$grant = new PasswordGrant();
$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('create')->andreturn(123);
$sessionStorage->shouldReceive('getScopes')->shouldReceive('getScopes')->andReturn([
(new ScopeEntity($server))->hydrate(['id' => 'foo']),
]);
$sessionStorage->shouldReceive('getByAccessToken')->andReturn(
(new SessionEntity($server))->setId('foobar')
);
$sessionStorage->shouldReceive('associateScope');
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$accessTokenStorage->shouldReceive('create');
$accessTokenStorage->shouldReceive('getScopes')->andReturn([
(new ScopeEntity($server))->hydrate(['id' => 'foo']),
]);
$accessTokenStorage->shouldReceive('associateScope');
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$scopeStorage->shouldReceive('get')->andReturn(
(new ScopeEntity($server))->hydrate(['id' => 'foo'])
);
$refreshTokenStorage = M::mock('League\OAuth2\Server\Storage\RefreshTokenInterface');
$refreshTokenStorage->shouldReceive('setServer');
$refreshTokenStorage->shouldReceive('create');
$refreshTokenStorage->shouldReceive('associateScope');
$server->setClientStorage($clientStorage);
$server->setScopeStorage($scopeStorage);
$server->setSessionStorage($sessionStorage);
$server->setAccessTokenStorage($accessTokenStorage);
$server->setRefreshTokenStorage($refreshTokenStorage);
$grant->setVerifyCredentialsCallback(function () {
return 123;
});
$server->addGrantType($grant);
$server->addGrantType(new RefreshTokenGrant());
$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

@ -1,501 +0,0 @@
<?php
namespace LeagueTests\Grant;
use League\OAuth2\Server\AuthorizationServer;
use League\OAuth2\Server\Entity\AccessTokenEntity;
use League\OAuth2\Server\Entity\ClientEntity;
use League\OAuth2\Server\Entity\RefreshTokenEntity;
use League\OAuth2\Server\Entity\ScopeEntity;
use League\OAuth2\Server\Entity\SessionEntity;
use League\OAuth2\Server\Grant\RefreshTokenGrant;
use Mockery as M;
class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
{
public function testSetRefreshTokenTTL()
{
$grant = new RefreshTokenGrant();
$grant->setRefreshTokenTTL(86400);
$property = new \ReflectionProperty($grant, 'refreshTokenTTL');
$property->setAccessible(true);
$this->assertEquals(86400, $property->getValue($grant));
}
public function testCompleteFlowMissingClientId()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidRequestException');
$_POST['grant_type'] = 'refresh_token';
$server = new AuthorizationServer();
$grant = new RefreshTokenGrant();
$server->addGrantType($grant);
$server->issueAccessToken();
}
public function testCompleteFlowMissingClientSecret()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidRequestException');
$_POST = [
'grant_type' => 'refresh_token',
'client_id' => 'testapp',
];
$server = new AuthorizationServer();
$grant = new RefreshTokenGrant();
$server->addGrantType($grant);
$server->issueAccessToken();
}
public function testCompleteFlowInvalidClient()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidClientException');
$_POST = [
'grant_type' => 'refresh_token',
'client_id' => 'testapp',
'client_secret' => 'foobar',
];
$server = new AuthorizationServer();
$grant = new RefreshTokenGrant();
$clientStorage = M::mock('League\OAuth2\Server\Storage\ClientInterface');
$clientStorage->shouldReceive('setServer');
$clientStorage->shouldReceive('get')->andReturn(null);
$server->setClientStorage($clientStorage);
$server->addGrantType($grant);
$server->issueAccessToken();
}
public function testCompleteFlowMissingRefreshToken()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidRequestException');
$_POST = [
'grant_type' => 'refresh_token',
'client_id' => 'testapp',
'client_secret' => 'foobar',
];
$server = new AuthorizationServer();
$grant = new RefreshTokenGrant();
$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');
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$server->setClientStorage($clientStorage);
$server->setScopeStorage($scopeStorage);
$server->setSessionStorage($sessionStorage);
$server->requireScopeParam(true);
$server->addGrantType($grant);
$server->issueAccessToken();
}
public function testCompleteFlowInvalidRefreshToken()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidRefreshException');
$_POST = [
'grant_type' => 'refresh_token',
'client_id' => 'testapp',
'client_secret' => 'foobar',
'refresh_token' => 'meh',
];
$server = new AuthorizationServer();
$grant = new RefreshTokenGrant();
$clientStorage = M::mock('League\OAuth2\Server\Storage\ClientInterface');
$clientStorage->shouldReceive('setServer');
$clientStorage->shouldReceive('get')->andReturn(
(new ClientEntity($server))->hydrate(['id' => 'testapp'])
);
$refreshTokenStorage = M::mock('League\OAuth2\Server\Storage\RefreshTokenInterface');
$refreshTokenStorage->shouldReceive('get');
$refreshTokenStorage->shouldReceive('setServer');
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$server->setClientStorage($clientStorage);
$server->setScopeStorage($scopeStorage);
$server->setRefreshTokenStorage($refreshTokenStorage);
$server->requireScopeParam(true);
$server->addGrantType($grant);
$server->issueAccessToken();
}
public function testCompleteFlowExistingScopes()
{
$_POST = [
'grant_type' => 'refresh_token',
'client_id' => 'testapp',
'client_secret' => 'foobar',
'refresh_token' => 'refresh_token',
];
$server = new AuthorizationServer();
$grant = new RefreshTokenGrant();
$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))->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));
}
public function testCompleteFlowRequestScopes()
{
$_POST = [
'grant_type' => 'refresh_token',
'client_id' => 'testapp',
'client_secret' => 'foobar',
'refresh_token' => 'refresh_token',
'scope' => 'foo',
];
$server = new AuthorizationServer();
$grant = new RefreshTokenGrant();
$oldSession = (new SessionEntity($server))->associateScope((new ScopeEntity($server))->hydrate(['id' => 'foo']));
$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(
$oldSession
);
$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))->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(isset($response['access_token']));
$this->assertTrue(isset($response['refresh_token']));
$this->assertTrue(isset($response['token_type']));
$this->assertTrue(isset($response['expires_in']));
}
public function testCompleteFlowExpiredRefreshToken()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidRefreshException');
$_POST = [
'grant_type' => 'refresh_token',
'client_id' => 'testapp',
'client_secret' => 'foobar',
'refresh_token' => 'refresh_token',
'scope' => 'foo',
];
$server = new AuthorizationServer();
$grant = new RefreshTokenGrant();
$oldSession = (new SessionEntity($server))->associateScope((new ScopeEntity($server))->hydrate(['id' => 'foo']));
$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(
$oldSession
);
$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))
);
$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);
$server->issueAccessToken();
}
public function testCompleteFlowRequestScopesInvalid()
{
$_POST = [
'grant_type' => 'refresh_token',
'client_id' => 'testapp',
'client_secret' => 'foobar',
'refresh_token' => 'refresh_token',
'scope' => 'blah',
];
$server = new AuthorizationServer();
$grant = new RefreshTokenGrant();
$oldSession = (new SessionEntity($server))->associateScope((new ScopeEntity($server))->hydrate(['id' => 'foo']));
$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(
$oldSession
);
$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))->setExpireTime(time() + 86400)
);
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$scopeStorage->shouldReceive('get')->andReturn(
(new ScopeEntity($server))->hydrate(['id' => 'blah'])
);
$server->setClientStorage($clientStorage);
$server->setScopeStorage($scopeStorage);
$server->setSessionStorage($sessionStorage);
$server->setAccessTokenStorage($accessTokenStorage);
$server->setRefreshTokenStorage($refreshTokenStorage);
$server->addGrantType($grant);
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidScopeException');
$server->issueAccessToken();
}
public function testCompleteFlowRotateRefreshToken()
{
$_POST = [
'grant_type' => 'refresh_token',
'client_id' => 'testapp',
'client_secret' => 'foobar',
'refresh_token' => 'refresh_token',
];
$server = new AuthorizationServer();
$grant = new RefreshTokenGrant();
$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));
$this->assertNotEquals($response['refresh_token'], $_POST['refresh_token']);
$grant->setRefreshTokenRotation(false);
$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));
$this->assertEquals($response['refresh_token'], $_POST['refresh_token']);
}
}

View File

@ -1,226 +0,0 @@
<?php
namespace LeagueTests;
use League\OAuth2\Server\Entity\AccessTokenEntity;
use League\OAuth2\Server\Entity\ClientEntity;
use League\OAuth2\Server\Entity\ScopeEntity;
use League\OAuth2\Server\Entity\SessionEntity;
use League\OAuth2\Server\ResourceServer;
use Mockery as M;
class ResourceServerTest extends \PHPUnit_Framework_TestCase
{
private function returnDefault()
{
$sessionStorage = M::mock('League\OAuth2\Server\Storage\SessionInterface');
$sessionStorage->shouldReceive('setServer');
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$clientStorage = M::mock('League\OAuth2\Server\Storage\ClientInterface');
$clientStorage->shouldReceive('setServer');
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$server = new ResourceServer(
$sessionStorage,
$accessTokenStorage,
$clientStorage,
$scopeStorage
);
return $server;
}
public function testGetSet()
{
$sessionStorage = M::mock('League\OAuth2\Server\Storage\SessionInterface');
$sessionStorage->shouldReceive('setServer');
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$clientStorage = M::mock('League\OAuth2\Server\Storage\ClientInterface');
$clientStorage->shouldReceive('setServer');
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$server = new ResourceServer(
$sessionStorage,
$accessTokenStorage,
$clientStorage,
$scopeStorage
);
}
public function testDetermineAccessTokenMissingToken()
{
$this->setExpectedException('League\OAuth2\Server\Exception\InvalidRequestException');
$sessionStorage = M::mock('League\OAuth2\Server\Storage\SessionInterface');
$sessionStorage->shouldReceive('setServer');
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$accessTokenStorage->shouldReceive('get')->andReturn(false);
$clientStorage = M::mock('League\OAuth2\Server\Storage\ClientInterface');
$clientStorage->shouldReceive('setServer');
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$server = new ResourceServer(
$sessionStorage,
$accessTokenStorage,
$clientStorage,
$scopeStorage
);
$request = new \Symfony\Component\HttpFoundation\Request();
$request->headers = new \Symfony\Component\HttpFoundation\ParameterBag([
'HTTP_AUTHORIZATION' => 'Bearer',
]);
$server->setRequest($request);
$reflector = new \ReflectionClass($server);
$method = $reflector->getMethod('determineAccessToken');
$method->setAccessible(true);
$method->invoke($server);
}
public function testIsValidNotValid()
{
$sessionStorage = M::mock('League\OAuth2\Server\Storage\SessionInterface');
$sessionStorage->shouldReceive('setServer');
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$accessTokenStorage->shouldReceive('get')->andReturn(false);
$clientStorage = M::mock('League\OAuth2\Server\Storage\ClientInterface');
$clientStorage->shouldReceive('setServer');
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$server = new ResourceServer(
$sessionStorage,
$accessTokenStorage,
$clientStorage,
$scopeStorage
);
$this->setExpectedException('League\OAuth2\Server\Exception\AccessDeniedException');
$server->isValidRequest(false, 'foobar');
}
public function testIsValid()
{
$sessionStorage = M::mock('League\OAuth2\Server\Storage\SessionInterface');
$sessionStorage->shouldReceive('setServer');
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$clientStorage = M::mock('League\OAuth2\Server\Storage\ClientInterface');
$clientStorage->shouldReceive('setServer');
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$server = new ResourceServer(
$sessionStorage,
$accessTokenStorage,
$clientStorage,
$scopeStorage
);
$server->setIdKey('at');
$server->addEventListener('session.owner', function ($event) {
$this->assertTrue($event->getSession() instanceof \League\OAuth2\Server\Entity\SessionEntity);
});
$accessTokenStorage->shouldReceive('get')->andReturn(
(new AccessTokenEntity($server))->setId('abcdef')->setExpireTime(time() + 300)
);
$accessTokenStorage->shouldReceive('getScopes')->andReturn([
(new ScopeEntity($server))->hydrate(['id' => 'foo']),
(new ScopeEntity($server))->hydrate(['id' => 'bar']),
]);
$sessionStorage->shouldReceive('getByAccessToken')->andReturn(
(new SessionEntity($server))->setId('foobar')->setOwner('user', 123)
);
$clientStorage->shouldReceive('getBySession')->andReturn(
(new ClientEntity($server))->hydrate(['id' => 'testapp'])
);
$request = new \Symfony\Component\HttpFoundation\Request();
$request->headers = new \Symfony\Component\HttpFoundation\ParameterBag([
'Authorization' => 'Bearer abcdef',
]);
$server->setRequest($request);
$this->assertTrue($server->isValidRequest());
$this->assertEquals('abcdef', $server->getAccessToken());
}
/**
* @expectedException League\OAuth2\Server\Exception\AccessDeniedException
*/
public function testIsValidExpiredToken()
{
$sessionStorage = M::mock('League\OAuth2\Server\Storage\SessionInterface');
$sessionStorage->shouldReceive('setServer');
$accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface');
$accessTokenStorage->shouldReceive('setServer');
$clientStorage = M::mock('League\OAuth2\Server\Storage\ClientInterface');
$clientStorage->shouldReceive('setServer');
$scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
$scopeStorage->shouldReceive('setServer');
$server = new ResourceServer(
$sessionStorage,
$accessTokenStorage,
$clientStorage,
$scopeStorage
);
$server->setIdKey('at');
$server->addEventListener('session.owner', function ($event) {
$this->assertTrue($event->getSession() instanceof \League\OAuth2\Server\Entity\SessionEntity);
});
$accessTokenStorage->shouldReceive('get')->andReturn(
(new AccessTokenEntity($server))->setId('abcdef')->setExpireTime(time() - 300)
);
$accessTokenStorage->shouldReceive('getScopes')->andReturn([
(new ScopeEntity($server))->hydrate(['id' => 'foo']),
(new ScopeEntity($server))->hydrate(['id' => 'bar']),
]);
$sessionStorage->shouldReceive('getByAccessToken')->andReturn(
(new SessionEntity($server))->setId('foobar')->setOwner('user', 123)
);
$clientStorage->shouldReceive('getBySession')->andReturn(
(new ClientEntity($server))->hydrate(['id' => 'testapp'])
);
$request = new \Symfony\Component\HttpFoundation\Request();
$request->headers = new \Symfony\Component\HttpFoundation\ParameterBag([
'Authorization' => 'Bearer abcdef',
]);
$server->setRequest($request);
$server->isValidRequest();
}
}

View File

@ -1,23 +0,0 @@
<?php
namespace LeagueTests\Storage;
use LeagueTests\Stubs\StubAbstractServer;
use LeagueTests\Stubs\StubAbstractStorage;
class AbstractStorageTest extends \PHPUnit_Framework_TestCase
{
public function testSetGet()
{
$storage = new StubAbstractStorage();
$reflector = new \ReflectionClass($storage);
$setMethod = $reflector->getMethod('setServer');
$setMethod->setAccessible(true);
$setMethod->invokeArgs($storage, [new StubAbstractServer()]);
$getMethod = $reflector->getMethod('getServer');
$getMethod->setAccessible(true);
$this->assertTrue($getMethod->invoke($storage) instanceof StubAbstractServer);
}
}

View File

@ -1,18 +0,0 @@
<?php
namespace LeagueTests\Stubs;
class StubAbstractGrant extends \League\OAuth2\Server\Grant\AbstractGrant
{
protected $responseType = 'foobar';
public function completeFlow()
{
return true;
}
public function getAuthorizationServer()
{
return $this->server;
}
}

Some files were not shown because too many files have changed in this diff Show More