mirror of
https://github.com/elyby/oauth2-server.git
synced 2025-05-31 14:12:07 +05:30
Compare commits
96 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f9bde23799 | ||
|
|
2328f59601 | ||
|
|
103b0cc50d | ||
|
|
eb7526ae97 | ||
|
|
03e8eb6157 | ||
|
|
7b803365f9 | ||
|
|
204706f1ff | ||
|
|
4c6dab3f55 | ||
|
|
54bedda11b | ||
|
|
883ba8b573 | ||
|
|
0d1e61422a | ||
|
|
a722659200 | ||
|
|
a80310b01c | ||
|
|
c017b59342 | ||
|
|
920c0c296a | ||
|
|
b0db04461f | ||
|
|
495b55d1e8 | ||
|
|
92a483b3bd | ||
|
|
6083870603 | ||
|
|
6359535e32 | ||
|
|
5969082963 | ||
|
|
7a6d9a4510 | ||
|
|
7c86d3b848 | ||
|
|
d3a7b442ce | ||
|
|
ba30e34511 | ||
|
|
e24dff2723 | ||
|
|
625876f7ae | ||
|
|
4f2dfc20b9 | ||
|
|
1512960d92 | ||
|
|
273ea0ba68 | ||
|
|
096a4a2883 | ||
|
|
a68f07f734 | ||
|
|
a0c4900ee7 | ||
|
|
4c0c10ae98 | ||
|
|
0fb0100088 | ||
|
|
8f50e58ba9 | ||
|
|
8225b4e697 | ||
|
|
236a3a0358 | ||
|
|
b00a4e169e | ||
|
|
c034c3b13c | ||
|
|
287c371586 | ||
|
|
634578997f | ||
|
|
b8c5056c31 | ||
|
|
79aa1988d8 | ||
|
|
7c35985c1e | ||
|
|
c75d0e0f0e | ||
|
|
5d3516c7b4 | ||
|
|
d4fb00628e | ||
|
|
4bc835c007 | ||
|
|
fdb1d70874 | ||
|
|
6f71a2d178 | ||
|
|
651709b70f | ||
|
|
3f6e91575d | ||
|
|
8f5e0ce9f7 | ||
|
|
5410a42bb6 | ||
|
|
b7064befe4 | ||
|
|
44937f3600 | ||
|
|
76ea6b5a6c | ||
|
|
4689802c30 | ||
|
|
6ee71754c4 | ||
|
|
b3329dbeac | ||
|
|
0ca2511d1e | ||
|
|
2c2ef800d4 | ||
|
|
d8d49f742e | ||
|
|
e758121458 | ||
|
|
47656cd9b5 | ||
|
|
b59106dc64 | ||
|
|
c6faa228fe | ||
|
|
4eee48ca4e | ||
|
|
00518dded7 | ||
|
|
3615cbeedf | ||
|
|
6773db66c6 | ||
|
|
5ca2152313 | ||
|
|
5cba35456f | ||
|
|
be9bd76f35 | ||
|
|
3c0a7f14ab | ||
|
|
198f4c4b6f | ||
|
|
6f0a0cca4e | ||
|
|
5430ddb230 | ||
|
|
1ccfd9be32 | ||
|
|
a83c56f570 | ||
|
|
d7dd07cf18 | ||
|
|
0fed56a265 | ||
|
|
fc9e912e06 | ||
|
|
39281a6f38 | ||
|
|
656a8d7a56 | ||
|
|
6c942f25f4 | ||
|
|
8274c56fc2 | ||
|
|
de8f6ff539 | ||
|
|
8f69f4f9a9 | ||
|
|
4d2ccac8ed | ||
|
|
a38b7f97f9 | ||
|
|
197657f2b9 | ||
|
|
e513b42117 | ||
|
|
b1ce1f872b | ||
|
|
d8e1e0e00e |
13
CHANGELOG.md
13
CHANGELOG.md
@@ -1,5 +1,18 @@
|
||||
# Changelog
|
||||
|
||||
## 5.0.0-RC2 (released 2016-04-XX)
|
||||
|
||||
* Allow multiple client redirect URIs (Issue #511)
|
||||
* Remove unused mac token interface (Issue #503)
|
||||
* Handle RSA key passphrase (Issue #502)
|
||||
* Remove access token repository from response types (Issue #501)
|
||||
* Remove unnecessary methods from entity interfaces (Issue #490)
|
||||
* Ensure incoming JWT hasn't expired (Issue #509)
|
||||
* Fix client identifier passed where user identifier is expected (Issue #498)
|
||||
* Removed built-in entities; added traits to for quick re-use (Issue #504)
|
||||
* Redirect uri is required only if the "redirect_uri" parameter was included in the authorization request (Issue #514)
|
||||
* Removed templating for auth code and implicit grants (Issue #499)
|
||||
|
||||
## 5.0.0-RC1 (release 2016-03-24)
|
||||
|
||||
Version 5 is a complete code rewrite.
|
||||
|
||||
17
README.md
17
README.md
@@ -1,4 +1,4 @@
|
||||
# PHP OAuth 2.0 Server by [@alexbilbie](https://twitter.com/alexbilbie)
|
||||
# PHP OAuth 2.0 Server
|
||||
|
||||
[](https://github.com/thephpleague/oauth2-server/releases)
|
||||
[](LICENSE.md)
|
||||
@@ -17,14 +17,7 @@ It supports out of the box the following grants:
|
||||
* Resource owner password credentials grant
|
||||
* Refresh grant
|
||||
|
||||
You can also easily define your own grants.
|
||||
|
||||
In addition it supports the following token response types:
|
||||
|
||||
* Bearer (JWT) tokens
|
||||
* MAC tokens
|
||||
|
||||
You can also create you own tokens.
|
||||
This library was created by Alex Bilbie. Find him on Twitter at [@alexbilbie](https://twitter.com/alexbilbie).
|
||||
|
||||
## Requirements
|
||||
|
||||
@@ -35,10 +28,12 @@ The following versions of PHP are supported:
|
||||
* PHP 7.0
|
||||
* HHVM
|
||||
|
||||
The `openssl` extension is also required.
|
||||
|
||||
## Documentation
|
||||
|
||||
The library documentation can be found at [http://oauth2.thephpleague.com](http://oauth2.thephpleague.com).
|
||||
You can contribute to this documentation in the [gh-pages branch](https://github.com/thephpleague/oauth2-server/tree/gh-pages/).
|
||||
The library documentation can be found at [https://oauth2.thephpleague.com](https://oauth2.thephpleague.com).
|
||||
You can contribute to the documentation in the [gh-pages branch](https://github.com/thephpleague/oauth2-server/tree/gh-pages/).
|
||||
|
||||
## Changelog
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
{
|
||||
"name": "league/oauth2-server",
|
||||
"description": "A lightweight and powerful OAuth 2.0 authorization and resource server library with support for all the core specification grants. This library will allow you to secure your API with OAuth and allow your applications users to approve apps that want to access their data from your API.",
|
||||
"homepage": "http://oauth2.thephpleague.com/",
|
||||
"homepage": "https://oauth2.thephpleague.com/",
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": ">=5.5.9",
|
||||
"ext-openssl": "*",
|
||||
"league/event": "^2.1",
|
||||
"lcobucci/jwt": "^3.1",
|
||||
"paragonie/random_compat": "^1.1",
|
||||
@@ -12,7 +13,6 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8",
|
||||
"league/plates": "^3.1",
|
||||
"zendframework/zend-diactoros": "^1.0"
|
||||
},
|
||||
"repositories": [
|
||||
@@ -63,11 +63,5 @@
|
||||
"branch-alias": {
|
||||
"dev-V5-WIP": "5.0-dev"
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
"league/plates": "Used for parsing authorization code templates",
|
||||
"twig/twig": "Used for parsing authorization code templates",
|
||||
"smarty/smarty": "Used for parsing authorization code templates",
|
||||
"mustache/mustache": "Used for parsing authorization code templates"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
],
|
||||
"require": {
|
||||
"slim/slim": "3.0.*",
|
||||
"league/oauth2-server": "dev-V5-WIP",
|
||||
"league/plates": "^3.1"
|
||||
"league/oauth2-server": "dev-V5-WIP"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
||||
18
examples/composer.lock
generated
18
examples/composer.lock
generated
@@ -4,8 +4,8 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "143453cc35e7f499b130b6460222dc5a",
|
||||
"content-hash": "1ea46581fb6db25f323a37a45ef74f95",
|
||||
"hash": "ec2df46ff78a00052e1a241ce5988d81",
|
||||
"content-hash": "46a1c1e42c62d3e3645279fc54ae95b7",
|
||||
"packages": [
|
||||
{
|
||||
"name": "container-interop/container-interop",
|
||||
@@ -36,16 +36,16 @@
|
||||
},
|
||||
{
|
||||
"name": "lcobucci/jwt",
|
||||
"version": "3.1.0",
|
||||
"version": "3.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/lcobucci/jwt.git",
|
||||
"reference": "31499db4e692b343cec7ff345932899f98fde1cf"
|
||||
"reference": "afea8e682e911a21574fd8519321b32522fa25b5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/lcobucci/jwt/zipball/31499db4e692b343cec7ff345932899f98fde1cf",
|
||||
"reference": "31499db4e692b343cec7ff345932899f98fde1cf",
|
||||
"url": "https://api.github.com/repos/lcobucci/jwt/zipball/afea8e682e911a21574fd8519321b32522fa25b5",
|
||||
"reference": "afea8e682e911a21574fd8519321b32522fa25b5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -90,7 +90,7 @@
|
||||
"JWS",
|
||||
"jwt"
|
||||
],
|
||||
"time": "2015-11-15 01:42:47"
|
||||
"time": "2016-03-24 22:46:13"
|
||||
},
|
||||
{
|
||||
"name": "league/event",
|
||||
@@ -144,11 +144,11 @@
|
||||
},
|
||||
{
|
||||
"name": "league/oauth2-server",
|
||||
"version": "dev-V5-WIP",
|
||||
"version": "dev-V5-authorization-request-flow",
|
||||
"dist": {
|
||||
"type": "path",
|
||||
"url": "../",
|
||||
"reference": "0fbe109e2004c71feac2bd14fd85aff97704b2e5",
|
||||
"reference": "5410a42bb66f5a61969c3ec1a8e7ab30d225875c",
|
||||
"shasum": null
|
||||
},
|
||||
"require": {
|
||||
|
||||
@@ -2,13 +2,14 @@
|
||||
|
||||
use League\OAuth2\Server\Exception\OAuthServerException;
|
||||
use League\OAuth2\Server\Grant\AuthCodeGrant;
|
||||
use League\OAuth2\Server\RequestTypes\AuthorizationRequest;
|
||||
use League\OAuth2\Server\Server;
|
||||
use OAuth2ServerExamples\Entities\UserEntity;
|
||||
use OAuth2ServerExamples\Repositories\AccessTokenRepository;
|
||||
use OAuth2ServerExamples\Repositories\AuthCodeRepository;
|
||||
use OAuth2ServerExamples\Repositories\ClientRepository;
|
||||
use OAuth2ServerExamples\Repositories\RefreshTokenRepository;
|
||||
use OAuth2ServerExamples\Repositories\ScopeRepository;
|
||||
use OAuth2ServerExamples\Repositories\UserRepository;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Slim\App;
|
||||
@@ -27,7 +28,6 @@ $app = new App([
|
||||
$accessTokenRepository = new AccessTokenRepository();
|
||||
$authCodeRepository = new AuthCodeRepository();
|
||||
$refreshTokenRepository = new RefreshTokenRepository();
|
||||
$userRepository = new UserRepository();
|
||||
|
||||
$privateKeyPath = 'file://' . __DIR__ . '/../private.key';
|
||||
$publicKeyPath = 'file://' . __DIR__ . '/../public.key';
|
||||
@@ -46,7 +46,6 @@ $app = new App([
|
||||
new AuthCodeGrant(
|
||||
$authCodeRepository,
|
||||
$refreshTokenRepository,
|
||||
$userRepository,
|
||||
new \DateInterval('PT10M')
|
||||
),
|
||||
new \DateInterval('PT1H')
|
||||
@@ -56,12 +55,24 @@ $app = new App([
|
||||
},
|
||||
]);
|
||||
|
||||
$app->any('/authorize', function (ServerRequestInterface $request, ResponseInterface $response) use ($app) {
|
||||
$app->get('/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);
|
||||
// Validate the HTTP request and return an AuthorizationRequest object.
|
||||
// The auth request object can be serialized into a user's session
|
||||
$authRequest = $server->validateAuthorizationRequest($request);
|
||||
|
||||
// Once the user has logged in set the user on the AuthorizationRequest
|
||||
$authRequest->setUser(new UserEntity());
|
||||
|
||||
// Once the user has approved or denied the client update the status
|
||||
// (true = approved, false = denied)
|
||||
$authRequest->setAuthorizationApproved(true);
|
||||
|
||||
// Return the HTTP redirect response
|
||||
return $server->completeAuthorizationRequest($authRequest, $response);
|
||||
} catch (OAuthServerException $exception) {
|
||||
return $exception->generateHttpResponse($response);
|
||||
} catch (\Exception $exception) {
|
||||
@@ -77,7 +88,7 @@ $app->post('/access_token', function (ServerRequestInterface $request, ResponseI
|
||||
$server = $app->getContainer()->get(Server::class);
|
||||
|
||||
try {
|
||||
return $server->respondToRequest($request, $response);
|
||||
return $server->respondToAccessTokenRequest($request, $response);
|
||||
} catch (OAuthServerException $exception) {
|
||||
return $exception->generateHttpResponse($response);
|
||||
} catch (\Exception $exception) {
|
||||
|
||||
@@ -50,7 +50,7 @@ $app->post('/access_token', function (ServerRequestInterface $request, ResponseI
|
||||
$server = $app->getContainer()->get(Server::class);
|
||||
|
||||
try {
|
||||
return $server->respondToRequest($request, $response);
|
||||
return $server->respondToAccessTokenRequest($request, $response);
|
||||
} catch (OAuthServerException $exception) {
|
||||
return $exception->generateHttpResponse($response);
|
||||
} catch (\Exception $exception) {
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
use League\OAuth2\Server\Exception\OAuthServerException;
|
||||
use League\OAuth2\Server\Grant\ImplicitGrant;
|
||||
use League\OAuth2\Server\Server;
|
||||
use OAuth2ServerExamples\Entities\UserEntity;
|
||||
use OAuth2ServerExamples\Repositories\AccessTokenRepository;
|
||||
use OAuth2ServerExamples\Repositories\ClientRepository;
|
||||
use OAuth2ServerExamples\Repositories\ScopeRepository;
|
||||
use OAuth2ServerExamples\Repositories\UserRepository;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Slim\App;
|
||||
@@ -23,7 +23,6 @@ $app = new App([
|
||||
$clientRepository = new ClientRepository();
|
||||
$scopeRepository = new ScopeRepository();
|
||||
$accessTokenRepository = new AccessTokenRepository();
|
||||
$userRepository = new UserRepository();
|
||||
|
||||
$privateKeyPath = 'file://' . __DIR__ . '/../private.key';
|
||||
$publicKeyPath = 'file://' . __DIR__ . '/../public.key';
|
||||
@@ -38,21 +37,30 @@ $app = new App([
|
||||
);
|
||||
|
||||
// Enable the implicit grant on the server with a token TTL of 1 hour
|
||||
$server->enableGrantType(
|
||||
new ImplicitGrant($userRepository),
|
||||
new \DateInterval('PT1H')
|
||||
);
|
||||
$server->enableGrantType(new ImplicitGrant(new \DateInterval('PT1H')));
|
||||
|
||||
return $server;
|
||||
},
|
||||
]);
|
||||
|
||||
$app->any('/authorize', function (ServerRequestInterface $request, ResponseInterface $response) use ($app) {
|
||||
$app->get('/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);
|
||||
// Validate the HTTP request and return an AuthorizationRequest object.
|
||||
// The auth request object can be serialized into a user's session
|
||||
$authRequest = $server->validateAuthorizationRequest($request);
|
||||
|
||||
// Once the user has logged in set the user on the AuthorizationRequest
|
||||
$authRequest->setUser(new UserEntity());
|
||||
|
||||
// Once the user has approved or denied the client update the status
|
||||
// (true = approved, false = denied)
|
||||
$authRequest->setAuthorizationApproved(true);
|
||||
|
||||
// Return the HTTP redirect response
|
||||
return $server->completeAuthorizationRequest($authRequest, $response);
|
||||
} catch (OAuthServerException $exception) {
|
||||
return $exception->generateHttpResponse($response);
|
||||
} catch (\Exception $exception) {
|
||||
|
||||
@@ -54,7 +54,7 @@ $app->post('/access_token', function (ServerRequestInterface $request, ResponseI
|
||||
$server = $app->getContainer()->get(Server::class);
|
||||
|
||||
try {
|
||||
return $server->respondToRequest($request, $response);
|
||||
return $server->respondToAccessTokenRequest($request, $response);
|
||||
} catch (OAuthServerException $exception) {
|
||||
return $exception->generateHttpResponse($response);
|
||||
} catch (\Exception $exception) {
|
||||
|
||||
@@ -52,7 +52,7 @@ $app->post('/access_token', function (ServerRequestInterface $request, ResponseI
|
||||
$server = $app->getContainer()->get(Server::class);
|
||||
|
||||
try {
|
||||
return $server->respondToRequest($request, $response);
|
||||
return $server->respondToAccessTokenRequest($request, $response);
|
||||
} catch (OAuthServerException $exception) {
|
||||
return $exception->generateHttpResponse($response);
|
||||
} catch (\Exception $exception) {
|
||||
|
||||
13
examples/src/Entities/AccessTokenEntity.php
Normal file
13
examples/src/Entities/AccessTokenEntity.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace OAuth2ServerExamples\Entities;
|
||||
|
||||
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\Traits\AccessTokenTrait;
|
||||
use League\OAuth2\Server\Entities\Traits\EntityTrait;
|
||||
use League\OAuth2\Server\Entities\Traits\TokenEntityTrait;
|
||||
|
||||
class AccessTokenEntity implements AccessTokenEntityInterface
|
||||
{
|
||||
use AccessTokenTrait, TokenEntityTrait, EntityTrait;
|
||||
}
|
||||
13
examples/src/Entities/AuthCodeEntity.php
Normal file
13
examples/src/Entities/AuthCodeEntity.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace OAuth2ServerExamples\Entities;
|
||||
|
||||
use League\OAuth2\Server\Entities\AuthCodeEntityInterface;
|
||||
use League\OAuth2\Server\Entities\Traits\AuthCodeTrait;
|
||||
use League\OAuth2\Server\Entities\Traits\EntityTrait;
|
||||
use League\OAuth2\Server\Entities\Traits\TokenEntityTrait;
|
||||
|
||||
class AuthCodeEntity implements AuthCodeEntityInterface
|
||||
{
|
||||
use EntityTrait, TokenEntityTrait, AuthCodeTrait;
|
||||
}
|
||||
@@ -2,84 +2,21 @@
|
||||
|
||||
namespace OAuth2ServerExamples\Entities;
|
||||
|
||||
use League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface;
|
||||
use League\OAuth2\Server\Entities\ClientEntityInterface;
|
||||
use League\OAuth2\Server\Entities\Traits\ClientTrait;
|
||||
use League\OAuth2\Server\Entities\Traits\EntityTrait;
|
||||
|
||||
class ClientEntity implements ClientEntityInterface
|
||||
{
|
||||
use EntityTrait;
|
||||
use EntityTrait, ClientTrait;
|
||||
|
||||
private $name;
|
||||
|
||||
private $secret;
|
||||
|
||||
private $redirectUri;
|
||||
|
||||
/**
|
||||
* Get the client's name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the client's name.
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $secret
|
||||
*/
|
||||
public function setSecret($secret)
|
||||
public function setRedirectUri($uri)
|
||||
{
|
||||
$this->secret = $secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the hashed client secret
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSecret()
|
||||
{
|
||||
return $this->secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the client's redirect uri.
|
||||
*
|
||||
* @param string $redirectUri
|
||||
*/
|
||||
public function setRedirectUri($redirectUri)
|
||||
{
|
||||
$this->redirectUri = $redirectUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the registered redirect URI.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRedirectUri()
|
||||
{
|
||||
return $this->redirectUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the client is capable of keeping it's secrets secret.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canKeepASecret()
|
||||
{
|
||||
return $this->secret !== null;
|
||||
$this->redirectUri = $uri;
|
||||
}
|
||||
}
|
||||
|
||||
12
examples/src/Entities/RefreshTokenEntity.php
Normal file
12
examples/src/Entities/RefreshTokenEntity.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace OAuth2ServerExamples\Entities;
|
||||
|
||||
use League\OAuth2\Server\Entities\RefreshTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\Traits\EntityTrait;
|
||||
use League\OAuth2\Server\Entities\Traits\RefreshTokenTrait;
|
||||
|
||||
class RefreshTokenEntity implements RefreshTokenEntityInterface
|
||||
{
|
||||
use RefreshTokenTrait, EntityTrait;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace OAuth2ServerExamples\Entities;
|
||||
|
||||
use League\OAuth2\Server\Entities\Interfaces\ScopeEntityInterface;
|
||||
use League\OAuth2\Server\Entities\ScopeEntityInterface;
|
||||
use League\OAuth2\Server\Entities\Traits\EntityTrait;
|
||||
|
||||
class ScopeEntity implements ScopeEntityInterface
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace OAuth2ServerExamples\Entities;
|
||||
|
||||
use League\OAuth2\Server\Entities\Interfaces\UserEntityInterface;
|
||||
use League\OAuth2\Server\Entities\UserEntityInterface;
|
||||
|
||||
class UserEntity implements UserEntityInterface
|
||||
{
|
||||
|
||||
@@ -2,40 +2,49 @@
|
||||
|
||||
namespace OAuth2ServerExamples\Repositories;
|
||||
|
||||
use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\ClientEntityInterface;
|
||||
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
|
||||
use OAuth2ServerExamples\Entities\AccessTokenEntity;
|
||||
|
||||
class AccessTokenRepository implements AccessTokenRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* Persists a new access token to permanent storage.
|
||||
*
|
||||
* @param \League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface $accessTokenEntity
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function persistNewAccessToken(AccessTokenEntityInterface $accessTokenEntity)
|
||||
{
|
||||
// TODO: Implement persistNewAccessToken() method.
|
||||
// Some logic here to save the access token to a database
|
||||
}
|
||||
|
||||
/**
|
||||
* Revoke an access token.
|
||||
*
|
||||
* @param string $tokenId
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function revokeAccessToken($tokenId)
|
||||
{
|
||||
// TODO: Implement revokeAccessToken() method.
|
||||
// Some logic here to revoke the access token
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the access token has been revoked.
|
||||
*
|
||||
* @param string $tokenId
|
||||
*
|
||||
* @return bool Return true if this token has been revoked
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isAccessTokenRevoked($tokenId)
|
||||
{
|
||||
// TODO: Implement isAccessTokenRevoked() method.
|
||||
return false; // Access token hasn't been revoked
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNewToken(ClientEntityInterface $clientEntity, array $scopes, $userIdentifier = null)
|
||||
{
|
||||
$accessToken = new AccessTokenEntity();
|
||||
$accessToken->setClient($clientEntity);
|
||||
foreach ($scopes as $scope) {
|
||||
$accessToken->addScope($scope);
|
||||
}
|
||||
$accessToken->setUserIdentifier($userIdentifier);
|
||||
|
||||
return $accessToken;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,40 +2,41 @@
|
||||
|
||||
namespace OAuth2ServerExamples\Repositories;
|
||||
|
||||
use League\OAuth2\Server\Entities\Interfaces\AuthCodeEntityInterface;
|
||||
use League\OAuth2\Server\Entities\AuthCodeEntityInterface;
|
||||
use League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface;
|
||||
use OAuth2ServerExamples\Entities\AuthCodeEntity;
|
||||
|
||||
class AuthCodeRepository implements AuthCodeRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* Persists a new auth code to permanent storage.
|
||||
*
|
||||
* @param \League\OAuth2\Server\Entities\Interfaces\AuthCodeEntityInterface $authCodeEntity
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function persistNewAuthCode(AuthCodeEntityInterface $authCodeEntity)
|
||||
{
|
||||
// TODO: Implement persistNewAuthCode() method.
|
||||
// Some logic to persist the auth code to a database
|
||||
}
|
||||
|
||||
/**
|
||||
* Revoke an auth code.
|
||||
*
|
||||
* @param string $codeId
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function revokeAuthCode($codeId)
|
||||
{
|
||||
// TODO: Implement revokeAuthCode() method.
|
||||
// Some logic to revoke the auth code in a database
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the auth code has been revoked.
|
||||
*
|
||||
* @param string $codeId
|
||||
*
|
||||
* @return bool Return true if this code has been revoked
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isAuthCodeRevoked($codeId)
|
||||
{
|
||||
// TODO: Implement isAuthCodeRevoked() method.
|
||||
return false; // The auth code has not been revoked
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNewAuthCode()
|
||||
{
|
||||
return new AuthCodeEntity();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ class ClientRepository implements ClientRepositoryInterface
|
||||
$client->setIdentifier($clientIdentifier);
|
||||
$client->setName($clients[$clientIdentifier]['name']);
|
||||
$client->setRedirectUri($clients[$clientIdentifier]['redirect_uri']);
|
||||
$client->setSecret($clients[$clientIdentifier]['secret']);
|
||||
|
||||
return $client;
|
||||
}
|
||||
|
||||
@@ -2,40 +2,41 @@
|
||||
|
||||
namespace OAuth2ServerExamples\Repositories;
|
||||
|
||||
use League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\RefreshTokenEntityInterface;
|
||||
use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;
|
||||
use OAuth2ServerExamples\Entities\RefreshTokenEntity;
|
||||
|
||||
class RefreshTokenRepository implements RefreshTokenRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* Create a new refresh token_name.
|
||||
*
|
||||
* @param \League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface $refreshTokenEntityInterface
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function persistNewRefreshToken(RefreshTokenEntityInterface $refreshTokenEntityInterface)
|
||||
{
|
||||
// TODO: Implement persistNewRefreshToken() method.
|
||||
// Some logic to persist the refresh token in a database
|
||||
}
|
||||
|
||||
/**
|
||||
* Revoke the refresh token.
|
||||
*
|
||||
* @param string $tokenId
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function revokeRefreshToken($tokenId)
|
||||
{
|
||||
// TODO: Implement revokeRefreshToken() method.
|
||||
// Some logic to revoke the refresh token in a database
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the refresh token has been revoked.
|
||||
*
|
||||
* @param string $tokenId
|
||||
*
|
||||
* @return bool Return true if this token has been revoked
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isRefreshTokenRevoked($tokenId)
|
||||
{
|
||||
// TODO: Implement isRefreshTokenRevoked() method.
|
||||
return false; // The refresh token has not been revoked
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNewRefreshToken()
|
||||
{
|
||||
return new RefreshTokenEntity();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace OAuth2ServerExamples\Repositories;
|
||||
|
||||
use League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface;
|
||||
use League\OAuth2\Server\Entities\ClientEntityInterface;
|
||||
use League\OAuth2\Server\Repositories\ScopeRepositoryInterface;
|
||||
use OAuth2ServerExamples\Entities\ScopeEntity;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace OAuth2ServerExamples\Repositories;
|
||||
|
||||
use League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface;
|
||||
use League\OAuth2\Server\Entities\ClientEntityInterface;
|
||||
use League\OAuth2\Server\Repositories\UserRepositoryInterface;
|
||||
use OAuth2ServerExamples\Entities\ScopeEntity;
|
||||
use OAuth2ServerExamples\Entities\UserEntity;
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace League\OAuth2\Server\AuthorizationValidators;
|
||||
|
||||
use Lcobucci\JWT\Parser;
|
||||
use Lcobucci\JWT\Signer\Rsa\Sha256;
|
||||
use Lcobucci\JWT\ValidationData;
|
||||
use League\OAuth2\Server\CryptTrait;
|
||||
use League\OAuth2\Server\Exception\OAuthServerException;
|
||||
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
|
||||
@@ -43,10 +44,18 @@ class BearerTokenValidator implements AuthorizationValidatorInterface
|
||||
try {
|
||||
// Attempt to parse and validate the JWT
|
||||
$token = (new Parser())->parse($jwt);
|
||||
if ($token->verify(new Sha256(), $this->publicKeyPath) === false) {
|
||||
if ($token->verify(new Sha256(), $this->publicKey->getKeyPath()) === false) {
|
||||
throw OAuthServerException::accessDenied('Access token could not be verified');
|
||||
}
|
||||
|
||||
// Ensure access token hasn't expired
|
||||
$data = new ValidationData();
|
||||
$data->setCurrentTime(time());
|
||||
|
||||
if ($token->validate($data) === false) {
|
||||
throw OAuthServerException::accessDenied('Access token is invalid');
|
||||
}
|
||||
|
||||
// Check if token has been revoked
|
||||
if ($this->accessTokenRepository->isAccessTokenRevoked($token->getClaim('jti'))) {
|
||||
throw OAuthServerException::accessDenied('Access token has been revoked');
|
||||
|
||||
62
src/CryptKey.php
Normal file
62
src/CryptKey.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* Cryptography key holder.
|
||||
*
|
||||
* @author Julián Gutiérrez <juliangut@gmail.com>
|
||||
* @copyright Copyright (c) Alex Bilbie
|
||||
* @license http://mit-license.org/
|
||||
*
|
||||
* @link https://github.com/thephpleague/oauth2-server
|
||||
*/
|
||||
namespace League\OAuth2\Server;
|
||||
|
||||
class CryptKey
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $keyPath;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $passPhrase;
|
||||
|
||||
/**
|
||||
* @param string $keyPath
|
||||
* @param null|string $passPhrase
|
||||
*/
|
||||
public function __construct($keyPath, $passPhrase = null)
|
||||
{
|
||||
if (strpos($keyPath, 'file://') !== 0) {
|
||||
$keyPath = 'file://' . $keyPath;
|
||||
}
|
||||
|
||||
if (!file_exists($keyPath) || !is_readable($keyPath)) {
|
||||
throw new \LogicException(sprintf('Key path "%s" does not exist or is not readable', $keyPath));
|
||||
}
|
||||
|
||||
$this->keyPath = $keyPath;
|
||||
$this->passPhrase = $passPhrase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve key path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getKeyPath()
|
||||
{
|
||||
return $this->keyPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve key pass phrase.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getPassPhrase()
|
||||
{
|
||||
return $this->passPhrase;
|
||||
}
|
||||
}
|
||||
@@ -13,41 +13,33 @@ namespace League\OAuth2\Server;
|
||||
trait CryptTrait
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
* @var \League\OAuth2\Server\CryptKey
|
||||
*/
|
||||
protected $privateKeyPath;
|
||||
protected $privateKey;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @var \League\OAuth2\Server\CryptKey
|
||||
*/
|
||||
protected $publicKeyPath;
|
||||
protected $publicKey;
|
||||
|
||||
/**
|
||||
* Set path to private key.
|
||||
*
|
||||
* @param string $privateKeyPath
|
||||
* @param \League\OAuth2\Server\CryptKey $privateKey
|
||||
*/
|
||||
public function setPrivateKeyPath($privateKeyPath)
|
||||
public function setPrivateKey(CryptKey $privateKey)
|
||||
{
|
||||
if (strpos($privateKeyPath, 'file://') !== 0) {
|
||||
$privateKeyPath = 'file://' . $privateKeyPath;
|
||||
}
|
||||
|
||||
$this->privateKeyPath = $privateKeyPath;
|
||||
$this->privateKey = $privateKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set path to public key.
|
||||
*
|
||||
* @param string $publicKeyPath
|
||||
* @param \League\OAuth2\Server\CryptKey $publicKey
|
||||
*/
|
||||
public function setPublicKeyPath($publicKeyPath)
|
||||
public function setPublicKey(CryptKey $publicKey)
|
||||
{
|
||||
if (strpos($publicKeyPath, 'file://') !== 0) {
|
||||
$publicKeyPath = 'file://' . $publicKeyPath;
|
||||
}
|
||||
|
||||
$this->publicKeyPath = $publicKeyPath;
|
||||
$this->publicKey = $publicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,10 +51,12 @@ trait CryptTrait
|
||||
*/
|
||||
protected function encrypt($unencryptedData)
|
||||
{
|
||||
$privateKey = openssl_pkey_get_private($this->privateKeyPath);
|
||||
$privateKey = openssl_pkey_get_private($this->privateKey->getKeyPath(), $this->privateKey->getPassPhrase());
|
||||
$privateKeyDetails = @openssl_pkey_get_details($privateKey);
|
||||
if ($privateKeyDetails === null) {
|
||||
throw new \LogicException(sprintf('Could not get details of private key: %s', $this->privateKeyPath));
|
||||
throw new \LogicException(
|
||||
sprintf('Could not get details of private key: %s', $this->privateKey->getKeyPath())
|
||||
);
|
||||
}
|
||||
|
||||
$chunkSize = ceil($privateKeyDetails['bits'] / 8) - 11;
|
||||
@@ -78,7 +72,7 @@ trait CryptTrait
|
||||
}
|
||||
$output .= $encrypted;
|
||||
}
|
||||
openssl_free_key($privateKey);
|
||||
openssl_pkey_free($privateKey);
|
||||
|
||||
return base64_encode($output);
|
||||
}
|
||||
@@ -94,10 +88,12 @@ trait CryptTrait
|
||||
*/
|
||||
protected function decrypt($encryptedData)
|
||||
{
|
||||
$publicKey = openssl_pkey_get_public($this->publicKeyPath);
|
||||
$publicKey = openssl_pkey_get_public($this->publicKey->getKeyPath());
|
||||
$publicKeyDetails = @openssl_pkey_get_details($publicKey);
|
||||
if ($publicKeyDetails === null) {
|
||||
throw new \LogicException(sprintf('Could not get details of public key: %s', $this->publicKeyPath));
|
||||
throw new \LogicException(
|
||||
sprintf('Could not get details of public key: %s', $this->publicKey->getKeyPath())
|
||||
);
|
||||
}
|
||||
|
||||
$chunkSize = ceil($publicKeyDetails['bits'] / 8);
|
||||
@@ -115,7 +111,7 @@ trait CryptTrait
|
||||
}
|
||||
$output .= $decrypted;
|
||||
}
|
||||
openssl_free_key($publicKey);
|
||||
openssl_pkey_free($publicKey);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
17
src/Entities/AccessTokenEntityInterface.php
Normal file
17
src/Entities/AccessTokenEntityInterface.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace League\OAuth2\Server\Entities;
|
||||
|
||||
use League\OAuth2\Server\CryptKey;
|
||||
|
||||
interface AccessTokenEntityInterface extends TokenInterface
|
||||
{
|
||||
/**
|
||||
* Generate a JWT from the access token
|
||||
*
|
||||
* @param \League\OAuth2\Server\CryptKey $privateKey
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function convertToJWT(CryptKey $privateKey);
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace League\OAuth2\Server\Entities;
|
||||
|
||||
use League\OAuth2\Server\Entities\Interfaces\AuthCodeEntityInterface;
|
||||
use League\OAuth2\Server\Entities\Traits\EntityTrait;
|
||||
use League\OAuth2\Server\Entities\Traits\TokenEntityTrait;
|
||||
|
||||
/**
|
||||
* Class AuthCodeEntity.
|
||||
*/
|
||||
class AuthCodeEntity implements AuthCodeEntityInterface
|
||||
{
|
||||
use EntityTrait, TokenEntityTrait;
|
||||
|
||||
protected $redirectUri;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRedirectUri()
|
||||
{
|
||||
return $this->redirectUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $uri
|
||||
*/
|
||||
public function setRedirectUri($uri)
|
||||
{
|
||||
$this->redirectUri = $uri;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace League\OAuth2\Server\Entities\Interfaces;
|
||||
namespace League\OAuth2\Server\Entities;
|
||||
|
||||
interface AuthCodeEntityInterface extends TokenInterface
|
||||
{
|
||||
29
src/Entities/ClientEntityInterface.php
Normal file
29
src/Entities/ClientEntityInterface.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace League\OAuth2\Server\Entities;
|
||||
|
||||
interface ClientEntityInterface
|
||||
{
|
||||
/**
|
||||
* Get the client's identifier.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier();
|
||||
|
||||
/**
|
||||
* Get the client's name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName();
|
||||
|
||||
/**
|
||||
* Returns the registered redirect URI (as a string).
|
||||
*
|
||||
* Alternatively return an indexed array of redirect URIs.
|
||||
*
|
||||
* @return string|string[]
|
||||
*/
|
||||
public function getRedirectUri();
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace League\OAuth2\Server\Entities\Interfaces;
|
||||
|
||||
interface AccessTokenEntityInterface extends TokenInterface
|
||||
{
|
||||
/**
|
||||
* Generate a JWT from the access token
|
||||
*
|
||||
* @param string $privateKeyPath
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function convertToJWT($privateKeyPath);
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace League\OAuth2\Server\Entities\Interfaces;
|
||||
|
||||
interface ClientEntityInterface
|
||||
{
|
||||
/**
|
||||
* Get the client's identifier.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier();
|
||||
|
||||
/**
|
||||
* Set the client's identifier.
|
||||
*
|
||||
* @param $identifier
|
||||
*/
|
||||
public function setIdentifier($identifier);
|
||||
|
||||
/**
|
||||
* Get the client's name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName();
|
||||
|
||||
/**
|
||||
* Set the client's name.
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
public function setName($name);
|
||||
|
||||
/**
|
||||
* Set the client's redirect uri.
|
||||
*
|
||||
* @param string $redirectUri
|
||||
*/
|
||||
public function setRedirectUri($redirectUri);
|
||||
|
||||
/**
|
||||
* Returns the registered redirect URI.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRedirectUri();
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace League\OAuth2\Server\Entities;
|
||||
|
||||
use League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\Traits\EntityTrait;
|
||||
use League\OAuth2\Server\Entities\Traits\RefreshTokenTrait;
|
||||
|
||||
/**
|
||||
* Class RefreshTokenEntity.
|
||||
*/
|
||||
class RefreshTokenEntity implements RefreshTokenEntityInterface
|
||||
{
|
||||
use EntityTrait, RefreshTokenTrait;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace League\OAuth2\Server\Entities\Interfaces;
|
||||
namespace League\OAuth2\Server\Entities;
|
||||
|
||||
interface RefreshTokenEntityInterface
|
||||
{
|
||||
@@ -35,14 +35,14 @@ interface RefreshTokenEntityInterface
|
||||
/**
|
||||
* Set the access token that the refresh token was associated with.
|
||||
*
|
||||
* @param \League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface $accessToken
|
||||
* @param \League\OAuth2\Server\Entities\AccessTokenEntityInterface $accessToken
|
||||
*/
|
||||
public function setAccessToken(AccessTokenEntityInterface $accessToken);
|
||||
|
||||
/**
|
||||
* Get the access token that the refresh token was originally associated with.
|
||||
*
|
||||
* @return \League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface
|
||||
* @return \League\OAuth2\Server\Entities\AccessTokenEntityInterface
|
||||
*/
|
||||
public function getAccessToken();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace League\OAuth2\Server\Entities\Interfaces;
|
||||
namespace League\OAuth2\Server\Entities;
|
||||
|
||||
interface ScopeEntityInterface extends \JsonSerializable
|
||||
{
|
||||
@@ -10,11 +10,4 @@ interface ScopeEntityInterface extends \JsonSerializable
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier();
|
||||
|
||||
/**
|
||||
* Set the scope's identifier.
|
||||
*
|
||||
* @param $identifier
|
||||
*/
|
||||
public function setIdentifier($identifier);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace League\OAuth2\Server\Entities\Interfaces;
|
||||
namespace League\OAuth2\Server\Entities;
|
||||
|
||||
interface TokenInterface
|
||||
{
|
||||
@@ -56,14 +56,14 @@ interface TokenInterface
|
||||
/**
|
||||
* Set the client that the token was issued to.
|
||||
*
|
||||
* @param \League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface $client
|
||||
* @param \League\OAuth2\Server\Entities\ClientEntityInterface $client
|
||||
*/
|
||||
public function setClient(ClientEntityInterface $client);
|
||||
|
||||
/**
|
||||
* Associate a scope with the token.
|
||||
*
|
||||
* @param \League\OAuth2\Server\Entities\Interfaces\ScopeEntityInterface $scope
|
||||
* @param \League\OAuth2\Server\Entities\ScopeEntityInterface $scope
|
||||
*/
|
||||
public function addScope(ScopeEntityInterface $scope);
|
||||
|
||||
@@ -1,26 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace League\OAuth2\Server\Entities;
|
||||
namespace League\OAuth2\Server\Entities\Traits;
|
||||
|
||||
use Lcobucci\JWT\Builder;
|
||||
use Lcobucci\JWT\Signer\Key;
|
||||
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;
|
||||
use League\OAuth2\Server\CryptKey;
|
||||
|
||||
class AccessTokenEntity implements AccessTokenEntityInterface
|
||||
trait AccessTokenTrait
|
||||
{
|
||||
use EntityTrait, TokenEntityTrait;
|
||||
|
||||
/**
|
||||
* Generate a JWT from the access token
|
||||
*
|
||||
* @param string $privateKeyPath
|
||||
* @param \League\OAuth2\Server\CryptKey $privateKey
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function convertToJWT($privateKeyPath)
|
||||
public function convertToJWT(CryptKey $privateKey)
|
||||
{
|
||||
return (new Builder())
|
||||
->setAudience($this->getClient()->getIdentifier())
|
||||
@@ -30,7 +26,7 @@ class AccessTokenEntity implements AccessTokenEntityInterface
|
||||
->setExpiration($this->getExpiryDateTime()->getTimestamp())
|
||||
->setSubject($this->getUserIdentifier())
|
||||
->set('scopes', $this->getScopes())
|
||||
->sign(new Sha256(), new Key($privateKeyPath))
|
||||
->sign(new Sha256(), new Key($privateKey->getKeyPath(), $privateKey->getPassPhrase()))
|
||||
->getToken();
|
||||
}
|
||||
}
|
||||
27
src/Entities/Traits/AuthCodeTrait.php
Normal file
27
src/Entities/Traits/AuthCodeTrait.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace League\OAuth2\Server\Entities\Traits;
|
||||
|
||||
trait AuthCodeTrait
|
||||
{
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
protected $redirectUri;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRedirectUri()
|
||||
{
|
||||
return $this->redirectUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $uri
|
||||
*/
|
||||
public function setRedirectUri($uri)
|
||||
{
|
||||
$this->redirectUri = $uri;
|
||||
}
|
||||
}
|
||||
33
src/Entities/Traits/ClientTrait.php
Normal file
33
src/Entities/Traits/ClientTrait.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace League\OAuth2\Server\Entities\Traits;
|
||||
|
||||
trait ClientTrait
|
||||
{
|
||||
protected $name;
|
||||
|
||||
protected $redirectUri;
|
||||
|
||||
/**
|
||||
* Get the client's name.
|
||||
*
|
||||
* @return string
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the registered redirect URI (as a string).
|
||||
*
|
||||
* Alternatively return an indexed array of redirect URIs.
|
||||
*
|
||||
* @return string|string[]
|
||||
*/
|
||||
public function getRedirectUri()
|
||||
{
|
||||
return $this->redirectUri;
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace League\OAuth2\Server\Entities\Traits;
|
||||
|
||||
use DateTime;
|
||||
use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
|
||||
|
||||
trait RefreshTokenTrait
|
||||
{
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
namespace League\OAuth2\Server\Entities\Traits;
|
||||
|
||||
use DateTime;
|
||||
use League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface;
|
||||
use League\OAuth2\Server\Entities\Interfaces\ScopeEntityInterface;
|
||||
use League\OAuth2\Server\Entities\ClientEntityInterface;
|
||||
use League\OAuth2\Server\Entities\ScopeEntityInterface;
|
||||
|
||||
trait TokenEntityTrait
|
||||
{
|
||||
@@ -31,7 +31,7 @@ trait TokenEntityTrait
|
||||
/**
|
||||
* Associate a scope with the token.
|
||||
*
|
||||
* @param \League\OAuth2\Server\Entities\Interfaces\ScopeEntityInterface $scope
|
||||
* @param \League\OAuth2\Server\Entities\ScopeEntityInterface $scope
|
||||
*/
|
||||
public function addScope(ScopeEntityInterface $scope)
|
||||
{
|
||||
@@ -101,7 +101,7 @@ trait TokenEntityTrait
|
||||
/**
|
||||
* Set the client that the token was issued to.
|
||||
*
|
||||
* @param \League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface $client
|
||||
* @param \League\OAuth2\Server\Entities\ClientEntityInterface $client
|
||||
*/
|
||||
public function setClient(ClientEntityInterface $client)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace League\OAuth2\Server\Entities\Interfaces;
|
||||
namespace League\OAuth2\Server\Entities;
|
||||
|
||||
interface UserEntityInterface
|
||||
{
|
||||
@@ -119,6 +119,8 @@ class OAuthServerException extends \Exception
|
||||
* @param $hint
|
||||
*
|
||||
* @return static
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function serverError($hint)
|
||||
{
|
||||
|
||||
@@ -11,45 +11,8 @@
|
||||
|
||||
namespace League\OAuth2\Server\Grant;
|
||||
|
||||
use League\OAuth2\Server\TemplateRenderer\PlatesRenderer;
|
||||
use League\OAuth2\Server\TemplateRenderer\RendererInterface;
|
||||
use League\Plates\Engine;
|
||||
|
||||
abstract class AbstractAuthorizeGrant extends AbstractGrant
|
||||
{
|
||||
/**
|
||||
* @var \League\OAuth2\Server\TemplateRenderer\RendererInterface
|
||||
*/
|
||||
protected $templateRenderer;
|
||||
|
||||
/**
|
||||
* Set the template renderer
|
||||
*
|
||||
* @param RendererInterface $templateRenderer
|
||||
*/
|
||||
public function setTemplateRenderer(RendererInterface $templateRenderer)
|
||||
{
|
||||
$this->templateRenderer = $templateRenderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve template renderer.
|
||||
*
|
||||
* @return \League\OAuth2\Server\TemplateRenderer\RendererInterface
|
||||
*/
|
||||
protected function getTemplateRenderer()
|
||||
{
|
||||
if (!$this->templateRenderer instanceof RendererInterface) {
|
||||
$this->templateRenderer = new PlatesRenderer(
|
||||
new Engine(__DIR__ . '/../TemplateRenderer/DefaultTemplates'),
|
||||
'login_user',
|
||||
'authorize_client'
|
||||
);
|
||||
}
|
||||
|
||||
return $this->templateRenderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $uri
|
||||
* @param array $params
|
||||
|
||||
@@ -12,12 +12,9 @@ namespace League\OAuth2\Server\Grant;
|
||||
|
||||
use League\Event\EmitterAwareTrait;
|
||||
use League\OAuth2\Server\CryptTrait;
|
||||
use League\OAuth2\Server\Entities\AccessTokenEntity;
|
||||
use League\OAuth2\Server\Entities\AuthCodeEntity;
|
||||
use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface;
|
||||
use League\OAuth2\Server\Entities\Interfaces\ScopeEntityInterface;
|
||||
use League\OAuth2\Server\Entities\RefreshTokenEntity;
|
||||
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\ClientEntityInterface;
|
||||
use League\OAuth2\Server\Entities\ScopeEntityInterface;
|
||||
use League\OAuth2\Server\Exception\OAuthServerException;
|
||||
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
|
||||
use League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface;
|
||||
@@ -26,6 +23,7 @@ use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;
|
||||
use League\OAuth2\Server\Repositories\ScopeRepositoryInterface;
|
||||
use League\OAuth2\Server\Repositories\UserRepositoryInterface;
|
||||
use League\OAuth2\Server\RequestEvent;
|
||||
use League\OAuth2\Server\RequestTypes\AuthorizationRequest;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
/**
|
||||
@@ -140,7 +138,7 @@ abstract class AbstractGrant implements GrantTypeInterface
|
||||
*
|
||||
* @throws \League\OAuth2\Server\Exception\OAuthServerException
|
||||
*
|
||||
* @return \League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface
|
||||
* @return \League\OAuth2\Server\Entities\ClientEntityInterface
|
||||
*/
|
||||
protected function validateClient(ServerRequestInterface $request)
|
||||
{
|
||||
@@ -173,8 +171,20 @@ abstract class AbstractGrant implements GrantTypeInterface
|
||||
|
||||
// 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();
|
||||
if ($redirectUri !== null) {
|
||||
if (
|
||||
is_string($client->getRedirectUri())
|
||||
&& (strcmp($client->getRedirectUri(), $redirectUri) !== 0)
|
||||
) {
|
||||
$this->getEmitter()->emit(new RequestEvent('client.authentication.failed', $request));
|
||||
throw OAuthServerException::invalidClient();
|
||||
} elseif (
|
||||
is_array($client->getRedirectUri())
|
||||
&& in_array($redirectUri, $client->getRedirectUri()) === false
|
||||
) {
|
||||
$this->getEmitter()->emit(new RequestEvent('client.authentication.failed', $request));
|
||||
throw OAuthServerException::invalidClient();
|
||||
}
|
||||
}
|
||||
|
||||
return $client;
|
||||
@@ -183,17 +193,15 @@ abstract class AbstractGrant implements GrantTypeInterface
|
||||
/**
|
||||
* Validate scopes in the request.
|
||||
*
|
||||
* @param string $scopes
|
||||
* @param \League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface $client
|
||||
* @param string $redirectUri
|
||||
* @param string $scopes
|
||||
* @param string $redirectUri
|
||||
*
|
||||
* @throws \League\OAuth2\Server\Exception\OAuthServerException
|
||||
*
|
||||
* @return \League\OAuth2\Server\Entities\Interfaces\ScopeEntityInterface[]
|
||||
* @return \League\OAuth2\Server\Entities\ScopeEntityInterface[]
|
||||
*/
|
||||
public function validateScopes(
|
||||
$scopes,
|
||||
ClientEntityInterface $client,
|
||||
$redirectUri = null
|
||||
) {
|
||||
$scopesList = array_filter(
|
||||
@@ -278,12 +286,12 @@ abstract class AbstractGrant implements GrantTypeInterface
|
||||
/**
|
||||
* Issue an access token.
|
||||
*
|
||||
* @param \DateInterval $accessTokenTTL
|
||||
* @param \League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface $client
|
||||
* @param string $userIdentifier
|
||||
* @param \League\OAuth2\Server\Entities\Interfaces\ScopeEntityInterface[] $scopes
|
||||
* @param \DateInterval $accessTokenTTL
|
||||
* @param \League\OAuth2\Server\Entities\ClientEntityInterface $client
|
||||
* @param string $userIdentifier
|
||||
* @param \League\OAuth2\Server\Entities\ScopeEntityInterface[] $scopes
|
||||
*
|
||||
* @return \League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface
|
||||
* @return \League\OAuth2\Server\Entities\AccessTokenEntityInterface
|
||||
*/
|
||||
protected function issueAccessToken(
|
||||
\DateInterval $accessTokenTTL,
|
||||
@@ -291,11 +299,11 @@ abstract class AbstractGrant implements GrantTypeInterface
|
||||
$userIdentifier,
|
||||
array $scopes = []
|
||||
) {
|
||||
$accessToken = new AccessTokenEntity();
|
||||
$accessToken->setIdentifier($this->generateUniqueIdentifier());
|
||||
$accessToken->setExpiryDateTime((new \DateTime())->add($accessTokenTTL));
|
||||
$accessToken = $this->accessTokenRepository->getNewToken($client, $scopes, $userIdentifier);
|
||||
$accessToken->setClient($client);
|
||||
$accessToken->setUserIdentifier($userIdentifier);
|
||||
$accessToken->setIdentifier($this->generateUniqueIdentifier());
|
||||
$accessToken->setExpiryDateTime((new \DateTime())->add($accessTokenTTL));
|
||||
|
||||
foreach ($scopes as $scope) {
|
||||
$accessToken->addScope($scope);
|
||||
@@ -309,13 +317,13 @@ abstract class AbstractGrant implements GrantTypeInterface
|
||||
/**
|
||||
* Issue an auth code.
|
||||
*
|
||||
* @param \DateInterval $authCodeTTL
|
||||
* @param \League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface $client
|
||||
* @param string $userIdentifier
|
||||
* @param string $redirectUri
|
||||
* @param \League\OAuth2\Server\Entities\Interfaces\ScopeEntityInterface[] $scopes
|
||||
* @param \DateInterval $authCodeTTL
|
||||
* @param \League\OAuth2\Server\Entities\ClientEntityInterface $client
|
||||
* @param string $userIdentifier
|
||||
* @param string $redirectUri
|
||||
* @param \League\OAuth2\Server\Entities\ScopeEntityInterface[] $scopes
|
||||
*
|
||||
* @return \League\OAuth2\Server\Entities\Interfaces\AuthCodeEntityInterface
|
||||
* @return \League\OAuth2\Server\Entities\AuthCodeEntityInterface
|
||||
*/
|
||||
protected function issueAuthCode(
|
||||
\DateInterval $authCodeTTL,
|
||||
@@ -324,7 +332,7 @@ abstract class AbstractGrant implements GrantTypeInterface
|
||||
$redirectUri,
|
||||
array $scopes = []
|
||||
) {
|
||||
$authCode = new AuthCodeEntity();
|
||||
$authCode = $this->authCodeRepository->getNewAuthCode();
|
||||
$authCode->setIdentifier($this->generateUniqueIdentifier());
|
||||
$authCode->setExpiryDateTime((new \DateTime())->add($authCodeTTL));
|
||||
$authCode->setClient($client);
|
||||
@@ -341,13 +349,13 @@ abstract class AbstractGrant implements GrantTypeInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface $accessToken
|
||||
* @param \League\OAuth2\Server\Entities\AccessTokenEntityInterface $accessToken
|
||||
*
|
||||
* @return \League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface
|
||||
* @return \League\OAuth2\Server\Entities\RefreshTokenEntityInterface
|
||||
*/
|
||||
protected function issueRefreshToken(AccessTokenEntityInterface $accessToken)
|
||||
{
|
||||
$refreshToken = new RefreshTokenEntity();
|
||||
$refreshToken = $this->refreshTokenRepository->getNewRefreshToken();
|
||||
$refreshToken->setIdentifier($this->generateUniqueIdentifier());
|
||||
$refreshToken->setExpiryDateTime((new \DateTime())->add($this->refreshTokenTTL));
|
||||
$refreshToken->setAccessToken($accessToken);
|
||||
@@ -385,7 +393,7 @@ abstract class AbstractGrant implements GrantTypeInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function canRespondToRequest(ServerRequestInterface $request)
|
||||
public function canRespondToAccessTokenRequest(ServerRequestInterface $request)
|
||||
{
|
||||
$requestParameters = (array) $request->getParsedBody();
|
||||
|
||||
@@ -394,4 +402,28 @@ abstract class AbstractGrant implements GrantTypeInterface
|
||||
&& $requestParameters['grant_type'] === $this->getIdentifier()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function canRespondToAuthorizationRequest(ServerRequestInterface $request)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateAuthorizationRequest(ServerRequestInterface $request)
|
||||
{
|
||||
throw new \LogicException('This grant cannot validate an authorization request');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function completeAuthorizationRequest(AuthorizationRequest $authorizationRequest)
|
||||
{
|
||||
throw new \LogicException('This grant cannot complete an authorization request');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,17 +3,15 @@
|
||||
namespace League\OAuth2\Server\Grant;
|
||||
|
||||
use DateInterval;
|
||||
use League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface;
|
||||
use League\OAuth2\Server\Entities\Interfaces\UserEntityInterface;
|
||||
use League\OAuth2\Server\Entities\ClientEntityInterface;
|
||||
use League\OAuth2\Server\Entities\UserEntityInterface;
|
||||
use League\OAuth2\Server\Exception\OAuthServerException;
|
||||
use League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface;
|
||||
use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;
|
||||
use League\OAuth2\Server\Repositories\UserRepositoryInterface;
|
||||
use League\OAuth2\Server\RequestEvent;
|
||||
use League\OAuth2\Server\ResponseTypes\HtmlResponse;
|
||||
use League\OAuth2\Server\RequestTypes\AuthorizationRequest;
|
||||
use League\OAuth2\Server\ResponseTypes\RedirectResponse;
|
||||
use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface;
|
||||
use League\OAuth2\Server\TemplateRenderer\RendererInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
class AuthCodeGrant extends AbstractAuthorizeGrant
|
||||
@@ -26,208 +24,17 @@ class AuthCodeGrant extends AbstractAuthorizeGrant
|
||||
/**
|
||||
* @param \League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface $authCodeRepository
|
||||
* @param \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface $refreshTokenRepository
|
||||
* @param \League\OAuth2\Server\Repositories\UserRepositoryInterface $userRepository
|
||||
* @param \DateInterval $authCodeTTL
|
||||
* @param \League\OAuth2\Server\TemplateRenderer\RendererInterface|null $templateRenderer
|
||||
*/
|
||||
public function __construct(
|
||||
AuthCodeRepositoryInterface $authCodeRepository,
|
||||
RefreshTokenRepositoryInterface $refreshTokenRepository,
|
||||
UserRepositoryInterface $userRepository,
|
||||
\DateInterval $authCodeTTL,
|
||||
RendererInterface $templateRenderer = null
|
||||
\DateInterval $authCodeTTL
|
||||
) {
|
||||
$this->setAuthCodeRepository($authCodeRepository);
|
||||
$this->setRefreshTokenRepository($refreshTokenRepository);
|
||||
$this->setUserRepository($userRepository);
|
||||
$this->authCodeTTL = $authCodeTTL;
|
||||
$this->refreshTokenTTL = new \DateInterval('P1M');
|
||||
$this->templateRenderer = $templateRenderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond to an authorization request.
|
||||
*
|
||||
* @param \Psr\Http\Message\ServerRequestInterface $request
|
||||
*
|
||||
* @throws \League\OAuth2\Server\Exception\OAuthServerException
|
||||
*
|
||||
* @return \Psr\Http\Message\ResponseInterface
|
||||
*/
|
||||
protected function respondToAuthorizationRequest(
|
||||
ServerRequestInterface $request
|
||||
) {
|
||||
$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 RequestEvent('client.authentication.failed', $request));
|
||||
throw OAuthServerException::invalidClient();
|
||||
}
|
||||
|
||||
$redirectUriParameter = $this->getQueryStringParameter('redirect_uri', $request, $client->getRedirectUri());
|
||||
if ($redirectUriParameter !== $client->getRedirectUri()) {
|
||||
$this->getEmitter()->emit(new RequestEvent('client.authentication.failed', $request));
|
||||
throw OAuthServerException::invalidClient();
|
||||
}
|
||||
|
||||
$scopes = $this->validateScopes(
|
||||
$this->getQueryStringParameter('scope', $request),
|
||||
$client,
|
||||
$client->getRedirectUri()
|
||||
);
|
||||
|
||||
$postbackUri = 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($this->decrypt($oauthCookie));
|
||||
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,
|
||||
$this->getIdentifier(),
|
||||
$client
|
||||
);
|
||||
|
||||
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) {
|
||||
$html = $this->getTemplateRenderer()->renderLogin([
|
||||
'error' => $loginError,
|
||||
'postback_uri' => $this->makeRedirectUri(
|
||||
$postbackUri,
|
||||
$request->getQueryParams()
|
||||
),
|
||||
]);
|
||||
|
||||
$htmlResponse = new HtmlResponse($this->accessTokenRepository);
|
||||
$htmlResponse->setStatusCode(403);
|
||||
$htmlResponse->setHtml($html);
|
||||
|
||||
return $htmlResponse;
|
||||
}
|
||||
|
||||
// The user hasn't approved the client yet so show an authorize form
|
||||
if ($userId !== null && $userHasApprovedClient === null) {
|
||||
$html = $this->getTemplateRenderer()->renderAuthorize([
|
||||
'client' => $client,
|
||||
'scopes' => $scopes,
|
||||
'postback_uri' => $this->makeRedirectUri(
|
||||
$postbackUri,
|
||||
$request->getQueryParams()
|
||||
),
|
||||
]);
|
||||
|
||||
$htmlResponse = new HtmlResponse($this->accessTokenRepository);
|
||||
$htmlResponse->setStatusCode(200);
|
||||
$htmlResponse->setHtml($html);
|
||||
$htmlResponse->setHeader('set-cookie', sprintf(
|
||||
'oauth_authorize_request=%s; Expires=%s',
|
||||
urlencode($this->encrypt(
|
||||
json_encode([
|
||||
'user_id' => $userId,
|
||||
])
|
||||
)),
|
||||
(new \DateTime())->add(new \DateInterval('PT5M'))->format('D, d M Y H:i:s e')
|
||||
));
|
||||
|
||||
return $htmlResponse;
|
||||
}
|
||||
|
||||
// The user has either approved or denied the client, so redirect them back
|
||||
$redirectUri = $client->getRedirectUri();
|
||||
$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) {
|
||||
|
||||
// Finalize the requested scopes
|
||||
$scopes = $this->scopeRepository->finalizeScopes($scopes, $this->getIdentifier(), $client, $userId);
|
||||
|
||||
$authCode = $this->issueAuthCode(
|
||||
$this->authCodeTTL,
|
||||
$client,
|
||||
$userId,
|
||||
$redirectUri,
|
||||
$scopes
|
||||
);
|
||||
|
||||
$redirectPayload['code'] = $this->encrypt(
|
||||
json_encode(
|
||||
[
|
||||
'client_id' => $authCode->getClient()->getIdentifier(),
|
||||
'redirect_uri' => $authCode->getRedirectUri(),
|
||||
'auth_code_id' => $authCode->getIdentifier(),
|
||||
'scopes' => $authCode->getScopes(),
|
||||
'user_id' => $authCode->getUserIdentifier(),
|
||||
'expire_time' => (new \DateTime())->add($this->authCodeTTL)->format('U'),
|
||||
]
|
||||
)
|
||||
);
|
||||
|
||||
$response = new RedirectResponse($this->accessTokenRepository);
|
||||
$response->setRedirectUri(
|
||||
$this->makeRedirectUri(
|
||||
$redirectUri,
|
||||
$redirectPayload
|
||||
)
|
||||
);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
// The user denied the client, redirect them back with an error
|
||||
throw OAuthServerException::accessDenied('The user denied the request', (string) $redirectUri);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -241,17 +48,11 @@ class AuthCodeGrant extends AbstractAuthorizeGrant
|
||||
*
|
||||
* @return \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface
|
||||
*/
|
||||
protected function respondToAccessTokenRequest(
|
||||
public 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);
|
||||
@@ -275,6 +76,12 @@ class AuthCodeGrant extends AbstractAuthorizeGrant
|
||||
throw OAuthServerException::invalidRequest('code', 'Authorization code was not issued to this client');
|
||||
}
|
||||
|
||||
// The redirect URI is required in this request
|
||||
$redirectUri = $this->getRequestParameter('redirect_uri', $request, null);
|
||||
if (empty($authCodePayload->redirect_uri) === false && $redirectUri === null) {
|
||||
throw OAuthServerException::invalidRequest('redirect_uri');
|
||||
}
|
||||
|
||||
if ($authCodePayload->redirect_uri !== $redirectUri) {
|
||||
throw OAuthServerException::invalidRequest('redirect_uri', 'Invalid redirect URI');
|
||||
}
|
||||
@@ -283,7 +90,7 @@ class AuthCodeGrant extends AbstractAuthorizeGrant
|
||||
foreach ($authCodePayload->scopes as $scopeId) {
|
||||
$scope = $this->scopeRepository->getScopeEntityByIdentifier($scopeId);
|
||||
|
||||
if (!$scope) {
|
||||
if ($scope === false) {
|
||||
// @codeCoverageIgnoreStart
|
||||
throw OAuthServerException::invalidScope($scopeId);
|
||||
// @codeCoverageIgnoreEnd
|
||||
@@ -291,6 +98,9 @@ class AuthCodeGrant extends AbstractAuthorizeGrant
|
||||
|
||||
$scopes[] = $scope;
|
||||
}
|
||||
|
||||
// Finalize the requested scopes
|
||||
$scopes = $this->scopeRepository->finalizeScopes($scopes, $this->getIdentifier(), $client, $authCodePayload->user_id);
|
||||
} catch (\LogicException $e) {
|
||||
throw OAuthServerException::invalidRequest('code', 'Cannot decrypt the authorization code');
|
||||
}
|
||||
@@ -303,41 +113,12 @@ class AuthCodeGrant extends AbstractAuthorizeGrant
|
||||
$responseType->setAccessToken($accessToken);
|
||||
$responseType->setRefreshToken($refreshToken);
|
||||
|
||||
// Revoke used auth code
|
||||
$this->authCodeRepository->revokeAuthCode($authCodePayload->auth_code_id);
|
||||
|
||||
return $responseType;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function respondToRequest(
|
||||
ServerRequestInterface $request,
|
||||
ResponseTypeInterface $responseType,
|
||||
\DateInterval $accessTokenTTL
|
||||
) {
|
||||
if (
|
||||
array_key_exists('response_type', $request->getQueryParams())
|
||||
&& $request->getQueryParams()['response_type'] === 'code'
|
||||
) {
|
||||
return $this->respondToAuthorizationRequest($request);
|
||||
}
|
||||
|
||||
return $this->respondToAccessTokenRequest($request, $responseType, $accessTokenTTL);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function canRespondToRequest(ServerRequestInterface $request)
|
||||
{
|
||||
return
|
||||
(
|
||||
array_key_exists('response_type', $request->getQueryParams())
|
||||
&& $request->getQueryParams()['response_type'] === 'code'
|
||||
&& isset($request->getQueryParams()['client_id'])
|
||||
)
|
||||
|| parent::canRespondToRequest($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the grant identifier that can be used in matching up requests.
|
||||
*
|
||||
@@ -347,4 +128,131 @@ class AuthCodeGrant extends AbstractAuthorizeGrant
|
||||
{
|
||||
return 'authorization_code';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function canRespondToAuthorizationRequest(ServerRequestInterface $request)
|
||||
{
|
||||
return (
|
||||
array_key_exists('response_type', $request->getQueryParams())
|
||||
&& $request->getQueryParams()['response_type'] === 'code'
|
||||
&& isset($request->getQueryParams()['client_id'])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateAuthorizationRequest(ServerRequestInterface $request)
|
||||
{
|
||||
$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 RequestEvent('client.authentication.failed', $request));
|
||||
throw OAuthServerException::invalidClient();
|
||||
}
|
||||
|
||||
$redirectUri = $this->getQueryStringParameter('redirect_uri', $request);
|
||||
if ($redirectUri !== null) {
|
||||
if (
|
||||
is_string($client->getRedirectUri())
|
||||
&& (strcmp($client->getRedirectUri(), $redirectUri) !== 0)
|
||||
) {
|
||||
$this->getEmitter()->emit(new RequestEvent('client.authentication.failed', $request));
|
||||
throw OAuthServerException::invalidClient();
|
||||
} elseif (
|
||||
is_array($client->getRedirectUri())
|
||||
&& in_array($redirectUri, $client->getRedirectUri()) === false
|
||||
) {
|
||||
$this->getEmitter()->emit(new RequestEvent('client.authentication.failed', $request));
|
||||
throw OAuthServerException::invalidClient();
|
||||
}
|
||||
}
|
||||
|
||||
$scopes = $this->validateScopes(
|
||||
$this->getQueryStringParameter('scope', $request),
|
||||
$client->getRedirectUri()
|
||||
);
|
||||
|
||||
$stateParameter = $this->getQueryStringParameter('state', $request);
|
||||
|
||||
$authorizationRequest = new AuthorizationRequest();
|
||||
$authorizationRequest->setGrantTypeId($this->getIdentifier());
|
||||
$authorizationRequest->setClient($client);
|
||||
$authorizationRequest->setRedirectUri($redirectUri);
|
||||
$authorizationRequest->setState($stateParameter);
|
||||
$authorizationRequest->setScopes($scopes);
|
||||
|
||||
return $authorizationRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function completeAuthorizationRequest(AuthorizationRequest $authorizationRequest)
|
||||
{
|
||||
if ($authorizationRequest->getUser() instanceof UserEntityInterface === false) {
|
||||
throw new \LogicException('An instance of UserEntityInterface should be set on the AuthorizationRequest');
|
||||
}
|
||||
|
||||
$finalRedirectUri = ($authorizationRequest->getRedirectUri() === null)
|
||||
? is_array($authorizationRequest->getClient()->getRedirectUri())
|
||||
? $authorizationRequest->getClient()->getRedirectUri()[0]
|
||||
: $authorizationRequest->getClient()->getRedirectUri()
|
||||
: $authorizationRequest->getRedirectUri();
|
||||
|
||||
// The user approved the client, redirect them back with an auth code
|
||||
if ($authorizationRequest->isAuthorizationApproved() === true) {
|
||||
$authCode = $this->issueAuthCode(
|
||||
$this->authCodeTTL,
|
||||
$authorizationRequest->getClient(),
|
||||
$authorizationRequest->getUser()->getIdentifier(),
|
||||
$authorizationRequest->getRedirectUri(),
|
||||
$authorizationRequest->getScopes()
|
||||
);
|
||||
|
||||
$redirectPayload['code'] = $this->encrypt(
|
||||
json_encode(
|
||||
[
|
||||
'client_id' => $authCode->getClient()->getIdentifier(),
|
||||
'redirect_uri' => $authCode->getRedirectUri(),
|
||||
'auth_code_id' => $authCode->getIdentifier(),
|
||||
'scopes' => $authCode->getScopes(),
|
||||
'user_id' => $authCode->getUserIdentifier(),
|
||||
'expire_time' => (new \DateTime())->add($this->authCodeTTL)->format('U'),
|
||||
]
|
||||
)
|
||||
);
|
||||
$redirectPayload['state'] = $authorizationRequest->getState();
|
||||
|
||||
$response = new RedirectResponse();
|
||||
$response->setRedirectUri(
|
||||
$this->makeRedirectUri(
|
||||
$finalRedirectUri,
|
||||
$redirectPayload
|
||||
)
|
||||
);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
// The user denied the client, redirect them back with an error
|
||||
throw OAuthServerException::accessDenied(
|
||||
'The user denied the request',
|
||||
$finalRedirectUri
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,20 +21,20 @@ class ClientCredentialsGrant extends AbstractGrant
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function respondToRequest(
|
||||
public function respondToAccessTokenRequest(
|
||||
ServerRequestInterface $request,
|
||||
ResponseTypeInterface $responseType,
|
||||
\DateInterval $accessTokenTTL
|
||||
) {
|
||||
// Validate request
|
||||
$client = $this->validateClient($request);
|
||||
$scopes = $this->validateScopes($this->getRequestParameter('scope', $request), $client);
|
||||
$scopes = $this->validateScopes($this->getRequestParameter('scope', $request));
|
||||
|
||||
// Finalize the requested scopes
|
||||
$scopes = $this->scopeRepository->finalizeScopes($scopes, $this->getIdentifier(), $client);
|
||||
|
||||
// Issue and persist access token
|
||||
$accessToken = $this->issueAccessToken($accessTokenTTL, $client, $client->getIdentifier(), $scopes);
|
||||
$accessToken = $this->issueAccessToken($accessTokenTTL, $client, null, $scopes);
|
||||
|
||||
// Inject access token into response type
|
||||
$responseType->setAccessToken($accessToken);
|
||||
|
||||
@@ -11,9 +11,11 @@
|
||||
namespace League\OAuth2\Server\Grant;
|
||||
|
||||
use League\Event\EmitterAwareInterface;
|
||||
use League\OAuth2\Server\CryptKey;
|
||||
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
|
||||
use League\OAuth2\Server\Repositories\ClientRepositoryInterface;
|
||||
use League\OAuth2\Server\Repositories\ScopeRepositoryInterface;
|
||||
use League\OAuth2\Server\RequestTypes\AuthorizationRequest;
|
||||
use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
@@ -45,25 +47,55 @@ interface GrantTypeInterface extends EmitterAwareInterface
|
||||
*
|
||||
* @return \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface
|
||||
*/
|
||||
public function respondToRequest(
|
||||
public function respondToAccessTokenRequest(
|
||||
ServerRequestInterface $request,
|
||||
ResponseTypeInterface $responseType,
|
||||
\DateInterval $accessTokenTTL
|
||||
);
|
||||
|
||||
/**
|
||||
* The grant type should return true if it is able to respond to this request.
|
||||
*
|
||||
* For example most grant types will check that the $_POST['grant_type'] property matches it's identifier property.
|
||||
*
|
||||
* Some grants, such as the authorization code grant can respond to multiple requests
|
||||
* - i.e. a client requesting an authorization code and requesting an access token
|
||||
* The grant type should return true if it is able to response to an authorization request
|
||||
*
|
||||
* @param \Psr\Http\Message\ServerRequestInterface $request
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canRespondToRequest(ServerRequestInterface $request);
|
||||
public function canRespondToAuthorizationRequest(ServerRequestInterface $request);
|
||||
|
||||
/**
|
||||
* If the grant can respond to an authorization request this method should be called to validate the parameters of
|
||||
* the request.
|
||||
*
|
||||
* If the validation is successful an AuthorizationRequest object will be returned. This object can be safely
|
||||
* serialized in a user's session, and can be used during user authentication and authorization.
|
||||
*
|
||||
* @param \Psr\Http\Message\ServerRequestInterface $request
|
||||
*
|
||||
* @return AuthorizationRequest
|
||||
*/
|
||||
public function validateAuthorizationRequest(ServerRequestInterface $request);
|
||||
|
||||
/**
|
||||
* Once a user has authenticated and authorized the client the grant can complete the authorization request.
|
||||
* The AuthorizationRequest object's $userId property must be set to the authenticated user and the
|
||||
* $authorizationApproved property must reflect their desire to authorize or deny the client.
|
||||
*
|
||||
* @param \League\OAuth2\Server\RequestTypes\AuthorizationRequest $authorizationRequest
|
||||
*
|
||||
* @return \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface
|
||||
*/
|
||||
public function completeAuthorizationRequest(AuthorizationRequest $authorizationRequest);
|
||||
|
||||
/**
|
||||
* The grant type should return true if it is able to respond to this request.
|
||||
*
|
||||
* For example most grant types will check that the $_POST['grant_type'] property matches it's identifier property.
|
||||
*
|
||||
* @param \Psr\Http\Message\ServerRequestInterface $request
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canRespondToAccessTokenRequest(ServerRequestInterface $request);
|
||||
|
||||
/**
|
||||
* Set the client repository.
|
||||
@@ -89,14 +121,14 @@ interface GrantTypeInterface extends EmitterAwareInterface
|
||||
/**
|
||||
* Set the path to the private key.
|
||||
*
|
||||
* @param string $privateKeyPath
|
||||
* @param \League\OAuth2\Server\CryptKey $privateKey
|
||||
*/
|
||||
public function setPrivateKeyPath($privateKeyPath);
|
||||
public function setPrivateKey(CryptKey $privateKey);
|
||||
|
||||
/**
|
||||
* Set the path to the public key.
|
||||
*
|
||||
* @param string $publicKeyPath
|
||||
* @param \League\OAuth2\Server\CryptKey $publicKey
|
||||
*/
|
||||
public function setPublicKeyPath($publicKeyPath);
|
||||
public function setPublicKey(CryptKey $publicKey);
|
||||
}
|
||||
|
||||
@@ -2,37 +2,37 @@
|
||||
|
||||
namespace League\OAuth2\Server\Grant;
|
||||
|
||||
use League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface;
|
||||
use League\OAuth2\Server\Entities\Interfaces\UserEntityInterface;
|
||||
use League\OAuth2\Server\Entities\ClientEntityInterface;
|
||||
use League\OAuth2\Server\Entities\UserEntityInterface;
|
||||
use League\OAuth2\Server\Exception\OAuthServerException;
|
||||
use League\OAuth2\Server\Repositories\UserRepositoryInterface;
|
||||
use League\OAuth2\Server\RequestEvent;
|
||||
use League\OAuth2\Server\ResponseTypes\HtmlResponse;
|
||||
use League\OAuth2\Server\RequestTypes\AuthorizationRequest;
|
||||
use League\OAuth2\Server\ResponseTypes\RedirectResponse;
|
||||
use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface;
|
||||
use League\OAuth2\Server\TemplateRenderer\RendererInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
class ImplicitGrant extends AbstractAuthorizeGrant
|
||||
{
|
||||
/**
|
||||
* @param \League\OAuth2\Server\Repositories\UserRepositoryInterface $userRepository
|
||||
* @param \League\OAuth2\Server\TemplateRenderer\RendererInterface|null $templateRenderer
|
||||
* @var \DateInterval
|
||||
*/
|
||||
public function __construct(UserRepositoryInterface $userRepository, RendererInterface $templateRenderer = null)
|
||||
private $accessTokenTTL;
|
||||
|
||||
/**
|
||||
* @param \DateInterval $accessTokenTTL
|
||||
*/
|
||||
public function __construct(\DateInterval $accessTokenTTL)
|
||||
{
|
||||
$this->setUserRepository($userRepository);
|
||||
$this->refreshTokenTTL = new \DateInterval('P1M');
|
||||
$this->templateRenderer = $templateRenderer;
|
||||
$this->accessTokenTTL = $accessTokenTTL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function canRespondToRequest(ServerRequestInterface $request)
|
||||
public function canRespondToAccessTokenRequest(ServerRequestInterface $request)
|
||||
{
|
||||
return (array_key_exists('response_type', $request->getQueryParams())
|
||||
&& $request->getQueryParams()['response_type'] === 'token');
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,13 +46,39 @@ class ImplicitGrant extends AbstractAuthorizeGrant
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* Respond to an incoming request.
|
||||
*
|
||||
* @param \Psr\Http\Message\ServerRequestInterface $request
|
||||
* @param \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface $responseType
|
||||
* @param \DateInterval $accessTokenTTL
|
||||
*
|
||||
* @return \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface
|
||||
*/
|
||||
public function respondToRequest(
|
||||
public function respondToAccessTokenRequest(
|
||||
ServerRequestInterface $request,
|
||||
ResponseTypeInterface $responseType,
|
||||
\DateInterval $accessTokenTTL
|
||||
) {
|
||||
throw new \LogicException('This grant does not used this method');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function canRespondToAuthorizationRequest(ServerRequestInterface $request)
|
||||
{
|
||||
return (
|
||||
array_key_exists('response_type', $request->getQueryParams())
|
||||
&& $request->getQueryParams()['response_type'] === 'token'
|
||||
&& isset($request->getQueryParams()['client_id'])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateAuthorizationRequest(ServerRequestInterface $request)
|
||||
{
|
||||
$clientId = $this->getQueryStringParameter(
|
||||
'client_id',
|
||||
$request,
|
||||
@@ -72,139 +98,72 @@ class ImplicitGrant extends AbstractAuthorizeGrant
|
||||
throw OAuthServerException::invalidClient();
|
||||
}
|
||||
|
||||
$redirectUriParameter = $this->getQueryStringParameter('redirect_uri', $request, $client->getRedirectUri());
|
||||
if ($redirectUriParameter !== $client->getRedirectUri()) {
|
||||
$this->getEmitter()->emit(new RequestEvent('client.authentication.failed', $request));
|
||||
throw OAuthServerException::invalidClient();
|
||||
$redirectUri = $this->getQueryStringParameter('redirect_uri', $request);
|
||||
if ($redirectUri !== null) {
|
||||
if (
|
||||
is_string($client->getRedirectUri())
|
||||
&& (strcmp($client->getRedirectUri(), $redirectUri) !== 0)
|
||||
) {
|
||||
$this->getEmitter()->emit(new RequestEvent('client.authentication.failed', $request));
|
||||
throw OAuthServerException::invalidClient();
|
||||
} elseif (
|
||||
is_array($client->getRedirectUri())
|
||||
&& in_array($redirectUri, $client->getRedirectUri()) === false
|
||||
) {
|
||||
$this->getEmitter()->emit(new RequestEvent('client.authentication.failed', $request));
|
||||
throw OAuthServerException::invalidClient();
|
||||
}
|
||||
}
|
||||
|
||||
$scopes = $this->validateScopes(
|
||||
$this->getQueryStringParameter('scope', $request),
|
||||
$client,
|
||||
$client->getRedirectUri()
|
||||
);
|
||||
|
||||
$postbackUri = 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($this->decrypt($oauthCookie));
|
||||
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,
|
||||
$this->getIdentifier(),
|
||||
$client
|
||||
);
|
||||
|
||||
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) {
|
||||
$html = $this->getTemplateRenderer()->renderLogin([
|
||||
'error' => $loginError,
|
||||
'postback_uri' => $this->makeRedirectUri(
|
||||
$postbackUri,
|
||||
$request->getQueryParams()
|
||||
),
|
||||
]);
|
||||
|
||||
$htmlResponse = new HtmlResponse($this->accessTokenRepository);
|
||||
$htmlResponse->setStatusCode(403);
|
||||
$htmlResponse->setHtml($html);
|
||||
|
||||
return $htmlResponse;
|
||||
}
|
||||
|
||||
// The user hasn't approved the client yet so show an authorize form
|
||||
if ($userId !== null && $userHasApprovedClient === null) {
|
||||
$html = $this->getTemplateRenderer()->renderAuthorize([
|
||||
'client' => $client,
|
||||
'scopes' => $scopes,
|
||||
'postback_uri' => $this->makeRedirectUri(
|
||||
$postbackUri,
|
||||
$request->getQueryParams()
|
||||
),
|
||||
]);
|
||||
|
||||
$htmlResponse = new HtmlResponse($this->accessTokenRepository);
|
||||
$htmlResponse->setStatusCode(200);
|
||||
$htmlResponse->setHtml($html);
|
||||
$htmlResponse->setHeader('set-cookie', sprintf(
|
||||
'oauth_authorize_request=%s; Expires=%s',
|
||||
urlencode($this->encrypt(
|
||||
json_encode([
|
||||
'user_id' => $userId,
|
||||
])
|
||||
)),
|
||||
(new \DateTime())->add(new \DateInterval('PT5M'))->format('D, d M Y H:i:s e')
|
||||
));
|
||||
|
||||
return $htmlResponse;
|
||||
}
|
||||
|
||||
// The user has either approved or denied the client, so redirect them back
|
||||
$redirectUri = $client->getRedirectUri();
|
||||
$redirectPayload = [];
|
||||
|
||||
$stateParameter = $this->getQueryStringParameter('state', $request);
|
||||
if ($stateParameter !== null) {
|
||||
$redirectPayload['state'] = $stateParameter;
|
||||
|
||||
$authorizationRequest = new AuthorizationRequest();
|
||||
$authorizationRequest->setGrantTypeId($this->getIdentifier());
|
||||
$authorizationRequest->setClient($client);
|
||||
$authorizationRequest->setRedirectUri($redirectUri);
|
||||
$authorizationRequest->setState($stateParameter);
|
||||
$authorizationRequest->setScopes($scopes);
|
||||
|
||||
return $authorizationRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function completeAuthorizationRequest(AuthorizationRequest $authorizationRequest)
|
||||
{
|
||||
if ($authorizationRequest->getUser() instanceof UserEntityInterface === false) {
|
||||
throw new \LogicException('An instance of UserEntityInterface should be set on the AuthorizationRequest');
|
||||
}
|
||||
|
||||
// THe user approved the client, redirect them back with an access token
|
||||
if ($userHasApprovedClient === true) {
|
||||
|
||||
// Finalize the requested scopes
|
||||
$scopes = $this->scopeRepository->finalizeScopes($scopes, $this->getIdentifier(), $client, $userId);
|
||||
$finalRedirectUri = ($authorizationRequest->getRedirectUri() === null)
|
||||
? is_array($authorizationRequest->getClient()->getRedirectUri())
|
||||
? $authorizationRequest->getClient()->getRedirectUri()[0]
|
||||
: $authorizationRequest->getClient()->getRedirectUri()
|
||||
: $authorizationRequest->getRedirectUri();
|
||||
|
||||
// The user approved the client, redirect them back with an access token
|
||||
if ($authorizationRequest->isAuthorizationApproved() === true) {
|
||||
$accessToken = $this->issueAccessToken(
|
||||
$accessTokenTTL,
|
||||
$client,
|
||||
$userId,
|
||||
$scopes
|
||||
$this->accessTokenTTL,
|
||||
$authorizationRequest->getClient(),
|
||||
$authorizationRequest->getUser()->getIdentifier(),
|
||||
$authorizationRequest->getScopes()
|
||||
);
|
||||
|
||||
$redirectPayload['access_token'] = (string) $accessToken->convertToJWT($this->privateKeyPath);
|
||||
$redirectPayload['access_token'] = (string) $accessToken->convertToJWT($this->privateKey);
|
||||
$redirectPayload['token_type'] = 'bearer';
|
||||
$redirectPayload['expires_in'] = time() - $accessToken->getExpiryDateTime()->getTimestamp();
|
||||
$redirectPayload['expires_in'] = $accessToken->getExpiryDateTime()->getTimestamp() - (new \DateTime())->getTimestamp();
|
||||
|
||||
$response = new RedirectResponse($this->accessTokenRepository);
|
||||
$response = new RedirectResponse();
|
||||
$response->setRedirectUri(
|
||||
$this->makeRedirectUri(
|
||||
$redirectUri,
|
||||
$finalRedirectUri,
|
||||
$redirectPayload,
|
||||
'#'
|
||||
)
|
||||
@@ -214,6 +173,9 @@ class ImplicitGrant extends AbstractAuthorizeGrant
|
||||
}
|
||||
|
||||
// The user denied the client, redirect them back with an error
|
||||
throw OAuthServerException::accessDenied('The user denied the request', (string) $redirectUri);
|
||||
throw OAuthServerException::accessDenied(
|
||||
'The user denied the request',
|
||||
$finalRedirectUri
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
*/
|
||||
namespace League\OAuth2\Server\Grant;
|
||||
|
||||
use League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface;
|
||||
use League\OAuth2\Server\Entities\Interfaces\UserEntityInterface;
|
||||
use League\OAuth2\Server\Entities\ClientEntityInterface;
|
||||
use League\OAuth2\Server\Entities\UserEntityInterface;
|
||||
use League\OAuth2\Server\Exception\OAuthServerException;
|
||||
use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;
|
||||
use League\OAuth2\Server\Repositories\UserRepositoryInterface;
|
||||
@@ -41,14 +41,14 @@ class PasswordGrant extends AbstractGrant
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function respondToRequest(
|
||||
public function respondToAccessTokenRequest(
|
||||
ServerRequestInterface $request,
|
||||
ResponseTypeInterface $responseType,
|
||||
\DateInterval $accessTokenTTL
|
||||
) {
|
||||
// Validate request
|
||||
$client = $this->validateClient($request);
|
||||
$scopes = $this->validateScopes($this->getRequestParameter('scope', $request), $client);
|
||||
$scopes = $this->validateScopes($this->getRequestParameter('scope', $request));
|
||||
$user = $this->validateUser($request, $client);
|
||||
|
||||
// Finalize the requested scopes
|
||||
@@ -66,12 +66,12 @@ class PasswordGrant extends AbstractGrant
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Psr\Http\Message\ServerRequestInterface $request
|
||||
* @param \League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface $client
|
||||
* @param \Psr\Http\Message\ServerRequestInterface $request
|
||||
* @param \League\OAuth2\Server\Entities\ClientEntityInterface $client
|
||||
*
|
||||
* @throws \League\OAuth2\Server\Exception\OAuthServerException
|
||||
*
|
||||
* @return \League\OAuth2\Server\Entities\Interfaces\UserEntityInterface
|
||||
* @return \League\OAuth2\Server\Entities\UserEntityInterface
|
||||
*/
|
||||
protected function validateUser(ServerRequestInterface $request, ClientEntityInterface $client)
|
||||
{
|
||||
|
||||
@@ -34,7 +34,7 @@ class RefreshTokenGrant extends AbstractGrant
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function respondToRequest(
|
||||
public function respondToAccessTokenRequest(
|
||||
ServerRequestInterface $request,
|
||||
ResponseTypeInterface $responseType,
|
||||
\DateInterval $accessTokenTTL
|
||||
@@ -42,7 +42,7 @@ class RefreshTokenGrant extends AbstractGrant
|
||||
// Validate request
|
||||
$client = $this->validateClient($request);
|
||||
$oldRefreshToken = $this->validateOldRefreshToken($request, $client->getIdentifier());
|
||||
$scopes = $this->validateScopes($this->getRequestParameter('scope', $request), $client);
|
||||
$scopes = $this->validateScopes($this->getRequestParameter('scope', $request));
|
||||
|
||||
// If no new scopes are requested then give the access token the original session scopes
|
||||
if (count($scopes) === 0) {
|
||||
|
||||
@@ -34,7 +34,7 @@ class AuthenticationServerMiddleware
|
||||
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next)
|
||||
{
|
||||
try {
|
||||
$response = $this->server->respondToRequest($request, $response);
|
||||
$response = $this->server->respondToAccessTokenRequest($request, $response);
|
||||
} catch (OAuthServerException $exception) {
|
||||
return $exception->generateHttpResponse($response);
|
||||
// @codeCoverageIgnoreStart
|
||||
|
||||
@@ -10,17 +10,29 @@
|
||||
*/
|
||||
namespace League\OAuth2\Server\Repositories;
|
||||
|
||||
use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\ClientEntityInterface;
|
||||
|
||||
/**
|
||||
* Access token interface.
|
||||
*/
|
||||
interface AccessTokenRepositoryInterface extends RepositoryInterface
|
||||
{
|
||||
/**
|
||||
* Create a new access token
|
||||
*
|
||||
* @param \League\OAuth2\Server\Entities\ClientEntityInterface $clientEntity
|
||||
* @param \League\OAuth2\Server\Entities\ScopeEntityInterface[] $scopes
|
||||
* @param mixed $userIdentifier
|
||||
*
|
||||
* @return AccessTokenEntityInterface
|
||||
*/
|
||||
public function getNewToken(ClientEntityInterface $clientEntity, array $scopes, $userIdentifier = null);
|
||||
|
||||
/**
|
||||
* Persists a new access token to permanent storage.
|
||||
*
|
||||
* @param \League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface $accessTokenEntity
|
||||
* @param \League\OAuth2\Server\Entities\AccessTokenEntityInterface $accessTokenEntity
|
||||
*/
|
||||
public function persistNewAccessToken(AccessTokenEntityInterface $accessTokenEntity);
|
||||
|
||||
|
||||
@@ -10,17 +10,24 @@
|
||||
*/
|
||||
namespace League\OAuth2\Server\Repositories;
|
||||
|
||||
use League\OAuth2\Server\Entities\Interfaces\AuthCodeEntityInterface;
|
||||
use League\OAuth2\Server\Entities\AuthCodeEntityInterface;
|
||||
|
||||
/**
|
||||
* Auth code storage interface.
|
||||
*/
|
||||
interface AuthCodeRepositoryInterface extends RepositoryInterface
|
||||
{
|
||||
/**
|
||||
* Creates a new AuthCode
|
||||
*
|
||||
* @return \League\OAuth2\Server\Entities\AuthCodeEntityInterface
|
||||
*/
|
||||
public function getNewAuthCode();
|
||||
|
||||
/**
|
||||
* Persists a new auth code to permanent storage.
|
||||
*
|
||||
* @param \League\OAuth2\Server\Entities\Interfaces\AuthCodeEntityInterface $authCodeEntity
|
||||
* @param \League\OAuth2\Server\Entities\AuthCodeEntityInterface $authCodeEntity
|
||||
*/
|
||||
public function persistNewAuthCode(AuthCodeEntityInterface $authCodeEntity);
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ interface ClientRepositoryInterface extends RepositoryInterface
|
||||
* @param string $grantType The grant type used
|
||||
* @param null|string $clientSecret The client's secret (if sent)
|
||||
*
|
||||
* @return \League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface
|
||||
* @return \League\OAuth2\Server\Entities\ClientEntityInterface
|
||||
*/
|
||||
public function getClientEntity($clientIdentifier, $grantType, $clientSecret = null);
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* OAuth 2.0 MAC Token Interface.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
interface MacTokenInterface extends RepositoryInterface
|
||||
{
|
||||
/**
|
||||
* Create a MAC key linked to an access token.
|
||||
*
|
||||
* @param string $macKey
|
||||
* @param string $accessToken
|
||||
*/
|
||||
public function persistMacTokenEntity($macKey, $accessToken);
|
||||
|
||||
/**
|
||||
* Get a MAC key by access token.
|
||||
*
|
||||
* @param string $accessToken
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMacKeyByAccessTokenString($accessToken);
|
||||
}
|
||||
@@ -10,17 +10,24 @@
|
||||
*/
|
||||
namespace League\OAuth2\Server\Repositories;
|
||||
|
||||
use League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\RefreshTokenEntityInterface;
|
||||
|
||||
/**
|
||||
* Refresh token interface.
|
||||
*/
|
||||
interface RefreshTokenRepositoryInterface extends RepositoryInterface
|
||||
{
|
||||
/**
|
||||
* Creates a new refresh token
|
||||
*
|
||||
* @return RefreshTokenEntityInterface
|
||||
*/
|
||||
public function getNewRefreshToken();
|
||||
|
||||
/**
|
||||
* Create a new refresh token_name.
|
||||
*
|
||||
* @param \League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface $refreshTokenEntity
|
||||
* @param \League\OAuth2\Server\Entities\RefreshTokenEntityInterface $refreshTokenEntity
|
||||
*/
|
||||
public function persistNewRefreshToken(RefreshTokenEntityInterface $refreshTokenEntity);
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
*/
|
||||
namespace League\OAuth2\Server\Repositories;
|
||||
|
||||
use League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface;
|
||||
use League\OAuth2\Server\Entities\Interfaces\ScopeEntityInterface;
|
||||
use League\OAuth2\Server\Entities\ClientEntityInterface;
|
||||
use League\OAuth2\Server\Entities\ScopeEntityInterface;
|
||||
|
||||
/**
|
||||
* Scope interface.
|
||||
@@ -23,7 +23,7 @@ interface ScopeRepositoryInterface extends RepositoryInterface
|
||||
*
|
||||
* @param string $identifier The scope identifier
|
||||
*
|
||||
* @return \League\OAuth2\Server\Entities\Interfaces\ScopeEntityInterface
|
||||
* @return \League\OAuth2\Server\Entities\ScopeEntityInterface
|
||||
*/
|
||||
public function getScopeEntityByIdentifier($identifier);
|
||||
|
||||
@@ -31,12 +31,12 @@ interface ScopeRepositoryInterface extends RepositoryInterface
|
||||
* Given a client, grant type and optional user identifier validate the set of scopes requested are valid and optionally
|
||||
* append additional scopes or remove requested scopes.
|
||||
*
|
||||
* @param ScopeEntityInterface[] $scopes
|
||||
* @param string $grantType
|
||||
* @param \League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface $clientEntity
|
||||
* @param null|string $userIdentifier
|
||||
* @param ScopeEntityInterface[] $scopes
|
||||
* @param string $grantType
|
||||
* @param \League\OAuth2\Server\Entities\ClientEntityInterface $clientEntity
|
||||
* @param null|string $userIdentifier
|
||||
*
|
||||
* @return \League\OAuth2\Server\Entities\Interfaces\ScopeEntityInterface[]
|
||||
* @return \League\OAuth2\Server\Entities\ScopeEntityInterface[]
|
||||
*/
|
||||
public function finalizeScopes(
|
||||
array $scopes,
|
||||
|
||||
@@ -2,19 +2,19 @@
|
||||
|
||||
namespace League\OAuth2\Server\Repositories;
|
||||
|
||||
use League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface;
|
||||
use League\OAuth2\Server\Entities\ClientEntityInterface;
|
||||
|
||||
interface UserRepositoryInterface extends RepositoryInterface
|
||||
{
|
||||
/**
|
||||
* Get a user entity.
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param string $grantType The grant type used
|
||||
* @param \League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface $clientEntity
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param string $grantType The grant type used
|
||||
* @param \League\OAuth2\Server\Entities\ClientEntityInterface $clientEntity
|
||||
*
|
||||
* @return \League\OAuth2\Server\Entities\Interfaces\UserEntityInterface
|
||||
* @return \League\OAuth2\Server\Entities\UserEntityInterface
|
||||
*/
|
||||
public function getUserEntityByUserCredentials(
|
||||
$username,
|
||||
|
||||
@@ -26,6 +26,7 @@ class RequestEvent extends Event
|
||||
|
||||
/**
|
||||
* @return ServerRequestInterface
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function getRequest()
|
||||
{
|
||||
|
||||
171
src/RequestTypes/AuthorizationRequest.php
Normal file
171
src/RequestTypes/AuthorizationRequest.php
Normal file
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
|
||||
namespace League\OAuth2\Server\RequestTypes;
|
||||
|
||||
use League\OAuth2\Server\Entities\ClientEntityInterface;
|
||||
use League\OAuth2\Server\Entities\ScopeEntityInterface;
|
||||
use League\OAuth2\Server\Entities\UserEntityInterface;
|
||||
|
||||
class AuthorizationRequest
|
||||
{
|
||||
/**
|
||||
* The grant type identifier
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $grantTypeId;
|
||||
|
||||
/**
|
||||
* The client identifier
|
||||
*
|
||||
* @var ClientEntityInterface
|
||||
*/
|
||||
protected $client;
|
||||
|
||||
/**
|
||||
* The user identifier
|
||||
*
|
||||
* @var UserEntityInterface
|
||||
*/
|
||||
protected $user;
|
||||
|
||||
/**
|
||||
* An array of scope identifiers
|
||||
*
|
||||
* @var ScopeEntityInterface[]
|
||||
*/
|
||||
protected $scopes = [];
|
||||
|
||||
/**
|
||||
* Has the user authorized the authorization request
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $authorizationApproved = false;
|
||||
|
||||
/**
|
||||
* The redirect URI used in the request
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectUri;
|
||||
|
||||
/**
|
||||
* The state parameter on the authorization request
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getGrantTypeId()
|
||||
{
|
||||
return $this->grantTypeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $grantTypeId
|
||||
*/
|
||||
public function setGrantTypeId($grantTypeId)
|
||||
{
|
||||
$this->grantTypeId = $grantTypeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ClientEntityInterface
|
||||
*/
|
||||
public function getClient()
|
||||
{
|
||||
return $this->client;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClientEntityInterface $client
|
||||
*/
|
||||
public function setClient(ClientEntityInterface $client)
|
||||
{
|
||||
$this->client = $client;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return UserEntityInterface
|
||||
*/
|
||||
public function getUser()
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UserEntityInterface $user
|
||||
*/
|
||||
public function setUser(UserEntityInterface $user)
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \League\OAuth2\Server\Entities\ScopeEntityInterface[]
|
||||
*/
|
||||
public function getScopes()
|
||||
{
|
||||
return $this->scopes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \League\OAuth2\Server\Entities\ScopeEntityInterface[] $scopes
|
||||
*/
|
||||
public function setScopes($scopes)
|
||||
{
|
||||
$this->scopes = $scopes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isAuthorizationApproved()
|
||||
{
|
||||
return $this->authorizationApproved;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $authorizationApproved
|
||||
*/
|
||||
public function setAuthorizationApproved($authorizationApproved)
|
||||
{
|
||||
$this->authorizationApproved = $authorizationApproved;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRedirectUri()
|
||||
{
|
||||
return $this->redirectUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $redirectUri
|
||||
*/
|
||||
public function setRedirectUri($redirectUri)
|
||||
{
|
||||
$this->redirectUri = $redirectUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getState()
|
||||
{
|
||||
return $this->state;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $state
|
||||
*/
|
||||
public function setState($state)
|
||||
{
|
||||
$this->state = $state;
|
||||
}
|
||||
}
|
||||
@@ -11,37 +11,23 @@
|
||||
namespace League\OAuth2\Server\ResponseTypes;
|
||||
|
||||
use League\OAuth2\Server\CryptTrait;
|
||||
use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface;
|
||||
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
|
||||
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\RefreshTokenEntityInterface;
|
||||
|
||||
abstract class AbstractResponseType implements ResponseTypeInterface
|
||||
{
|
||||
use CryptTrait;
|
||||
|
||||
/**
|
||||
* @var \League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface
|
||||
* @var \League\OAuth2\Server\Entities\AccessTokenEntityInterface
|
||||
*/
|
||||
protected $accessToken;
|
||||
|
||||
/**
|
||||
* @var \League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface
|
||||
* @var \League\OAuth2\Server\Entities\RefreshTokenEntityInterface
|
||||
*/
|
||||
protected $refreshToken;
|
||||
|
||||
/**
|
||||
* @var \League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface
|
||||
*/
|
||||
protected $accessTokenRepository;
|
||||
|
||||
/**
|
||||
* @param \League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface $accessTokenRepository
|
||||
*/
|
||||
public function __construct(AccessTokenRepositoryInterface $accessTokenRepository)
|
||||
{
|
||||
$this->accessTokenRepository = $accessTokenRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*/
|
||||
namespace League\OAuth2\Server\ResponseTypes;
|
||||
|
||||
use League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\RefreshTokenEntityInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class BearerTokenResponse extends AbstractResponseType
|
||||
@@ -22,7 +22,7 @@ class BearerTokenResponse extends AbstractResponseType
|
||||
{
|
||||
$expireDateTime = $this->accessToken->getExpiryDateTime()->getTimestamp();
|
||||
|
||||
$jwtAccessToken = $this->accessToken->convertToJWT($this->privateKeyPath);
|
||||
$jwtAccessToken = $this->accessToken->convertToJWT($this->privateKey);
|
||||
|
||||
$responseParams = [
|
||||
'token_type' => 'Bearer',
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace League\OAuth2\Server\ResponseTypes;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class HtmlResponse extends AbstractResponseType
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $html = '';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $statusCode = 200;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $headers = [];
|
||||
|
||||
/**
|
||||
* @param string $html
|
||||
*/
|
||||
public function setHtml($html)
|
||||
{
|
||||
$this->html = $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $statusCode
|
||||
*/
|
||||
public function setStatusCode($statusCode = 200)
|
||||
{
|
||||
$this->statusCode = $statusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ResponseInterface $response
|
||||
*
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function generateHttpResponse(ResponseInterface $response)
|
||||
{
|
||||
$response->getBody()->write($this->html);
|
||||
|
||||
foreach ($this->headers as $key => $value) {
|
||||
$response = $response->withHeader($key, $value);
|
||||
}
|
||||
|
||||
return $response
|
||||
->withStatus($this->statusCode)
|
||||
->withHeader('content-type', 'text/html');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
*/
|
||||
public function setHeader($key, $value)
|
||||
{
|
||||
$this->headers[$key] = $value;
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,6 @@ class RedirectResponse extends AbstractResponseType
|
||||
*/
|
||||
public function generateHttpResponse(ResponseInterface $response)
|
||||
{
|
||||
return $response->withStatus(302)->withHeader('location', $this->redirectUri);
|
||||
return $response->withStatus(302)->withHeader('Location', $this->redirectUri);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,19 +10,19 @@
|
||||
*/
|
||||
namespace League\OAuth2\Server\ResponseTypes;
|
||||
|
||||
use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\RefreshTokenEntityInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
interface ResponseTypeInterface
|
||||
{
|
||||
/**
|
||||
* @param \League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface $accessToken
|
||||
* @param \League\OAuth2\Server\Entities\AccessTokenEntityInterface $accessToken
|
||||
*/
|
||||
public function setAccessToken(AccessTokenEntityInterface $accessToken);
|
||||
|
||||
/**
|
||||
* @param \League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface $refreshToken
|
||||
* @param \League\OAuth2\Server\Entities\RefreshTokenEntityInterface $refreshToken
|
||||
*/
|
||||
public function setRefreshToken(RefreshTokenEntityInterface $refreshToken);
|
||||
|
||||
|
||||
103
src/Server.php
103
src/Server.php
@@ -12,6 +12,7 @@ use League\OAuth2\Server\Grant\GrantTypeInterface;
|
||||
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
|
||||
use League\OAuth2\Server\Repositories\ClientRepositoryInterface;
|
||||
use League\OAuth2\Server\Repositories\ScopeRepositoryInterface;
|
||||
use League\OAuth2\Server\RequestTypes\AuthorizationRequest;
|
||||
use League\OAuth2\Server\ResponseTypes\BearerTokenResponse;
|
||||
use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
@@ -32,20 +33,20 @@ class Server implements EmitterAwareInterface
|
||||
protected $grantTypeAccessTokenTTL = [];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @var \League\OAuth2\Server\CryptKey
|
||||
*/
|
||||
protected $privateKeyPath;
|
||||
protected $privateKey;
|
||||
|
||||
/**
|
||||
* @var \League\OAuth2\Server\CryptKey
|
||||
*/
|
||||
protected $publicKey;
|
||||
|
||||
/**
|
||||
* @var ResponseTypeInterface
|
||||
*/
|
||||
protected $responseType;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $publicKeyPath;
|
||||
|
||||
/**
|
||||
* @var \League\OAuth2\Server\Repositories\ClientRepositoryInterface
|
||||
*/
|
||||
@@ -72,8 +73,8 @@ class Server implements EmitterAwareInterface
|
||||
* @param \League\OAuth2\Server\Repositories\ClientRepositoryInterface $clientRepository
|
||||
* @param \League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface $accessTokenRepository
|
||||
* @param \League\OAuth2\Server\Repositories\ScopeRepositoryInterface $scopeRepository
|
||||
* @param string $privateKeyPath
|
||||
* @param string $publicKeyPath
|
||||
* @param \League\OAuth2\Server\CryptKey|string $privateKey
|
||||
* @param \League\OAuth2\Server\CryptKey|string $publicKey
|
||||
* @param null|\League\OAuth2\Server\ResponseTypes\ResponseTypeInterface $responseType
|
||||
* @param null|\League\OAuth2\Server\AuthorizationValidators\AuthorizationValidatorInterface $authorizationValidator
|
||||
*/
|
||||
@@ -81,16 +82,25 @@ class Server implements EmitterAwareInterface
|
||||
ClientRepositoryInterface $clientRepository,
|
||||
AccessTokenRepositoryInterface $accessTokenRepository,
|
||||
ScopeRepositoryInterface $scopeRepository,
|
||||
$privateKeyPath,
|
||||
$publicKeyPath,
|
||||
$privateKey,
|
||||
$publicKey,
|
||||
ResponseTypeInterface $responseType = null,
|
||||
AuthorizationValidatorInterface $authorizationValidator = null
|
||||
) {
|
||||
$this->clientRepository = $clientRepository;
|
||||
$this->accessTokenRepository = $accessTokenRepository;
|
||||
$this->scopeRepository = $scopeRepository;
|
||||
$this->privateKeyPath = $privateKeyPath;
|
||||
$this->publicKeyPath = $publicKeyPath;
|
||||
|
||||
if (!$privateKey instanceof CryptKey) {
|
||||
$privateKey = new CryptKey($privateKey);
|
||||
}
|
||||
$this->privateKey = $privateKey;
|
||||
|
||||
if (!$publicKey instanceof CryptKey) {
|
||||
$publicKey = new CryptKey($publicKey);
|
||||
}
|
||||
$this->publicKey = $publicKey;
|
||||
|
||||
$this->responseType = $responseType;
|
||||
$this->authorizationValidator = $authorizationValidator;
|
||||
}
|
||||
@@ -101,37 +111,80 @@ class Server implements EmitterAwareInterface
|
||||
* @param \League\OAuth2\Server\Grant\GrantTypeInterface $grantType
|
||||
* @param \DateInterval $accessTokenTTL
|
||||
*/
|
||||
public function enableGrantType(GrantTypeInterface $grantType, DateInterval $accessTokenTTL)
|
||||
public function enableGrantType(GrantTypeInterface $grantType, DateInterval $accessTokenTTL = null)
|
||||
{
|
||||
if ($accessTokenTTL instanceof DateInterval === false) {
|
||||
$accessTokenTTL = new \DateInterval('PT1H');
|
||||
}
|
||||
|
||||
$grantType->setAccessTokenRepository($this->accessTokenRepository);
|
||||
$grantType->setClientRepository($this->clientRepository);
|
||||
$grantType->setScopeRepository($this->scopeRepository);
|
||||
$grantType->setPrivateKeyPath($this->privateKeyPath);
|
||||
$grantType->setPublicKeyPath($this->publicKeyPath);
|
||||
$grantType->setPrivateKey($this->privateKey);
|
||||
$grantType->setPublicKey($this->publicKey);
|
||||
$grantType->setEmitter($this->getEmitter());
|
||||
|
||||
$this->enabledGrantTypes[$grantType->getIdentifier()] = $grantType;
|
||||
|
||||
$this->grantTypeAccessTokenTTL[$grantType->getIdentifier()] = $accessTokenTTL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate an authorization request
|
||||
*
|
||||
* @param \Psr\Http\Message\ServerRequestInterface $request
|
||||
*
|
||||
* @throws \League\OAuth2\Server\Exception\OAuthServerException
|
||||
*
|
||||
* @return \League\OAuth2\Server\RequestTypes\AuthorizationRequest|null
|
||||
*/
|
||||
public function validateAuthorizationRequest(ServerRequestInterface $request)
|
||||
{
|
||||
$authRequest = null;
|
||||
$enabledGrantTypes = $this->enabledGrantTypes;
|
||||
while ($authRequest === null && $grantType = array_shift($enabledGrantTypes)) {
|
||||
/** @var \League\OAuth2\Server\Grant\GrantTypeInterface $grantType */
|
||||
if ($grantType->canRespondToAuthorizationRequest($request)) {
|
||||
$authRequest = $grantType->validateAuthorizationRequest($request);
|
||||
|
||||
return $authRequest;
|
||||
}
|
||||
}
|
||||
|
||||
throw OAuthServerException::unsupportedGrantType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Complete an authorization request
|
||||
*
|
||||
* @param \League\OAuth2\Server\RequestTypes\AuthorizationRequest $authRequest
|
||||
* @param \Psr\Http\Message\ResponseInterface $response
|
||||
*
|
||||
* @return \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface
|
||||
*/
|
||||
public function completeAuthorizationRequest(AuthorizationRequest $authRequest, ResponseInterface $response)
|
||||
{
|
||||
return $this->enabledGrantTypes[$authRequest->getGrantTypeId()]
|
||||
->completeAuthorizationRequest($authRequest)
|
||||
->generateHttpResponse($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an access token response.
|
||||
*
|
||||
* @param \Psr\Http\Message\ServerRequestInterface|null $request
|
||||
* @param \Psr\Http\Message\ResponseInterface|null $response
|
||||
* @param \Psr\Http\Message\ServerRequestInterface $request
|
||||
* @param \Psr\Http\Message\ResponseInterface $response
|
||||
*
|
||||
* @throws \League\OAuth2\Server\Exception\OAuthServerException
|
||||
*
|
||||
* @return \Psr\Http\Message\ResponseInterface
|
||||
*/
|
||||
public function respondToRequest(ServerRequestInterface $request, ResponseInterface $response)
|
||||
public function respondToAccessTokenRequest(ServerRequestInterface $request, ResponseInterface $response)
|
||||
{
|
||||
$tokenResponse = null;
|
||||
while ($tokenResponse === null && $grantType = array_shift($this->enabledGrantTypes)) {
|
||||
/** @var \League\OAuth2\Server\Grant\GrantTypeInterface $grantType */
|
||||
if ($grantType->canRespondToRequest($request)) {
|
||||
$tokenResponse = $grantType->respondToRequest(
|
||||
if ($grantType->canRespondToAccessTokenRequest($request)) {
|
||||
$tokenResponse = $grantType->respondToAccessTokenRequest(
|
||||
$request,
|
||||
$this->getResponseType(),
|
||||
$this->grantTypeAccessTokenTTL[$grantType->getIdentifier()]
|
||||
@@ -171,8 +224,7 @@ class Server implements EmitterAwareInterface
|
||||
$this->responseType = new BearerTokenResponse($this->accessTokenRepository);
|
||||
}
|
||||
|
||||
$this->responseType->setPublicKeyPath($this->publicKeyPath);
|
||||
$this->responseType->setPrivateKeyPath($this->privateKeyPath);
|
||||
$this->responseType->setPrivateKey($this->privateKey);
|
||||
|
||||
return $this->responseType;
|
||||
}
|
||||
@@ -186,8 +238,7 @@ class Server implements EmitterAwareInterface
|
||||
$this->authorizationValidator = new BearerTokenValidator($this->accessTokenRepository);
|
||||
}
|
||||
|
||||
$this->authorizationValidator->setPublicKeyPath($this->publicKeyPath);
|
||||
$this->authorizationValidator->setPrivateKeyPath($this->privateKeyPath);
|
||||
$this->authorizationValidator->setPublicKey($this->publicKey);
|
||||
|
||||
return $this->authorizationValidator;
|
||||
}
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Base template renderer.
|
||||
*
|
||||
* @author Julián Gutiérrez <juliangut@gmail.com>
|
||||
* @copyright Copyright (c) Alex Bilbie
|
||||
* @license http://mit-license.org/
|
||||
*
|
||||
* @link https://github.com/thephpleague/oauth2-server
|
||||
*/
|
||||
namespace League\OAuth2\Server\TemplateRenderer;
|
||||
|
||||
abstract class AbstractRenderer implements RendererInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $loginTemplate;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $authorizeTemplate;
|
||||
|
||||
/**
|
||||
* PlatesRenderer constructor.
|
||||
*
|
||||
* @param string $loginTemplate
|
||||
* @param string $authorizeTemplate
|
||||
*/
|
||||
public function __construct($loginTemplate, $authorizeTemplate)
|
||||
{
|
||||
$this->loginTemplate = $loginTemplate;
|
||||
$this->authorizeTemplate = $authorizeTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render login template.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function renderLogin(array $data = [])
|
||||
{
|
||||
return $this->render($this->loginTemplate, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render authorize template.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function renderAuthorize(array $data = [])
|
||||
{
|
||||
return $this->render($this->authorizeTemplate, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render template.
|
||||
*
|
||||
* @param string $template
|
||||
* @param array $data
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function render($template, array $data = []);
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Authorize <?=$this->e($client->getName())?></title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h1>
|
||||
Authorize <?=$this->e($client->getName())?>
|
||||
</h1>
|
||||
|
||||
<p>
|
||||
Do you want to authorize <?=$this->e($client->getName())?> to access the following data?
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<?php foreach ($scopes as $scope): ?>
|
||||
<li><?=$scope->getIdentifier()?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
|
||||
<form method="POST">
|
||||
<input type="hidden" value="approve" name="action">
|
||||
<button type="submit">Approve</button>
|
||||
</form>
|
||||
|
||||
<form method="POST">
|
||||
<input type="hidden" value="deny" name="action">
|
||||
<button type="submit">Deny</button>
|
||||
</form>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,35 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Login</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h1>Login</h1>
|
||||
|
||||
<?php if ($error !== null): ?>
|
||||
<div style="border:solid 1px red; padding: 1rem; margin-bottom:1rem">
|
||||
<?=$this->e($error)?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form method="POST">
|
||||
|
||||
<label for="username">Username</label>
|
||||
<input type="text" id="username" name="username">
|
||||
|
||||
<br>
|
||||
|
||||
<label for="password">Password</label>
|
||||
<input type="password" id="password" name="password">
|
||||
|
||||
<br>
|
||||
|
||||
<input type="submit" value="Login">
|
||||
|
||||
</form>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,41 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Mustache template renderer bridge.
|
||||
*
|
||||
* @author Julián Gutiérrez <juliangut@gmail.com>
|
||||
* @copyright Copyright (c) Alex Bilbie
|
||||
* @license http://mit-license.org/
|
||||
*
|
||||
* @link https://github.com/thephpleague/oauth2-server
|
||||
*/
|
||||
namespace League\OAuth2\Server\TemplateRenderer;
|
||||
|
||||
class MustacheRenderer extends AbstractRenderer
|
||||
{
|
||||
/**
|
||||
* @var \Mustache_Engine
|
||||
*/
|
||||
private $engine;
|
||||
|
||||
/**
|
||||
* PlatesRenderer constructor.
|
||||
*
|
||||
* @param \Mustache_Engine $engine
|
||||
* @param string $loginTemplate
|
||||
* @param string $authorizeTemplate
|
||||
*/
|
||||
public function __construct(\Mustache_Engine $engine, $loginTemplate, $authorizeTemplate)
|
||||
{
|
||||
parent::__construct($loginTemplate, $authorizeTemplate);
|
||||
|
||||
$this->engine = $engine;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function render($template, array $data = [])
|
||||
{
|
||||
return $this->engine->render($template, $data);
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Plates template renderer bridge.
|
||||
*
|
||||
* @author Julián Gutiérrez <juliangut@gmail.com>
|
||||
* @copyright Copyright (c) Alex Bilbie
|
||||
* @license http://mit-license.org/
|
||||
*
|
||||
* @link https://github.com/thephpleague/oauth2-server
|
||||
*/
|
||||
namespace League\OAuth2\Server\TemplateRenderer;
|
||||
|
||||
use League\Plates\Engine;
|
||||
|
||||
class PlatesRenderer extends AbstractRenderer
|
||||
{
|
||||
/**
|
||||
* @var \League\Plates\Engine
|
||||
*/
|
||||
private $engine;
|
||||
|
||||
/**
|
||||
* PlatesRenderer constructor.
|
||||
*
|
||||
* @param \League\Plates\Engine $engine
|
||||
* @param string $loginTemplate
|
||||
* @param string $authorizeTemplate
|
||||
*/
|
||||
public function __construct(Engine $engine, $loginTemplate, $authorizeTemplate)
|
||||
{
|
||||
parent::__construct($loginTemplate, $authorizeTemplate);
|
||||
|
||||
$this->engine = $engine;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function render($template, array $data = [])
|
||||
{
|
||||
if ($this->engine->getFileExtension()) {
|
||||
$template = preg_replace(sprintf('/\.%s$/', $this->engine->getFileExtension()), '', $template);
|
||||
}
|
||||
|
||||
return $this->engine->render($template, $data);
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace League\OAuth2\Server\TemplateRenderer;
|
||||
|
||||
interface RendererInterface
|
||||
{
|
||||
/**
|
||||
* Render login template.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function renderLogin(array $data = []);
|
||||
|
||||
/**
|
||||
* Render authorize template.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function renderAuthorize(array $data = []);
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty template renderer bridge.
|
||||
*
|
||||
* @author Julián Gutiérrez <juliangut@gmail.com>
|
||||
* @copyright Copyright (c) Alex Bilbie
|
||||
* @license http://mit-license.org/
|
||||
*
|
||||
* @link https://github.com/thephpleague/oauth2-server
|
||||
*/
|
||||
namespace League\OAuth2\Server\TemplateRenderer;
|
||||
|
||||
class SmartyRenderer extends AbstractRenderer
|
||||
{
|
||||
/**
|
||||
* Smarty class.
|
||||
*
|
||||
* @var \Smarty
|
||||
*/
|
||||
private $smarty;
|
||||
|
||||
/**
|
||||
* PlatesRenderer constructor.
|
||||
*
|
||||
* @param \Smarty $smarty
|
||||
* @param string $loginTemplate
|
||||
* @param string $authorizeTemplate
|
||||
*/
|
||||
public function __construct(\Smarty $smarty, $loginTemplate, $authorizeTemplate)
|
||||
{
|
||||
parent::__construct($loginTemplate, $authorizeTemplate);
|
||||
|
||||
$this->smarty = $smarty;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function render($template, array $data = [])
|
||||
{
|
||||
$this->smarty->assign($data);
|
||||
|
||||
$output = $this->smarty->fetch($template);
|
||||
|
||||
$this->smarty->clear_assign(array_keys($data));
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Twig template renderer bridge.
|
||||
*
|
||||
* @author Julián Gutiérrez <juliangut@gmail.com>
|
||||
* @copyright Copyright (c) Alex Bilbie
|
||||
* @license http://mit-license.org/
|
||||
*
|
||||
* @link https://github.com/thephpleague/oauth2-server
|
||||
*/
|
||||
namespace League\OAuth2\Server\TemplateRenderer;
|
||||
|
||||
class TwigRenderer extends AbstractRenderer
|
||||
{
|
||||
/**
|
||||
* @var \Twig_Environment
|
||||
*/
|
||||
private $environment;
|
||||
|
||||
/**
|
||||
* PlatesRenderer constructor.
|
||||
*
|
||||
* @param \Twig_Environment $environment
|
||||
* @param string $loginTemplate
|
||||
* @param string $authorizeTemplate
|
||||
*/
|
||||
public function __construct(\Twig_Environment $environment, $loginTemplate, $authorizeTemplate)
|
||||
{
|
||||
parent::__construct($loginTemplate, $authorizeTemplate);
|
||||
|
||||
$this->environment = $environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function render($template, array $data = [])
|
||||
{
|
||||
return $this->environment->loadTemplate($template)->render($data);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace LeagueTests\Utils;
|
||||
|
||||
use League\OAuth2\Server\CryptKey;
|
||||
use LeagueTests\Stubs\CryptTraitStub;
|
||||
|
||||
class CryptTraitTest extends \PHPUnit_Framework_TestCase
|
||||
@@ -31,7 +32,7 @@ class CryptTraitTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testBadPrivateKey()
|
||||
{
|
||||
$this->cryptStub->setPrivateKeyPath(__DIR__ . '/Stubs/public.key');
|
||||
$this->cryptStub->setPrivateKey(new CryptKey(__DIR__ . '/Stubs/public.key'));
|
||||
$this->cryptStub->doEncrypt('');
|
||||
}
|
||||
|
||||
@@ -40,7 +41,15 @@ class CryptTraitTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testBadPublicKey()
|
||||
{
|
||||
$this->cryptStub->setPublicKeyPath(__DIR__ . '/Stubs/private.key');
|
||||
$this->cryptStub->setPublicKey(new CryptKey(__DIR__ . '/Stubs/private.key'));
|
||||
$this->cryptStub->doDecrypt('');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
*/
|
||||
public function testNonExistentKey()
|
||||
{
|
||||
new CryptKey('foo/bar');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,17 +3,21 @@
|
||||
namespace LeagueTests\Grant;
|
||||
|
||||
use League\Event\Emitter;
|
||||
use League\OAuth2\Server\Entities\AccessTokenEntity;
|
||||
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\CryptKey;
|
||||
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\AuthCodeEntityInterface;
|
||||
use League\OAuth2\Server\Entities\RefreshTokenEntityInterface;
|
||||
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 League\OAuth2\Server\RequestTypes\AuthorizationRequest;
|
||||
use LeagueTests\Stubs\AccessTokenEntity;
|
||||
use LeagueTests\Stubs\AuthCodeEntity;
|
||||
use LeagueTests\Stubs\ClientEntity;
|
||||
use LeagueTests\Stubs\RefreshTokenEntity;
|
||||
use LeagueTests\Stubs\ScopeEntity;
|
||||
use Zend\Diactoros\ServerRequest;
|
||||
|
||||
@@ -23,8 +27,8 @@ class AbstractGrantTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/** @var AbstractGrant $grantMock */
|
||||
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
|
||||
$grantMock->setPrivateKeyPath('./private.key');
|
||||
$grantMock->setPublicKeyPath('./public.key');
|
||||
$grantMock->setPrivateKey(new CryptKey(__DIR__ . '/../Stubs/private.key'));
|
||||
$grantMock->setPublicKey(new CryptKey(__DIR__ . '/../Stubs/public.key'));
|
||||
$grantMock->setEmitter(new Emitter());
|
||||
}
|
||||
|
||||
@@ -57,8 +61,6 @@ class AbstractGrantTest extends \PHPUnit_Framework_TestCase
|
||||
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);
|
||||
@@ -175,8 +177,36 @@ class AbstractGrantTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$serverRequest = new ServerRequest();
|
||||
$serverRequest = $serverRequest->withParsedBody([
|
||||
'client_id' => 'foo',
|
||||
'redirect_uri' => 'http://bar/foo',
|
||||
'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 testValidateClientInvalidRedirectUriArray()
|
||||
{
|
||||
$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');
|
||||
@@ -221,12 +251,16 @@ class AbstractGrantTest extends \PHPUnit_Framework_TestCase
|
||||
'grant_type' => 'foobar',
|
||||
]);
|
||||
|
||||
$this->assertTrue($grantMock->canRespondToRequest($serverRequest));
|
||||
$this->assertTrue($grantMock->canRespondToAccessTokenRequest($serverRequest));
|
||||
}
|
||||
|
||||
public function testIssueRefreshToken()
|
||||
{
|
||||
$refreshTokenRepoMock = $this->getMock(RefreshTokenRepositoryInterface::class);
|
||||
$refreshTokenRepoMock
|
||||
->expects($this->once())
|
||||
->method('getNewRefreshToken')
|
||||
->willReturn(new RefreshTokenEntity());
|
||||
|
||||
/** @var AbstractGrant $grantMock */
|
||||
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
|
||||
@@ -248,6 +282,7 @@ class AbstractGrantTest extends \PHPUnit_Framework_TestCase
|
||||
public function testIssueAccessToken()
|
||||
{
|
||||
$accessTokenRepoMock = $this->getMock(AccessTokenRepositoryInterface::class);
|
||||
$accessTokenRepoMock->method('getNewToken')->willReturn(new AccessTokenEntity());
|
||||
|
||||
/** @var AbstractGrant $grantMock */
|
||||
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
|
||||
@@ -272,6 +307,7 @@ class AbstractGrantTest extends \PHPUnit_Framework_TestCase
|
||||
public function testIssueAuthCode()
|
||||
{
|
||||
$authCodeRepoMock = $this->getMock(AuthCodeRepositoryInterface::class);
|
||||
$authCodeRepoMock->expects($this->once())->method('getNewAuthCode')->willReturn(new AuthCodeEntity());
|
||||
|
||||
/** @var AbstractGrant $grantMock */
|
||||
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
|
||||
@@ -339,7 +375,7 @@ class AbstractGrantTest extends \PHPUnit_Framework_TestCase
|
||||
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
|
||||
$grantMock->setScopeRepository($scopeRepositoryMock);
|
||||
|
||||
$this->assertEquals([$scope], $grantMock->validateScopes('basic ', new ClientEntity()));
|
||||
$this->assertEquals([$scope], $grantMock->validateScopes('basic '));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -354,7 +390,7 @@ class AbstractGrantTest extends \PHPUnit_Framework_TestCase
|
||||
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
|
||||
$grantMock->setScopeRepository($scopeRepositoryMock);
|
||||
|
||||
$grantMock->validateScopes('basic ', new ClientEntity());
|
||||
$grantMock->validateScopes('basic ');
|
||||
}
|
||||
|
||||
public function testGenerateUniqueIdentifier()
|
||||
@@ -367,4 +403,28 @@ class AbstractGrantTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$this->assertTrue(is_string($method->invoke($grantMock)));
|
||||
}
|
||||
|
||||
public function testCanRespondToAuthorizationRequest()
|
||||
{
|
||||
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
|
||||
$this->assertFalse($grantMock->canRespondToAuthorizationRequest(new ServerRequest()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
*/
|
||||
public function testValidateAuthorizationRequest()
|
||||
{
|
||||
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
|
||||
$grantMock->validateAuthorizationRequest(new ServerRequest());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
*/
|
||||
public function testCompleteAuthorizationRequest()
|
||||
{
|
||||
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
|
||||
$grantMock->completeAuthorizationRequest(new AuthorizationRequest());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
namespace LeagueTests\Grant;
|
||||
|
||||
use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface;
|
||||
use League\OAuth2\Server\CryptKey;
|
||||
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\RefreshTokenEntityInterface;
|
||||
use League\OAuth2\Server\Exception\OAuthServerException;
|
||||
use League\OAuth2\Server\Grant\AuthCodeGrant;
|
||||
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
|
||||
@@ -11,16 +12,16 @@ 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\Repositories\UserRepositoryInterface;
|
||||
use League\OAuth2\Server\ResponseTypes\HtmlResponse;
|
||||
use League\OAuth2\Server\RequestTypes\AuthorizationRequest;
|
||||
use League\OAuth2\Server\ResponseTypes\RedirectResponse;
|
||||
use LeagueTests\Stubs\AccessTokenEntity;
|
||||
use LeagueTests\Stubs\AuthCodeEntity;
|
||||
use LeagueTests\Stubs\ClientEntity;
|
||||
use LeagueTests\Stubs\CryptTraitStub;
|
||||
use LeagueTests\Stubs\RefreshTokenEntity;
|
||||
use LeagueTests\Stubs\ScopeEntity;
|
||||
use LeagueTests\Stubs\StubResponseType;
|
||||
use LeagueTests\Stubs\UserEntity;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Zend\Diactoros\Response;
|
||||
use Zend\Diactoros\ServerRequest;
|
||||
|
||||
class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
|
||||
@@ -40,19 +41,17 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
|
||||
$grant = new AuthCodeGrant(
|
||||
$this->getMock(AuthCodeRepositoryInterface::class),
|
||||
$this->getMock(RefreshTokenRepositoryInterface::class),
|
||||
$this->getMock(UserRepositoryInterface::class),
|
||||
new \DateInterval('PT10M')
|
||||
);
|
||||
|
||||
$this->assertEquals('authorization_code', $grant->getIdentifier());
|
||||
}
|
||||
|
||||
public function testCanRespondToRequest()
|
||||
public function testCanRespondToAuthorizationRequest()
|
||||
{
|
||||
$grant = new AuthCodeGrant(
|
||||
$this->getMock(AuthCodeRepositoryInterface::class),
|
||||
$this->getMock(RefreshTokenRepositoryInterface::class),
|
||||
$this->getMock(UserRepositoryInterface::class),
|
||||
new \DateInterval('PT10M')
|
||||
);
|
||||
|
||||
@@ -70,509 +69,257 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
|
||||
]
|
||||
);
|
||||
|
||||
$this->assertTrue($grant->canRespondToRequest($request));
|
||||
$this->assertTrue($grant->canRespondToAuthorizationRequest($request));
|
||||
}
|
||||
|
||||
public function testRespondToAuthorizationRequest()
|
||||
public function testValidateAuthorizationRequest()
|
||||
{
|
||||
$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);
|
||||
|
||||
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
|
||||
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
|
||||
|
||||
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
|
||||
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
|
||||
|
||||
$grant = new AuthCodeGrant(
|
||||
$this->getMock(AuthCodeRepositoryInterface::class),
|
||||
$this->getMock(RefreshTokenRepositoryInterface::class),
|
||||
$userRepositoryMock,
|
||||
new \DateInterval('PT10M')
|
||||
);
|
||||
$grant->setClientRepository($clientRepositoryMock);
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
$grant->setScopeRepository($scopeRepositoryMock);
|
||||
$grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
|
||||
$request = new ServerRequest(
|
||||
[
|
||||
'HTTP_HOST' => 'auth-server.tld',
|
||||
'REQUEST_URI' => '/authorize',
|
||||
],
|
||||
[],
|
||||
[],
|
||||
null,
|
||||
'POST',
|
||||
null,
|
||||
'php://input',
|
||||
[],
|
||||
[
|
||||
'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => 123])),
|
||||
],
|
||||
[
|
||||
$headers = [],
|
||||
$cookies = [],
|
||||
$queryParams = [
|
||||
'response_type' => 'code',
|
||||
'client_id' => 'foo',
|
||||
'state' => 'foobar',
|
||||
],
|
||||
[
|
||||
'username' => 'alex',
|
||||
'password' => 'whisky',
|
||||
'action' => 'approve',
|
||||
'redirect_uri' => 'http://foo/bar',
|
||||
]
|
||||
);
|
||||
|
||||
$response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
|
||||
|
||||
$this->assertTrue($response instanceof RedirectResponse);
|
||||
|
||||
$response = $response->generateHttpResponse(new Response);
|
||||
$this->assertTrue(strstr($response->getHeader('location')[0], 'http://foo/bar') !== false);
|
||||
$this->assertTrue($grant->validateAuthorizationRequest($request) instanceof AuthorizationRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
|
||||
* @expectedExceptionCode 9
|
||||
*/
|
||||
public function testRespondToAuthorizationRequestUserDenied()
|
||||
public function testValidateAuthorizationRequestRedirectUriArray()
|
||||
{
|
||||
$client = new ClientEntity();
|
||||
$client->setRedirectUri('http://foo/bar');
|
||||
$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();
|
||||
|
||||
$grant = new AuthCodeGrant(
|
||||
$this->getMock(AuthCodeRepositoryInterface::class),
|
||||
$this->getMock(RefreshTokenRepositoryInterface::class),
|
||||
$userRepositoryMock,
|
||||
new \DateInterval('PT10M')
|
||||
);
|
||||
$grant->setClientRepository($clientRepositoryMock);
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
$grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
|
||||
$request = new ServerRequest(
|
||||
[
|
||||
'HTTP_HOST' => 'auth-server.tld',
|
||||
'REQUEST_URI' => '/authorize',
|
||||
],
|
||||
[],
|
||||
[],
|
||||
null,
|
||||
'POST',
|
||||
null,
|
||||
'php://input',
|
||||
[],
|
||||
[
|
||||
'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => 123])),
|
||||
],
|
||||
[
|
||||
$headers = [],
|
||||
$cookies = [],
|
||||
$queryParams = [
|
||||
'response_type' => 'code',
|
||||
'client_id' => 'foo',
|
||||
'state' => 'foobar',
|
||||
],
|
||||
[
|
||||
'username' => 'alex',
|
||||
'password' => 'whisky',
|
||||
'action' => 'denied',
|
||||
'redirect_uri' => 'http://foo/bar',
|
||||
]
|
||||
);
|
||||
|
||||
$grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
|
||||
$this->assertTrue($grant->validateAuthorizationRequest($request) instanceof AuthorizationRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
|
||||
* @expectedExceptionCode 3
|
||||
*/
|
||||
public function testRespondToAuthorizationRequestMissingClientId()
|
||||
public function testValidateAuthorizationRequestMissingClientId()
|
||||
{
|
||||
$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->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
|
||||
$request = new ServerRequest(
|
||||
[
|
||||
'HTTP_HOST' => 'auth-server.tld',
|
||||
'REQUEST_URI' => '/authorize',
|
||||
],
|
||||
[],
|
||||
[],
|
||||
null,
|
||||
'POST',
|
||||
null,
|
||||
'php://input',
|
||||
[],
|
||||
[
|
||||
'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => 123])),
|
||||
],
|
||||
[
|
||||
$headers = [],
|
||||
$cookies = [],
|
||||
$queryParams = [
|
||||
'response_type' => 'code',
|
||||
],
|
||||
[
|
||||
'username' => 'alex',
|
||||
'password' => 'whisky',
|
||||
'action' => 'approve',
|
||||
]
|
||||
);
|
||||
|
||||
$grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
|
||||
}
|
||||
|
||||
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->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
|
||||
$request = new ServerRequest(
|
||||
[
|
||||
'HTTP_HOST' => 'auth-server.tld',
|
||||
'REQUEST_URI' => '/authorize',
|
||||
],
|
||||
[],
|
||||
null,
|
||||
'POST',
|
||||
'php://input',
|
||||
[],
|
||||
[
|
||||
'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => 123])),
|
||||
],
|
||||
[
|
||||
'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->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
|
||||
$request = new ServerRequest(
|
||||
[
|
||||
'HTTP_HOST' => 'auth-server.tld',
|
||||
'REQUEST_URI' => '/authorize',
|
||||
],
|
||||
[],
|
||||
null,
|
||||
'POST',
|
||||
'php://input',
|
||||
[],
|
||||
[
|
||||
'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => 123])),
|
||||
],
|
||||
[
|
||||
'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');
|
||||
}
|
||||
$grant->validateAuthorizationRequest($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
|
||||
* @expectedExceptionCode 7
|
||||
* @expectedExceptionCode 4
|
||||
*/
|
||||
public function testRespondToAuthorizationRequestBadCookie()
|
||||
public function testValidateAuthorizationRequestInvalidClientId()
|
||||
{
|
||||
$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);
|
||||
$clientRepositoryMock->method('getClientEntity')->willReturn(null);
|
||||
|
||||
$grant = new AuthCodeGrant(
|
||||
$this->getMock(AuthCodeRepositoryInterface::class),
|
||||
$this->getMock(RefreshTokenRepositoryInterface::class),
|
||||
$userRepositoryMock,
|
||||
new \DateInterval('PT10M')
|
||||
);
|
||||
$grant->setClientRepository($clientRepositoryMock);
|
||||
$grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
|
||||
$request = new ServerRequest(
|
||||
[
|
||||
'HTTP_HOST' => 'auth-server.tld',
|
||||
'REQUEST_URI' => '/authorize',
|
||||
],
|
||||
[],
|
||||
[],
|
||||
null,
|
||||
'POST',
|
||||
null,
|
||||
'php://input',
|
||||
[],
|
||||
[
|
||||
'oauth_authorize_request' => 'blah',
|
||||
],
|
||||
[
|
||||
$headers = [],
|
||||
$cookies = [],
|
||||
$queryParams = [
|
||||
'response_type' => 'code',
|
||||
'client_id' => 'foo',
|
||||
],
|
||||
[
|
||||
'username' => 'alex',
|
||||
'password' => 'whisky',
|
||||
'action' => 'approve',
|
||||
]
|
||||
);
|
||||
|
||||
$grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
|
||||
$grant->validateAuthorizationRequest($request);
|
||||
}
|
||||
|
||||
public function testRespondToAuthorizationRequestTryLogin()
|
||||
/**
|
||||
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
|
||||
* @expectedExceptionCode 4
|
||||
*/
|
||||
public function testValidateAuthorizationRequestBadRedirectUriString()
|
||||
{
|
||||
$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);
|
||||
|
||||
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
|
||||
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
|
||||
|
||||
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
|
||||
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
|
||||
|
||||
$grant = new AuthCodeGrant(
|
||||
$this->getMock(AuthCodeRepositoryInterface::class),
|
||||
$this->getMock(RefreshTokenRepositoryInterface::class),
|
||||
$userRepositoryMock,
|
||||
new \DateInterval('PT10M')
|
||||
);
|
||||
$grant->setClientRepository($clientRepositoryMock);
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
$grant->setScopeRepository($scopeRepositoryMock);
|
||||
$grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
|
||||
$request = new ServerRequest(
|
||||
[
|
||||
'HTTP_HOST' => 'auth-server.tld',
|
||||
'REQUEST_URI' => '/authorize',
|
||||
],
|
||||
[],
|
||||
[],
|
||||
null,
|
||||
'POST',
|
||||
null,
|
||||
'php://input',
|
||||
[],
|
||||
[
|
||||
'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => null])),
|
||||
],
|
||||
[
|
||||
$headers = [],
|
||||
$cookies = [],
|
||||
$queryParams = [
|
||||
'response_type' => 'code',
|
||||
'client_id' => 'foo',
|
||||
],
|
||||
[
|
||||
'username' => 'alex',
|
||||
'password' => 'whisky',
|
||||
'action' => 'approve',
|
||||
'redirect_uri' => 'http://bar',
|
||||
]
|
||||
);
|
||||
|
||||
$response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
|
||||
|
||||
$this->assertTrue($response instanceof RedirectResponse);
|
||||
|
||||
$response = $response->generateHttpResponse(new Response);
|
||||
$this->assertTrue(strstr($response->getHeader('location')[0], 'http://foo/bar') !== false);
|
||||
$grant->validateAuthorizationRequest($request);
|
||||
}
|
||||
|
||||
public function testRespondToAuthorizationRequestShowLoginForm()
|
||||
/**
|
||||
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
|
||||
* @expectedExceptionCode 4
|
||||
*/
|
||||
public function testValidateAuthorizationRequestBadRedirectUriArray()
|
||||
{
|
||||
$client = new ClientEntity();
|
||||
$client->setRedirectUri('http://foo/bar');
|
||||
$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);
|
||||
|
||||
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
|
||||
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
|
||||
|
||||
$grant = new AuthCodeGrant(
|
||||
$this->getMock(AuthCodeRepositoryInterface::class),
|
||||
$this->getMock(RefreshTokenRepositoryInterface::class),
|
||||
$userRepositoryMock,
|
||||
new \DateInterval('PT10M')
|
||||
);
|
||||
$grant->setClientRepository($clientRepositoryMock);
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
$grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
|
||||
$request = new ServerRequest(
|
||||
[
|
||||
'HTTP_HOST' => 'auth-server.tld',
|
||||
'REQUEST_URI' => '/authorize',
|
||||
],
|
||||
[],
|
||||
[],
|
||||
null,
|
||||
'POST',
|
||||
null,
|
||||
'php://input',
|
||||
[],
|
||||
[
|
||||
'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => null])),
|
||||
],
|
||||
[
|
||||
$headers = [],
|
||||
$cookies = [],
|
||||
$queryParams = [
|
||||
'response_type' => 'code',
|
||||
'client_id' => 'foo',
|
||||
],
|
||||
[
|
||||
'username' => 'alex',
|
||||
'password' => 'whisky',
|
||||
'action' => 'approve',
|
||||
'redirect_uri' => 'http://bar',
|
||||
]
|
||||
);
|
||||
|
||||
$response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
|
||||
|
||||
$this->assertTrue($response instanceof HtmlResponse);
|
||||
|
||||
$response = $response->generateHttpResponse(new Response);
|
||||
$this->assertTrue(strstr($response->getHeader('content-type')[0], 'text/html') !== false);
|
||||
$this->assertTrue(strstr((string) $response->getBody(), 'Incorrect username or password') !== false);
|
||||
$grant->validateAuthorizationRequest($request);
|
||||
}
|
||||
|
||||
public function testRespondToAuthorizationRequestShowAuthorizeForm()
|
||||
public function testCompleteAuthorizationRequest()
|
||||
{
|
||||
$client = new ClientEntity();
|
||||
$client->setRedirectUri('http://foo/bar');
|
||||
$client->setName('Test Client');
|
||||
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
|
||||
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
|
||||
$authRequest = new AuthorizationRequest();
|
||||
$authRequest->setAuthorizationApproved(true);
|
||||
$authRequest->setClient(new ClientEntity());
|
||||
$authRequest->setGrantTypeId('authorization_code');
|
||||
$authRequest->setUser(new UserEntity());
|
||||
|
||||
$userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
|
||||
$userEntity = new UserEntity();
|
||||
$userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity);
|
||||
|
||||
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
|
||||
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
|
||||
$authCodeRepository = $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock();
|
||||
$authCodeRepository->method('getNewAuthCode')->willReturn(new AuthCodeEntity());
|
||||
|
||||
$grant = new AuthCodeGrant(
|
||||
$this->getMock(AuthCodeRepositoryInterface::class),
|
||||
$authCodeRepository,
|
||||
$this->getMock(RefreshTokenRepositoryInterface::class),
|
||||
$userRepositoryMock,
|
||||
new \DateInterval('PT10M')
|
||||
);
|
||||
$grant->setClientRepository($clientRepositoryMock);
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
$grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
|
||||
$request = new ServerRequest(
|
||||
[
|
||||
'HTTP_HOST' => 'auth-server.tld',
|
||||
'REQUEST_URI' => '/authorize',
|
||||
],
|
||||
[],
|
||||
null,
|
||||
'POST',
|
||||
'php://input',
|
||||
[],
|
||||
[
|
||||
'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => 123])),
|
||||
],
|
||||
[
|
||||
'response_type' => 'code',
|
||||
'client_id' => 'foo',
|
||||
],
|
||||
[
|
||||
'username' => 'alex',
|
||||
'password' => 'whisky',
|
||||
]
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
|
||||
$this->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
|
||||
* @expectedExceptionCode 9
|
||||
*/
|
||||
public function testCompleteAuthorizationRequestDenied()
|
||||
{
|
||||
$authRequest = new AuthorizationRequest();
|
||||
$authRequest->setAuthorizationApproved(false);
|
||||
$authRequest->setClient(new ClientEntity());
|
||||
$authRequest->setGrantTypeId('authorization_code');
|
||||
$authRequest->setUser(new UserEntity());
|
||||
|
||||
$authCodeRepository = $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock();
|
||||
$authCodeRepository->method('getNewAuthCode')->willReturn(new AuthCodeEntity());
|
||||
|
||||
$grant = new AuthCodeGrant(
|
||||
$authCodeRepository,
|
||||
$this->getMock(RefreshTokenRepositoryInterface::class),
|
||||
new \DateInterval('PT10M')
|
||||
);
|
||||
|
||||
$response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
|
||||
$response = $response->generateHttpResponse(new Response);
|
||||
$this->assertTrue($response instanceof ResponseInterface);
|
||||
$this->assertTrue(strstr($response->getHeader('set-cookie')[0], 'oauth_authorize_request') !== false);
|
||||
$grant->completeAuthorizationRequest($authRequest);
|
||||
}
|
||||
|
||||
public function testRespondToAccessTokenRequest()
|
||||
@@ -583,32 +330,30 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
|
||||
$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);
|
||||
|
||||
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
|
||||
$scopeEntity = new ScopeEntity();
|
||||
$scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scopeEntity);
|
||||
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
|
||||
|
||||
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
|
||||
$accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity());
|
||||
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
|
||||
|
||||
$refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
|
||||
$refreshTokenRepositoryMock->method('persistNewRefreshToken')->willReturnSelf();
|
||||
$refreshTokenRepositoryMock->method('getNewRefreshToken')->willReturn(new RefreshTokenEntity());
|
||||
|
||||
$grant = new AuthCodeGrant(
|
||||
$this->getMock(AuthCodeRepositoryInterface::class),
|
||||
$this->getMock(RefreshTokenRepositoryInterface::class),
|
||||
$userRepositoryMock,
|
||||
new \DateInterval('PT10M')
|
||||
);
|
||||
$grant->setClientRepository($clientRepositoryMock);
|
||||
$grant->setScopeRepository($scopeRepositoryMock);
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
|
||||
$grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$request = new ServerRequest(
|
||||
[],
|
||||
@@ -639,7 +384,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
|
||||
);
|
||||
|
||||
/** @var StubResponseType $response */
|
||||
$response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
|
||||
$response = $grant->respondToAccessTokenRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
|
||||
|
||||
$this->assertTrue($response->getAccessToken() instanceof AccessTokenEntityInterface);
|
||||
$this->assertTrue($response->getRefreshToken() instanceof RefreshTokenEntityInterface);
|
||||
@@ -652,21 +397,19 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
|
||||
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->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$request = new ServerRequest(
|
||||
[],
|
||||
@@ -683,7 +426,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
|
||||
);
|
||||
|
||||
/* @var StubResponseType $response */
|
||||
$grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
|
||||
$grant->respondToAccessTokenRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -693,26 +436,23 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
|
||||
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->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$request = new ServerRequest(
|
||||
[],
|
||||
@@ -732,7 +472,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
|
||||
);
|
||||
|
||||
/* @var StubResponseType $response */
|
||||
$grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
|
||||
$grant->respondToAccessTokenRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
|
||||
}
|
||||
|
||||
public function testRespondToAccessTokenRequestExpiredCode()
|
||||
@@ -743,10 +483,6 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
|
||||
$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();
|
||||
|
||||
@@ -756,14 +492,13 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
|
||||
$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->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$request = new ServerRequest(
|
||||
[],
|
||||
@@ -795,7 +530,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
try {
|
||||
/* @var StubResponseType $response */
|
||||
$grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
|
||||
$grant->respondToAccessTokenRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
|
||||
} catch (OAuthServerException $e) {
|
||||
$this->assertEquals($e->getHint(), 'Authorization code has expired');
|
||||
}
|
||||
@@ -809,10 +544,6 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
|
||||
$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();
|
||||
|
||||
@@ -825,14 +556,13 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
|
||||
$grant = new AuthCodeGrant(
|
||||
$authCodeRepositoryMock,
|
||||
$this->getMock(RefreshTokenRepositoryInterface::class),
|
||||
$userRepositoryMock,
|
||||
new \DateInterval('PT10M')
|
||||
);
|
||||
$grant->setClientRepository($clientRepositoryMock);
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
|
||||
$grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$request = new ServerRequest(
|
||||
[],
|
||||
@@ -864,7 +594,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
try {
|
||||
/* @var StubResponseType $response */
|
||||
$grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
|
||||
$grant->respondToAccessTokenRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
|
||||
} catch (OAuthServerException $e) {
|
||||
$this->assertEquals($e->getHint(), 'Authorization code has been revoked');
|
||||
}
|
||||
@@ -878,10 +608,6 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
|
||||
$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();
|
||||
|
||||
@@ -891,14 +617,13 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
|
||||
$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->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$request = new ServerRequest(
|
||||
[],
|
||||
@@ -930,7 +655,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
try {
|
||||
/* @var StubResponseType $response */
|
||||
$grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
|
||||
$grant->respondToAccessTokenRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
|
||||
} catch (OAuthServerException $e) {
|
||||
$this->assertEquals($e->getHint(), 'Authorization code was not issued to this client');
|
||||
}
|
||||
@@ -944,10 +669,6 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
|
||||
$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();
|
||||
|
||||
@@ -957,14 +678,13 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
|
||||
$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->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$request = new ServerRequest(
|
||||
[],
|
||||
@@ -985,7 +705,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
try {
|
||||
/* @var StubResponseType $response */
|
||||
$grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
|
||||
$grant->respondToAccessTokenRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
|
||||
} catch (OAuthServerException $e) {
|
||||
$this->assertEquals($e->getHint(), 'Cannot decrypt the authorization code');
|
||||
}
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
|
||||
namespace LeagueTests\Grant;
|
||||
|
||||
use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
|
||||
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 LeagueTests\Stubs\AccessTokenEntity;
|
||||
use LeagueTests\Stubs\ClientEntity;
|
||||
use LeagueTests\Stubs\StubResponseType;
|
||||
use Zend\Diactoros\ServerRequest;
|
||||
@@ -22,11 +23,11 @@ class ClientCredentialsGrantTest extends \PHPUnit_Framework_TestCase
|
||||
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('getNewToken')->willReturn(new AccessTokenEntity());
|
||||
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
|
||||
|
||||
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
|
||||
@@ -46,7 +47,7 @@ class ClientCredentialsGrantTest extends \PHPUnit_Framework_TestCase
|
||||
);
|
||||
|
||||
$responseType = new StubResponseType();
|
||||
$grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
|
||||
$grant->respondToAccessTokenRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
|
||||
|
||||
$this->assertTrue($responseType->getAccessToken() instanceof AccessTokenEntityInterface);
|
||||
}
|
||||
|
||||
@@ -2,19 +2,17 @@
|
||||
|
||||
namespace LeagueTests\Grant;
|
||||
|
||||
use League\OAuth2\Server\Exception\OAuthServerException;
|
||||
use League\OAuth2\Server\CryptKey;
|
||||
use League\OAuth2\Server\Grant\ImplicitGrant;
|
||||
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
|
||||
use League\OAuth2\Server\Repositories\ClientRepositoryInterface;
|
||||
use League\OAuth2\Server\Repositories\ScopeRepositoryInterface;
|
||||
use League\OAuth2\Server\Repositories\UserRepositoryInterface;
|
||||
use League\OAuth2\Server\ResponseTypes\HtmlResponse;
|
||||
use League\OAuth2\Server\RequestTypes\AuthorizationRequest;
|
||||
use League\OAuth2\Server\ResponseTypes\RedirectResponse;
|
||||
use LeagueTests\Stubs\AccessTokenEntity;
|
||||
use LeagueTests\Stubs\ClientEntity;
|
||||
use LeagueTests\Stubs\CryptTraitStub;
|
||||
use LeagueTests\Stubs\StubResponseType;
|
||||
use LeagueTests\Stubs\UserEntity;
|
||||
use Zend\Diactoros\Response;
|
||||
use Zend\Diactoros\ServerRequest;
|
||||
|
||||
class ImplicitGrantTest extends \PHPUnit_Framework_TestCase
|
||||
@@ -31,14 +29,35 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function testGetIdentifier()
|
||||
{
|
||||
$grant = new ImplicitGrant($this->getMock(UserRepositoryInterface::class));
|
||||
|
||||
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
|
||||
$this->assertEquals('implicit', $grant->getIdentifier());
|
||||
}
|
||||
|
||||
public function testCanRespondToRequest()
|
||||
public function testCanRespondToAccessTokenRequest()
|
||||
{
|
||||
$grant = new ImplicitGrant($this->getMock(UserRepositoryInterface::class));
|
||||
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
|
||||
|
||||
$this->assertFalse(
|
||||
$grant->canRespondToAccessTokenRequest(new ServerRequest())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
*/
|
||||
public function testRespondToAccessTokenRequest()
|
||||
{
|
||||
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
|
||||
$grant->respondToAccessTokenRequest(
|
||||
new ServerRequest(),
|
||||
new StubResponseType(),
|
||||
new \DateInterval('PT10M')
|
||||
);
|
||||
}
|
||||
|
||||
public function testCanRespondToAuthorizationRequest()
|
||||
{
|
||||
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
|
||||
|
||||
$request = new ServerRequest(
|
||||
[],
|
||||
@@ -46,389 +65,234 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase
|
||||
null,
|
||||
null,
|
||||
'php://input',
|
||||
[],
|
||||
[],
|
||||
[
|
||||
$headers = [],
|
||||
$cookies = [],
|
||||
$queryParams = [
|
||||
'response_type' => 'token',
|
||||
'client_id' => 'foo',
|
||||
]
|
||||
);
|
||||
|
||||
$this->assertTrue($grant->canRespondToRequest($request));
|
||||
$this->assertTrue($grant->canRespondToAuthorizationRequest($request));
|
||||
}
|
||||
|
||||
public function testRespondToAuthorizationRequest()
|
||||
public function testValidateAuthorizationRequest()
|
||||
{
|
||||
$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);
|
||||
|
||||
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
|
||||
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
|
||||
|
||||
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
|
||||
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
|
||||
|
||||
$grant = new ImplicitGrant($userRepositoryMock);
|
||||
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
|
||||
$grant->setClientRepository($clientRepositoryMock);
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
$grant->setScopeRepository($scopeRepositoryMock);
|
||||
$grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
|
||||
$request = new ServerRequest(
|
||||
[
|
||||
'HTTP_HOST' => 'auth-server.tld',
|
||||
'REQUEST_URI' => '/authorize',
|
||||
],
|
||||
[],
|
||||
[],
|
||||
null,
|
||||
'POST',
|
||||
null,
|
||||
'php://input',
|
||||
[],
|
||||
[],
|
||||
[
|
||||
'response_type' => 'token',
|
||||
$headers = [],
|
||||
$cookies = [],
|
||||
$queryParams = [
|
||||
'response_type' => 'code',
|
||||
'client_id' => 'foo',
|
||||
'state' => 'foobar',
|
||||
],
|
||||
[
|
||||
'username' => 'alex',
|
||||
'password' => 'whisky',
|
||||
'action' => 'approve',
|
||||
'redirect_uri' => 'http://foo/bar',
|
||||
]
|
||||
);
|
||||
|
||||
$response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
|
||||
$this->assertTrue($grant->validateAuthorizationRequest($request) instanceof AuthorizationRequest);
|
||||
}
|
||||
|
||||
$this->assertTrue($response instanceof RedirectResponse);
|
||||
public function testValidateAuthorizationRequestRedirectUriArray()
|
||||
{
|
||||
$client = new ClientEntity();
|
||||
$client->setRedirectUri(['http://foo/bar']);
|
||||
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
|
||||
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
|
||||
|
||||
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
|
||||
$grant->setClientRepository($clientRepositoryMock);
|
||||
|
||||
$request = new ServerRequest(
|
||||
[],
|
||||
[],
|
||||
null,
|
||||
null,
|
||||
'php://input',
|
||||
$headers = [],
|
||||
$cookies = [],
|
||||
$queryParams = [
|
||||
'response_type' => 'code',
|
||||
'client_id' => 'foo',
|
||||
'redirect_uri' => 'http://foo/bar',
|
||||
]
|
||||
);
|
||||
|
||||
$this->assertTrue($grant->validateAuthorizationRequest($request) instanceof AuthorizationRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
|
||||
* @expectedExceptionCode 3
|
||||
*/
|
||||
public function testRespondToAuthorizationRequestMissingClientId()
|
||||
public function testValidateAuthorizationRequestMissingClientId()
|
||||
{
|
||||
$grant = new ImplicitGrant($this->getMock(UserRepositoryInterface::class));
|
||||
$grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
|
||||
$request = new ServerRequest(
|
||||
[
|
||||
'HTTP_HOST' => 'auth-server.tld',
|
||||
'REQUEST_URI' => '/authorize',
|
||||
],
|
||||
[],
|
||||
null,
|
||||
'POST',
|
||||
'php://input',
|
||||
[],
|
||||
[
|
||||
'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => 123])),
|
||||
],
|
||||
[
|
||||
'response_type' => 'token',
|
||||
],
|
||||
[
|
||||
'username' => 'alex',
|
||||
'password' => 'whisky',
|
||||
'action' => 'approve',
|
||||
]
|
||||
);
|
||||
|
||||
$grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
|
||||
}
|
||||
|
||||
public function testRespondToAuthorizationRequestBadClient()
|
||||
{
|
||||
$client = null;
|
||||
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
|
||||
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
|
||||
|
||||
$grant = new ImplicitGrant($this->getMock(UserRepositoryInterface::class));
|
||||
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
|
||||
$grant->setClientRepository($clientRepositoryMock);
|
||||
$grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
|
||||
$request = new ServerRequest(
|
||||
[
|
||||
'HTTP_HOST' => 'auth-server.tld',
|
||||
'REQUEST_URI' => '/authorize',
|
||||
],
|
||||
[],
|
||||
[],
|
||||
null,
|
||||
'POST',
|
||||
null,
|
||||
'php://input',
|
||||
[],
|
||||
[
|
||||
'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => 123])),
|
||||
],
|
||||
[
|
||||
'response_type' => 'token',
|
||||
'client_id' => 'foo',
|
||||
],
|
||||
[
|
||||
'username' => 'alex',
|
||||
'password' => 'whisky',
|
||||
'action' => 'approve',
|
||||
$headers = [],
|
||||
$cookies = [],
|
||||
$queryParams = [
|
||||
'response_type' => 'code',
|
||||
]
|
||||
);
|
||||
|
||||
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 ImplicitGrant($this->getMock(UserRepositoryInterface::class));
|
||||
$grant->setClientRepository($clientRepositoryMock);
|
||||
$grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
|
||||
$request = new ServerRequest(
|
||||
[
|
||||
'HTTP_HOST' => 'auth-server.tld',
|
||||
'REQUEST_URI' => '/authorize',
|
||||
],
|
||||
[],
|
||||
null,
|
||||
'POST',
|
||||
'php://input',
|
||||
[],
|
||||
[
|
||||
'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => 123])),
|
||||
],
|
||||
[
|
||||
'response_type' => 'token',
|
||||
'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');
|
||||
}
|
||||
$grant->validateAuthorizationRequest($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
|
||||
* @expectedExceptionCode 7
|
||||
* @expectedExceptionCode 4
|
||||
*/
|
||||
public function testRespondToAuthorizationRequestBadCookie()
|
||||
public function testValidateAuthorizationRequestInvalidClientId()
|
||||
{
|
||||
$client = new ClientEntity();
|
||||
$client->setRedirectUri('http://foo/bar');
|
||||
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
|
||||
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
|
||||
$clientRepositoryMock->method('getClientEntity')->willReturn(null);
|
||||
|
||||
$userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
|
||||
$userEntity = new UserEntity();
|
||||
$userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity);
|
||||
|
||||
$grant = new ImplicitGrant($this->getMock(UserRepositoryInterface::class));
|
||||
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
|
||||
$grant->setClientRepository($clientRepositoryMock);
|
||||
$grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
|
||||
$request = new ServerRequest(
|
||||
[
|
||||
'HTTP_HOST' => 'auth-server.tld',
|
||||
'REQUEST_URI' => '/authorize',
|
||||
],
|
||||
[],
|
||||
[],
|
||||
null,
|
||||
'POST',
|
||||
'php://input',
|
||||
[],
|
||||
[
|
||||
'oauth_authorize_request' => 'blah',
|
||||
],
|
||||
[
|
||||
'response_type' => 'token',
|
||||
'client_id' => 'foo',
|
||||
],
|
||||
[
|
||||
'username' => 'alex',
|
||||
'password' => 'whisky',
|
||||
'action' => 'approve',
|
||||
]
|
||||
);
|
||||
|
||||
$grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
|
||||
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
|
||||
|
||||
$grant = new ImplicitGrant($this->getMock(UserRepositoryInterface::class));
|
||||
$grant->setClientRepository($clientRepositoryMock);
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
$grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
|
||||
$request = new ServerRequest(
|
||||
[
|
||||
'HTTP_HOST' => 'auth-server.tld',
|
||||
'REQUEST_URI' => '/authorize',
|
||||
],
|
||||
[],
|
||||
null,
|
||||
'POST',
|
||||
'php://input',
|
||||
[],
|
||||
[
|
||||
'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => null])),
|
||||
],
|
||||
[
|
||||
'response_type' => 'token',
|
||||
'client_id' => 'foo',
|
||||
],
|
||||
[
|
||||
'username' => 'alex',
|
||||
'password' => 'whisky',
|
||||
'action' => 'approve',
|
||||
]
|
||||
);
|
||||
|
||||
$response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
|
||||
$this->assertTrue($response instanceof HtmlResponse);
|
||||
|
||||
$response = $response->generateHttpResponse(new Response);
|
||||
$this->assertTrue(strstr((string) $response->getBody(), '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);
|
||||
|
||||
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
|
||||
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
|
||||
|
||||
$grant = new ImplicitGrant($this->getMock(UserRepositoryInterface::class));
|
||||
$grant->setClientRepository($clientRepositoryMock);
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
$grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
|
||||
$request = new ServerRequest(
|
||||
[
|
||||
'HTTP_HOST' => 'auth-server.tld',
|
||||
'REQUEST_URI' => '/authorize',
|
||||
],
|
||||
[],
|
||||
null,
|
||||
'POST',
|
||||
'php://input',
|
||||
[],
|
||||
[
|
||||
'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => 123])),
|
||||
],
|
||||
[
|
||||
$headers = [],
|
||||
$cookies = [],
|
||||
$queryParams = [
|
||||
'response_type' => 'code',
|
||||
'client_id' => 'foo',
|
||||
],
|
||||
[
|
||||
'username' => 'alex',
|
||||
'password' => 'whisky',
|
||||
]
|
||||
);
|
||||
|
||||
$response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
|
||||
$grant->validateAuthorizationRequest($request);
|
||||
}
|
||||
|
||||
$this->assertTrue($response instanceof HtmlResponse);
|
||||
/**
|
||||
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
|
||||
* @expectedExceptionCode 4
|
||||
*/
|
||||
public function testValidateAuthorizationRequestBadRedirectUriString()
|
||||
{
|
||||
$client = new ClientEntity();
|
||||
$client->setRedirectUri('http://foo/bar');
|
||||
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
|
||||
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
|
||||
|
||||
$response = $response->generateHttpResponse(new Response);
|
||||
$this->assertTrue(strstr($response->getHeader('set-cookie')[0], 'oauth_authorize_request') !== false);
|
||||
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
|
||||
$grant->setClientRepository($clientRepositoryMock);
|
||||
|
||||
$request = new ServerRequest(
|
||||
[],
|
||||
[],
|
||||
null,
|
||||
null,
|
||||
'php://input',
|
||||
$headers = [],
|
||||
$cookies = [],
|
||||
$queryParams = [
|
||||
'response_type' => 'code',
|
||||
'client_id' => 'foo',
|
||||
'redirect_uri' => 'http://bar',
|
||||
]
|
||||
);
|
||||
|
||||
$grant->validateAuthorizationRequest($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
|
||||
* @expectedExceptionCode 4
|
||||
*/
|
||||
public function testValidateAuthorizationRequestBadRedirectUriArray()
|
||||
{
|
||||
$client = new ClientEntity();
|
||||
$client->setRedirectUri(['http://foo/bar']);
|
||||
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
|
||||
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
|
||||
|
||||
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
|
||||
$grant->setClientRepository($clientRepositoryMock);
|
||||
|
||||
$request = new ServerRequest(
|
||||
[],
|
||||
[],
|
||||
null,
|
||||
null,
|
||||
'php://input',
|
||||
$headers = [],
|
||||
$cookies = [],
|
||||
$queryParams = [
|
||||
'response_type' => 'code',
|
||||
'client_id' => 'foo',
|
||||
'redirect_uri' => 'http://bar',
|
||||
]
|
||||
);
|
||||
|
||||
$grant->validateAuthorizationRequest($request);
|
||||
}
|
||||
|
||||
public function testCompleteAuthorizationRequest()
|
||||
{
|
||||
$authRequest = new AuthorizationRequest();
|
||||
$authRequest->setAuthorizationApproved(true);
|
||||
$authRequest->setClient(new ClientEntity());
|
||||
$authRequest->setGrantTypeId('authorization_code');
|
||||
$authRequest->setUser(new UserEntity());
|
||||
|
||||
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
|
||||
$accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity());
|
||||
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
|
||||
|
||||
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
|
||||
$this->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
|
||||
* @expectedExceptionCode 9
|
||||
*/
|
||||
public function testRespondToAuthorizationRequestUserDenied()
|
||||
public function testCompleteAuthorizationRequestDenied()
|
||||
{
|
||||
$client = new ClientEntity();
|
||||
$client->setRedirectUri('http://foo/bar');
|
||||
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
|
||||
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
|
||||
$authRequest = new AuthorizationRequest();
|
||||
$authRequest->setAuthorizationApproved(false);
|
||||
$authRequest->setClient(new ClientEntity());
|
||||
$authRequest->setGrantTypeId('authorization_code');
|
||||
$authRequest->setUser(new UserEntity());
|
||||
|
||||
$userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
|
||||
$userEntity = new UserEntity();
|
||||
$userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity);
|
||||
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
|
||||
$accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity());
|
||||
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
|
||||
|
||||
$grant = new ImplicitGrant($this->getMock(UserRepositoryInterface::class));
|
||||
$grant->setClientRepository($clientRepositoryMock);
|
||||
$grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
|
||||
$request = new ServerRequest(
|
||||
[
|
||||
'HTTP_HOST' => 'auth-server.tld',
|
||||
'REQUEST_URI' => '/authorize',
|
||||
],
|
||||
[],
|
||||
null,
|
||||
'POST',
|
||||
'php://input',
|
||||
[],
|
||||
[
|
||||
'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => 123])),
|
||||
],
|
||||
[
|
||||
'response_type' => 'code',
|
||||
'client_id' => 'foo',
|
||||
'state' => 'foobar',
|
||||
],
|
||||
[
|
||||
'username' => 'alex',
|
||||
'password' => 'whisky',
|
||||
'action' => 'denied',
|
||||
]
|
||||
);
|
||||
|
||||
$grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M'));
|
||||
$grant->completeAuthorizationRequest($authRequest);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,15 +2,17 @@
|
||||
|
||||
namespace LeagueTests\Grant;
|
||||
|
||||
use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\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\ScopeRepositoryInterface;
|
||||
use League\OAuth2\Server\Repositories\UserRepositoryInterface;
|
||||
use LeagueTests\Stubs\AccessTokenEntity;
|
||||
use LeagueTests\Stubs\ClientEntity;
|
||||
use LeagueTests\Stubs\RefreshTokenEntity;
|
||||
use LeagueTests\Stubs\StubResponseType;
|
||||
use LeagueTests\Stubs\UserEntity;
|
||||
use Zend\Diactoros\ServerRequest;
|
||||
@@ -29,11 +31,11 @@ class PasswordGrantTest extends \PHPUnit_Framework_TestCase
|
||||
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('getNewToken')->willReturn(new AccessTokenEntity());
|
||||
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
|
||||
|
||||
$userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
|
||||
@@ -42,6 +44,7 @@ class PasswordGrantTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
|
||||
$refreshTokenRepositoryMock->method('persistNewRefreshToken')->willReturnSelf();
|
||||
$refreshTokenRepositoryMock->method('getNewRefreshToken')->willReturn(new RefreshTokenEntity());
|
||||
|
||||
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
|
||||
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
|
||||
@@ -62,7 +65,7 @@ class PasswordGrantTest extends \PHPUnit_Framework_TestCase
|
||||
);
|
||||
|
||||
$responseType = new StubResponseType();
|
||||
$grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
|
||||
$grant->respondToAccessTokenRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
|
||||
|
||||
$this->assertTrue($responseType->getAccessToken() instanceof AccessTokenEntityInterface);
|
||||
$this->assertTrue($responseType->getRefreshToken() instanceof RefreshTokenEntityInterface);
|
||||
@@ -74,7 +77,6 @@ class PasswordGrantTest extends \PHPUnit_Framework_TestCase
|
||||
public function testRespondToRequestMissingUsername()
|
||||
{
|
||||
$client = new ClientEntity();
|
||||
$client->setSecret('bar');
|
||||
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
|
||||
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
|
||||
|
||||
@@ -97,7 +99,7 @@ class PasswordGrantTest extends \PHPUnit_Framework_TestCase
|
||||
);
|
||||
|
||||
$responseType = new StubResponseType();
|
||||
$grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
|
||||
$grant->respondToAccessTokenRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,7 +108,6 @@ class PasswordGrantTest extends \PHPUnit_Framework_TestCase
|
||||
public function testRespondToRequestMissingPassword()
|
||||
{
|
||||
$client = new ClientEntity();
|
||||
$client->setSecret('bar');
|
||||
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
|
||||
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
|
||||
|
||||
@@ -130,7 +131,7 @@ class PasswordGrantTest extends \PHPUnit_Framework_TestCase
|
||||
);
|
||||
|
||||
$responseType = new StubResponseType();
|
||||
$grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
|
||||
$grant->respondToAccessTokenRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,7 +140,6 @@ class PasswordGrantTest extends \PHPUnit_Framework_TestCase
|
||||
public function testRespondToRequestBadCredentials()
|
||||
{
|
||||
$client = new ClientEntity();
|
||||
$client->setSecret('bar');
|
||||
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
|
||||
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
|
||||
|
||||
@@ -165,6 +165,6 @@ class PasswordGrantTest extends \PHPUnit_Framework_TestCase
|
||||
);
|
||||
|
||||
$responseType = new StubResponseType();
|
||||
$grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
|
||||
$grant->respondToAccessTokenRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,15 +2,18 @@
|
||||
|
||||
namespace LeagueTests\Grant;
|
||||
|
||||
use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface;
|
||||
use League\OAuth2\Server\CryptKey;
|
||||
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\RefreshTokenEntityInterface;
|
||||
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 LeagueTests\Stubs\AccessTokenEntity;
|
||||
use LeagueTests\Stubs\ClientEntity;
|
||||
use LeagueTests\Stubs\CryptTraitStub;
|
||||
use LeagueTests\Stubs\RefreshTokenEntity;
|
||||
use LeagueTests\Stubs\ScopeEntity;
|
||||
use LeagueTests\Stubs\StubResponseType;
|
||||
use Zend\Diactoros\ServerRequest;
|
||||
@@ -39,7 +42,6 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
$client = new ClientEntity();
|
||||
$client->setIdentifier('foo');
|
||||
$client->setSecret('bar');
|
||||
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
|
||||
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
|
||||
|
||||
@@ -48,11 +50,13 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
|
||||
$scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scopeEntity);
|
||||
|
||||
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
|
||||
$accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity());
|
||||
$accessTokenRepositoryMock
|
||||
->expects($this->once())
|
||||
->method('persistNewAccessToken')->willReturnSelf();
|
||||
|
||||
$refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
|
||||
$refreshTokenRepositoryMock->method('getNewRefreshToken')->willReturn(new RefreshTokenEntity());
|
||||
$refreshTokenRepositoryMock
|
||||
->expects($this->once())
|
||||
->method('persistNewRefreshToken')->willReturnSelf();
|
||||
@@ -61,8 +65,8 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
|
||||
$grant->setClientRepository($clientRepositoryMock);
|
||||
$grant->setScopeRepository($scopeRepositoryMock);
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
$grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$oldRefreshToken = $this->cryptStub->doEncrypt(
|
||||
json_encode(
|
||||
@@ -87,7 +91,7 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
|
||||
);
|
||||
|
||||
$responseType = new StubResponseType();
|
||||
$grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
|
||||
$grant->respondToAccessTokenRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
|
||||
|
||||
$this->assertTrue($responseType->getAccessToken() instanceof AccessTokenEntityInterface);
|
||||
$this->assertTrue($responseType->getRefreshToken() instanceof RefreshTokenEntityInterface);
|
||||
@@ -97,15 +101,16 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
$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('getNewToken')->willReturn(new AccessTokenEntity());
|
||||
$accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
|
||||
|
||||
$refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
|
||||
$refreshTokenRepositoryMock->method('persistNewRefreshToken')->willReturnSelf();
|
||||
$refreshTokenRepositoryMock->method('getNewRefreshToken')->willReturn(new RefreshTokenEntity());
|
||||
|
||||
$scope = new ScopeEntity();
|
||||
$scope->setIdentifier('foo');
|
||||
@@ -116,8 +121,8 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
|
||||
$grant->setClientRepository($clientRepositoryMock);
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
$grant->setScopeRepository($scopeRepositoryMock);
|
||||
$grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$oldRefreshToken = $this->cryptStub->doEncrypt(
|
||||
json_encode(
|
||||
@@ -143,7 +148,7 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
|
||||
);
|
||||
|
||||
$responseType = new StubResponseType();
|
||||
$grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
|
||||
$grant->respondToAccessTokenRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
|
||||
|
||||
$this->assertTrue($responseType->getAccessToken() instanceof AccessTokenEntityInterface);
|
||||
$this->assertTrue($responseType->getRefreshToken() instanceof RefreshTokenEntityInterface);
|
||||
@@ -157,7 +162,6 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
$client = new ClientEntity();
|
||||
$client->setIdentifier('foo');
|
||||
$client->setSecret('bar');
|
||||
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
|
||||
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
|
||||
|
||||
@@ -176,8 +180,8 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
|
||||
$grant->setClientRepository($clientRepositoryMock);
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
$grant->setScopeRepository($scopeRepositoryMock);
|
||||
$grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$oldRefreshToken = $this->cryptStub->doEncrypt(
|
||||
json_encode(
|
||||
@@ -203,7 +207,7 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
|
||||
);
|
||||
|
||||
$responseType = new StubResponseType();
|
||||
$grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
|
||||
$grant->respondToAccessTokenRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -214,7 +218,6 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
$client = new ClientEntity();
|
||||
$client->setIdentifier('foo');
|
||||
$client->setSecret('bar');
|
||||
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
|
||||
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
|
||||
|
||||
@@ -224,8 +227,8 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
|
||||
$grant = new RefreshTokenGrant($refreshTokenRepositoryMock);
|
||||
$grant->setClientRepository($clientRepositoryMock);
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
$grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$serverRequest = new ServerRequest();
|
||||
$serverRequest = $serverRequest->withParsedBody(
|
||||
@@ -236,7 +239,7 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
|
||||
);
|
||||
|
||||
$responseType = new StubResponseType();
|
||||
$grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
|
||||
$grant->respondToAccessTokenRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -247,7 +250,6 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
$client = new ClientEntity();
|
||||
$client->setIdentifier('foo');
|
||||
$client->setSecret('bar');
|
||||
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
|
||||
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
|
||||
|
||||
@@ -257,8 +259,8 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
|
||||
$grant = new RefreshTokenGrant($refreshTokenRepositoryMock);
|
||||
$grant->setClientRepository($clientRepositoryMock);
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
$grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$oldRefreshToken = 'foobar';
|
||||
|
||||
@@ -272,7 +274,7 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
|
||||
);
|
||||
|
||||
$responseType = new StubResponseType();
|
||||
$grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
|
||||
$grant->respondToAccessTokenRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -283,7 +285,6 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
$client = new ClientEntity();
|
||||
$client->setIdentifier('foo');
|
||||
$client->setSecret('bar');
|
||||
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
|
||||
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
|
||||
|
||||
@@ -297,8 +298,8 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
|
||||
$grant = new RefreshTokenGrant($refreshTokenRepositoryMock);
|
||||
$grant->setClientRepository($clientRepositoryMock);
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
$grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$oldRefreshToken = $this->cryptStub->doEncrypt(
|
||||
json_encode(
|
||||
@@ -323,7 +324,7 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
|
||||
);
|
||||
|
||||
$responseType = new StubResponseType();
|
||||
$grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
|
||||
$grant->respondToAccessTokenRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -334,7 +335,6 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
$client = new ClientEntity();
|
||||
$client->setIdentifier('foo');
|
||||
$client->setSecret('bar');
|
||||
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
|
||||
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
|
||||
|
||||
@@ -344,8 +344,8 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
|
||||
$grant = new RefreshTokenGrant($refreshTokenRepositoryMock);
|
||||
$grant->setClientRepository($clientRepositoryMock);
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
$grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$oldRefreshToken = $this->cryptStub->doEncrypt(
|
||||
json_encode(
|
||||
@@ -370,7 +370,7 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
|
||||
);
|
||||
|
||||
$responseType = new StubResponseType();
|
||||
$grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
|
||||
$grant->respondToAccessTokenRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -381,7 +381,6 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
$client = new ClientEntity();
|
||||
$client->setIdentifier('foo');
|
||||
$client->setSecret('bar');
|
||||
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
|
||||
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
|
||||
|
||||
@@ -392,8 +391,8 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
|
||||
$grant = new RefreshTokenGrant($refreshTokenRepositoryMock);
|
||||
$grant->setClientRepository($clientRepositoryMock);
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
$grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$oldRefreshToken = $this->cryptStub->doEncrypt(
|
||||
json_encode(
|
||||
@@ -418,6 +417,6 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
|
||||
);
|
||||
|
||||
$responseType = new StubResponseType();
|
||||
$grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
|
||||
$grant->respondToAccessTokenRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,14 @@
|
||||
|
||||
namespace LeagueTests\Middleware;
|
||||
|
||||
use League\OAuth2\Server\Exception\OAuthServerException;
|
||||
use League\OAuth2\Server\Grant\ClientCredentialsGrant;
|
||||
use League\OAuth2\Server\Middleware\AuthenticationServerMiddleware;
|
||||
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\AccessTokenEntity;
|
||||
use LeagueTests\Stubs\ClientEntity;
|
||||
use LeagueTests\Stubs\StubResponseType;
|
||||
use Zend\Diactoros\Response;
|
||||
@@ -23,16 +25,19 @@ class AuthenticationServerMiddlewareTest extends \PHPUnit_Framework_TestCase
|
||||
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
|
||||
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
|
||||
|
||||
$accessRepositoryMock = $this->getMock(AccessTokenRepositoryInterface::class);
|
||||
$accessRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity());
|
||||
|
||||
$server = new Server(
|
||||
$clientRepository,
|
||||
$this->getMock(AccessTokenRepositoryInterface::class),
|
||||
$accessRepositoryMock,
|
||||
$scopeRepositoryMock,
|
||||
'',
|
||||
'',
|
||||
'file://' . __DIR__ . '/../Stubs/private.key',
|
||||
'file://' . __DIR__ . '/../Stubs/public.key',
|
||||
new StubResponseType()
|
||||
);
|
||||
|
||||
$server->enableGrantType(new ClientCredentialsGrant(), new \DateInterval('PT1M'));
|
||||
$server->enableGrantType(new ClientCredentialsGrant());
|
||||
|
||||
$_POST['grant_type'] = 'client_credentials';
|
||||
$_POST['client_id'] = 'foo';
|
||||
@@ -60,8 +65,8 @@ class AuthenticationServerMiddlewareTest extends \PHPUnit_Framework_TestCase
|
||||
$clientRepository,
|
||||
$this->getMock(AccessTokenRepositoryInterface::class),
|
||||
$this->getMock(ScopeRepositoryInterface::class),
|
||||
'',
|
||||
'',
|
||||
'file://' . __DIR__ . '/../Stubs/private.key',
|
||||
'file://' . __DIR__ . '/../Stubs/public.key',
|
||||
new StubResponseType()
|
||||
);
|
||||
|
||||
@@ -85,4 +90,22 @@ class AuthenticationServerMiddlewareTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$this->assertEquals(401, $response->getStatusCode());
|
||||
}
|
||||
|
||||
public function testOAuthErrorResponseRedirectUri()
|
||||
{
|
||||
$exception = OAuthServerException::invalidScope('test', 'http://foo/bar');
|
||||
$response = $exception->generateHttpResponse(new Response());
|
||||
|
||||
$this->assertEquals(302, $response->getStatusCode());
|
||||
$this->assertEquals('http://foo/bar?error=invalid_scope&message=The+requested+scope+is+invalid%2C+unknown%2C+or+malformed&hint=Check+the+%60test%60+scope', $response->getHeader('location')[0]);
|
||||
}
|
||||
|
||||
public function testOAuthErrorResponseRedirectUriFragment()
|
||||
{
|
||||
$exception = OAuthServerException::invalidScope('test', 'http://foo/bar');
|
||||
$response = $exception->generateHttpResponse(new Response(), true);
|
||||
|
||||
$this->assertEquals(302, $response->getStatusCode());
|
||||
$this->assertEquals('http://foo/bar#error=invalid_scope&message=The+requested+scope+is+invalid%2C+unknown%2C+or+malformed&hint=Check+the+%60test%60+scope', $response->getHeader('location')[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
|
||||
namespace LeagueTests\Middleware;
|
||||
|
||||
use League\OAuth2\Server\Entities\AccessTokenEntity;
|
||||
use League\OAuth2\Server\CryptKey;
|
||||
use League\OAuth2\Server\Middleware\ResourceServerMiddleware;
|
||||
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\AccessTokenEntity;
|
||||
use LeagueTests\Stubs\ClientEntity;
|
||||
use LeagueTests\Stubs\StubResponseType;
|
||||
use Zend\Diactoros\Response;
|
||||
@@ -37,7 +38,7 @@ class ResourceServerMiddlewareTest extends \PHPUnit_Framework_TestCase
|
||||
$accessToken->setExpiryDateTime((new \DateTime())->add(new \DateInterval('PT1H')));
|
||||
$accessToken->setClient($client);
|
||||
|
||||
$token = $accessToken->convertToJWT('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
$token = $accessToken->convertToJWT(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$request = new ServerRequest();
|
||||
$request = $request->withHeader('authorization', sprintf('Bearer %s', $token));
|
||||
@@ -56,6 +57,47 @@ class ResourceServerMiddlewareTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
}
|
||||
|
||||
public function testValidResponseExpiredToken()
|
||||
{
|
||||
$clientRepository = $this->getMock(ClientRepositoryInterface::class);
|
||||
|
||||
$server = new Server(
|
||||
$clientRepository,
|
||||
$this->getMock(AccessTokenRepositoryInterface::class),
|
||||
$this->getMock(ScopeRepositoryInterface::class),
|
||||
'file://' . __DIR__ . '/../Stubs/private.key',
|
||||
'file://' . __DIR__ . '/../Stubs/public.key',
|
||||
new StubResponseType()
|
||||
);
|
||||
|
||||
$client = new ClientEntity();
|
||||
$client->setIdentifier('clientName');
|
||||
|
||||
$accessToken = new AccessTokenEntity();
|
||||
$accessToken->setIdentifier('test');
|
||||
$accessToken->setUserIdentifier(123);
|
||||
$accessToken->setExpiryDateTime((new \DateTime())->sub(new \DateInterval('PT1H')));
|
||||
$accessToken->setClient($client);
|
||||
|
||||
$token = $accessToken->convertToJWT(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$request = new ServerRequest();
|
||||
$request = $request->withHeader('authorization', sprintf('Bearer %s', $token));
|
||||
|
||||
$middleware = new ResourceServerMiddleware($server);
|
||||
$response = $middleware->__invoke(
|
||||
$request,
|
||||
new Response(),
|
||||
function () {
|
||||
$this->assertEquals('test', func_get_args()[0]->getAttribute('oauth_access_token_id'));
|
||||
|
||||
return func_get_args()[1];
|
||||
}
|
||||
);
|
||||
|
||||
$this->assertEquals(401, $response->getStatusCode());
|
||||
}
|
||||
|
||||
public function testErrorResponse()
|
||||
{
|
||||
$clientRepository = $this->getMock(ClientRepositoryInterface::class);
|
||||
@@ -64,8 +106,8 @@ class ResourceServerMiddlewareTest extends \PHPUnit_Framework_TestCase
|
||||
$clientRepository,
|
||||
$this->getMock(AccessTokenRepositoryInterface::class),
|
||||
$this->getMock(ScopeRepositoryInterface::class),
|
||||
'',
|
||||
'',
|
||||
'file://' . __DIR__ . '/../Stubs/private.key',
|
||||
'file://' . __DIR__ . '/../Stubs/public.key',
|
||||
new StubResponseType()
|
||||
);
|
||||
|
||||
|
||||
@@ -3,12 +3,13 @@
|
||||
namespace LeagueTests\ResponseTypes;
|
||||
|
||||
use League\OAuth2\Server\AuthorizationValidators\BearerTokenValidator;
|
||||
use League\OAuth2\Server\Entities\AccessTokenEntity;
|
||||
use League\OAuth2\Server\Entities\RefreshTokenEntity;
|
||||
use League\OAuth2\Server\CryptKey;
|
||||
use League\OAuth2\Server\Exception\OAuthServerException;
|
||||
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
|
||||
use League\OAuth2\Server\ResponseTypes\BearerTokenResponse;
|
||||
use LeagueTests\Stubs\AccessTokenEntity;
|
||||
use LeagueTests\Stubs\ClientEntity;
|
||||
use LeagueTests\Stubs\RefreshTokenEntity;
|
||||
use LeagueTests\Stubs\ScopeEntity;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Zend\Diactoros\Response;
|
||||
@@ -21,8 +22,8 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase
|
||||
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
|
||||
|
||||
$responseType = new BearerTokenResponse($accessTokenRepositoryMock);
|
||||
$responseType->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
$responseType->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
$responseType->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
|
||||
$client = new ClientEntity();
|
||||
$client->setIdentifier('clientName');
|
||||
@@ -66,8 +67,8 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase
|
||||
$accessTokenRepositoryMock->method('isAccessTokenRevoked')->willReturn(false);
|
||||
|
||||
$responseType = new BearerTokenResponse($accessTokenRepositoryMock);
|
||||
$responseType->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
$responseType->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
$responseType->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
|
||||
$client = new ClientEntity();
|
||||
$client->setIdentifier('clientName');
|
||||
@@ -89,9 +90,12 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase
|
||||
$response = $responseType->generateHttpResponse(new Response());
|
||||
$json = json_decode((string) $response->getBody());
|
||||
|
||||
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
|
||||
$accessTokenRepositoryMock->method('isAccessTokenRevoked')->willReturn(false);
|
||||
|
||||
$authorizationValidator = new BearerTokenValidator($accessTokenRepositoryMock);
|
||||
$authorizationValidator->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
$authorizationValidator->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$authorizationValidator->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
$authorizationValidator->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
|
||||
$request = new ServerRequest();
|
||||
$request = $request->withHeader('authorization', sprintf('Bearer %s', $json->access_token));
|
||||
@@ -110,8 +114,8 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase
|
||||
$accessTokenRepositoryMock->method('isAccessTokenRevoked')->willReturn(false);
|
||||
|
||||
$responseType = new BearerTokenResponse($accessTokenRepositoryMock);
|
||||
$responseType->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
$responseType->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
$responseType->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
|
||||
$client = new ClientEntity();
|
||||
$client->setIdentifier('clientName');
|
||||
@@ -134,8 +138,8 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase
|
||||
$json = json_decode((string) $response->getBody());
|
||||
|
||||
$authorizationValidator = new BearerTokenValidator($accessTokenRepositoryMock);
|
||||
$authorizationValidator->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
$authorizationValidator->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$authorizationValidator->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
$authorizationValidator->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
|
||||
$request = new ServerRequest();
|
||||
$request = $request->withHeader('authorization', sprintf('Bearer %s', $json->access_token . 'foo'));
|
||||
@@ -152,12 +156,9 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function testDetermineAccessTokenInHeaderRevokedToken()
|
||||
{
|
||||
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
|
||||
$accessTokenRepositoryMock->method('isAccessTokenRevoked')->willReturn(true);
|
||||
|
||||
$responseType = new BearerTokenResponse($accessTokenRepositoryMock);
|
||||
$responseType->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
$responseType->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$responseType = new BearerTokenResponse();
|
||||
$responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
$responseType->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
|
||||
$client = new ClientEntity();
|
||||
$client->setIdentifier('clientName');
|
||||
@@ -179,9 +180,12 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase
|
||||
$response = $responseType->generateHttpResponse(new Response());
|
||||
$json = json_decode((string) $response->getBody());
|
||||
|
||||
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
|
||||
$accessTokenRepositoryMock->method('isAccessTokenRevoked')->willReturn(true);
|
||||
|
||||
$authorizationValidator = new BearerTokenValidator($accessTokenRepositoryMock);
|
||||
$authorizationValidator->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
$authorizationValidator->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$authorizationValidator->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
$authorizationValidator->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
|
||||
$request = new ServerRequest();
|
||||
$request = $request->withHeader('authorization', sprintf('Bearer %s', $json->access_token));
|
||||
@@ -201,12 +205,14 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase
|
||||
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
|
||||
|
||||
$responseType = new BearerTokenResponse($accessTokenRepositoryMock);
|
||||
$responseType->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
$responseType->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
$responseType->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
|
||||
$accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
|
||||
|
||||
$authorizationValidator = new BearerTokenValidator($accessTokenRepositoryMock);
|
||||
$authorizationValidator->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key');
|
||||
$authorizationValidator->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key');
|
||||
$authorizationValidator->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
$authorizationValidator->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key'));
|
||||
|
||||
$request = new ServerRequest();
|
||||
$request = $request->withHeader('authorization', 'Bearer blah');
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace LeagueTests;
|
||||
|
||||
use League\OAuth2\Server\CryptKey;
|
||||
use League\OAuth2\Server\Exception\OAuthServerException;
|
||||
use League\OAuth2\Server\Grant\AuthCodeGrant;
|
||||
use League\OAuth2\Server\Grant\ClientCredentialsGrant;
|
||||
@@ -10,14 +11,17 @@ 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\Repositories\UserRepositoryInterface;
|
||||
use League\OAuth2\Server\RequestTypes\AuthorizationRequest;
|
||||
use League\OAuth2\Server\ResponseTypes\BearerTokenResponse;
|
||||
use League\OAuth2\Server\Server;
|
||||
use LeagueTests\Stubs\AccessTokenEntity;
|
||||
use LeagueTests\Stubs\AuthCodeEntity;
|
||||
use LeagueTests\Stubs\ClientEntity;
|
||||
use LeagueTests\Stubs\StubResponseType;
|
||||
use LeagueTests\Stubs\UserEntity;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Zend\Diactoros\Response;
|
||||
use Zend\Diactoros\ServerRequest;
|
||||
use Zend\Diactoros\ServerRequestFactory;
|
||||
|
||||
class ServerTest extends \PHPUnit_Framework_TestCase
|
||||
@@ -28,15 +32,15 @@ class ServerTest extends \PHPUnit_Framework_TestCase
|
||||
$this->getMock(ClientRepositoryInterface::class),
|
||||
$this->getMock(AccessTokenRepositoryInterface::class),
|
||||
$this->getMock(ScopeRepositoryInterface::class),
|
||||
'',
|
||||
'',
|
||||
'file://' . __DIR__ . '/Stubs/private.key',
|
||||
'file://' . __DIR__ . '/Stubs/public.key',
|
||||
new StubResponseType()
|
||||
);
|
||||
|
||||
$server->enableGrantType(new ClientCredentialsGrant(), new \DateInterval('PT1M'));
|
||||
|
||||
try {
|
||||
$server->respondToRequest(ServerRequestFactory::fromGlobals(), new Response);
|
||||
$server->respondToAccessTokenRequest(ServerRequestFactory::fromGlobals(), new Response);
|
||||
} catch (OAuthServerException $e) {
|
||||
$this->assertEquals('unsupported_grant_type', $e->getErrorType());
|
||||
$this->assertEquals(400, $e->getHttpStatusCode());
|
||||
@@ -51,12 +55,15 @@ class ServerTest extends \PHPUnit_Framework_TestCase
|
||||
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
|
||||
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
|
||||
|
||||
$accessTokenRepositoryMock = $this->getMock(AccessTokenRepositoryInterface::class);
|
||||
$accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity());
|
||||
|
||||
$server = new Server(
|
||||
$clientRepository,
|
||||
$this->getMock(AccessTokenRepositoryInterface::class),
|
||||
$accessTokenRepositoryMock,
|
||||
$scopeRepositoryMock,
|
||||
'',
|
||||
'',
|
||||
'file://' . __DIR__ . '/Stubs/private.key',
|
||||
'file://' . __DIR__ . '/Stubs/public.key',
|
||||
new StubResponseType()
|
||||
);
|
||||
|
||||
@@ -65,58 +72,10 @@ class ServerTest extends \PHPUnit_Framework_TestCase
|
||||
$_POST['grant_type'] = 'client_credentials';
|
||||
$_POST['client_id'] = 'foo';
|
||||
$_POST['client_secret'] = 'bar';
|
||||
$response = $server->respondToRequest(ServerRequestFactory::fromGlobals(), new Response);
|
||||
$response = $server->respondToAccessTokenRequest(ServerRequestFactory::fromGlobals(), new Response);
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
}
|
||||
|
||||
public function testRespondToRequestPsrResponse()
|
||||
{
|
||||
$client = new ClientEntity();
|
||||
$client->setIdentifier('foo');
|
||||
$client->setIdentifier('http://bar.com');
|
||||
|
||||
$clientRepository = $this->getMock(ClientRepositoryInterface::class);
|
||||
$clientRepository->method('getClientEntity')->willReturn($client);
|
||||
|
||||
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
|
||||
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
|
||||
|
||||
$server = new Server(
|
||||
$clientRepository,
|
||||
$this->getMock(AccessTokenRepositoryInterface::class),
|
||||
$scopeRepositoryMock,
|
||||
'file://' . __DIR__ . '/Stubs/private.key',
|
||||
'file://' . __DIR__ . '/Stubs/public.key',
|
||||
new StubResponseType()
|
||||
);
|
||||
|
||||
$userRepository = $this->getMock(UserRepositoryInterface::class);
|
||||
$userRepository->method('getUserEntityByUserCredentials')->willReturn(new UserEntity());
|
||||
|
||||
$server->enableGrantType(
|
||||
new AuthCodeGrant(
|
||||
$this->getMock(AuthCodeRepositoryInterface::class),
|
||||
$this->getMock(RefreshTokenRepositoryInterface::class),
|
||||
$userRepository,
|
||||
new \DateInterval('PT1H')
|
||||
),
|
||||
new \DateInterval('PT1M')
|
||||
);
|
||||
|
||||
$_SERVER['HTTP_HOST'] = 'http://auth.com';
|
||||
$_SERVER['REQUEST_URI'] = '/auth';
|
||||
$_GET['response_type'] = 'code';
|
||||
$_GET['client_id'] = $client->getIdentifier();
|
||||
$_GET['redirect_uri'] = $client->getRedirectUri();
|
||||
$_POST['action'] = 'approve';
|
||||
$_POST['username'] = 'user';
|
||||
$_POST['password'] = 'pass';
|
||||
$response = $server->respondToRequest(ServerRequestFactory::fromGlobals(), new Response);
|
||||
$this->assertTrue($response instanceof ResponseInterface);
|
||||
$this->assertEquals(302, $response->getStatusCode());
|
||||
$this->assertTrue(strstr($response->getHeaderLine('location'), 'code=') !== false);
|
||||
}
|
||||
|
||||
public function testGetResponseType()
|
||||
{
|
||||
$clientRepository = $this->getMock(ClientRepositoryInterface::class);
|
||||
@@ -125,8 +84,8 @@ class ServerTest extends \PHPUnit_Framework_TestCase
|
||||
$clientRepository,
|
||||
$this->getMock(AccessTokenRepositoryInterface::class),
|
||||
$this->getMock(ScopeRepositoryInterface::class),
|
||||
'',
|
||||
''
|
||||
'file://' . __DIR__ . '/Stubs/private.key',
|
||||
'file://' . __DIR__ . '/Stubs/public.key'
|
||||
);
|
||||
|
||||
$abstractGrantReflection = new \ReflectionClass($server);
|
||||
@@ -136,7 +95,7 @@ class ServerTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertTrue($method->invoke($server) instanceof BearerTokenResponse);
|
||||
}
|
||||
|
||||
public function testValidateRequest()
|
||||
public function testValidateAuthenticatedRequest()
|
||||
{
|
||||
$clientRepository = $this->getMock(ClientRepositoryInterface::class);
|
||||
|
||||
@@ -144,8 +103,8 @@ class ServerTest extends \PHPUnit_Framework_TestCase
|
||||
$clientRepository,
|
||||
$this->getMock(AccessTokenRepositoryInterface::class),
|
||||
$this->getMock(ScopeRepositoryInterface::class),
|
||||
'',
|
||||
''
|
||||
'file://' . __DIR__ . '/Stubs/private.key',
|
||||
'file://' . __DIR__ . '/Stubs/public.key'
|
||||
);
|
||||
|
||||
try {
|
||||
@@ -154,4 +113,111 @@ class ServerTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('Missing "Authorization" header', $e->getHint());
|
||||
}
|
||||
}
|
||||
|
||||
public function testCompleteAuthorizationRequest()
|
||||
{
|
||||
$clientRepository = $this->getMock(ClientRepositoryInterface::class);
|
||||
|
||||
$server = new Server(
|
||||
$clientRepository,
|
||||
$this->getMock(AccessTokenRepositoryInterface::class),
|
||||
$this->getMock(ScopeRepositoryInterface::class),
|
||||
'file://' . __DIR__ . '/Stubs/private.key',
|
||||
'file://' . __DIR__ . '/Stubs/public.key'
|
||||
);
|
||||
|
||||
$authCodeRepository = $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock();
|
||||
$authCodeRepository->method('getNewAuthCode')->willReturn(new AuthCodeEntity());
|
||||
|
||||
$grant = new AuthCodeGrant(
|
||||
$authCodeRepository,
|
||||
$this->getMock(RefreshTokenRepositoryInterface::class),
|
||||
new \DateInterval('PT10M')
|
||||
);
|
||||
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/Stubs/private.key'));
|
||||
$grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/Stubs/public.key'));
|
||||
|
||||
$server->enableGrantType($grant);
|
||||
|
||||
$authRequest = new AuthorizationRequest();
|
||||
$authRequest->setAuthorizationApproved(true);
|
||||
$authRequest->setClient(new ClientEntity());
|
||||
$authRequest->setGrantTypeId('authorization_code');
|
||||
$authRequest->setUser(new UserEntity());
|
||||
|
||||
$this->assertTrue(
|
||||
$server->completeAuthorizationRequest($authRequest, new Response) instanceof ResponseInterface
|
||||
);
|
||||
}
|
||||
|
||||
public function testValidateAuthorizationRequest()
|
||||
{
|
||||
$client = new ClientEntity();
|
||||
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
|
||||
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
|
||||
|
||||
$grant = new AuthCodeGrant(
|
||||
$this->getMock(AuthCodeRepositoryInterface::class),
|
||||
$this->getMock(RefreshTokenRepositoryInterface::class),
|
||||
new \DateInterval('PT10M')
|
||||
);
|
||||
$grant->setClientRepository($clientRepositoryMock);
|
||||
|
||||
$server = new Server(
|
||||
$clientRepositoryMock,
|
||||
$this->getMock(AccessTokenRepositoryInterface::class),
|
||||
$this->getMock(ScopeRepositoryInterface::class),
|
||||
'file://' . __DIR__ . '/Stubs/private.key',
|
||||
'file://' . __DIR__ . '/Stubs/public.key'
|
||||
);
|
||||
$server->enableGrantType($grant);
|
||||
|
||||
$request = new ServerRequest(
|
||||
[],
|
||||
[],
|
||||
null,
|
||||
null,
|
||||
'php://input',
|
||||
$headers = [],
|
||||
$cookies = [],
|
||||
$queryParams = [
|
||||
'response_type' => 'code',
|
||||
'client_id' => 'foo',
|
||||
]
|
||||
);
|
||||
|
||||
$this->assertTrue($server->validateAuthorizationRequest($request) instanceof AuthorizationRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
|
||||
* @expectedExceptionCode 2
|
||||
*/
|
||||
public function testValidateAuthorizationRequestUnregistered()
|
||||
{
|
||||
$server = new Server(
|
||||
$this->getMock(ClientRepositoryInterface::class),
|
||||
$this->getMock(AccessTokenRepositoryInterface::class),
|
||||
$this->getMock(ScopeRepositoryInterface::class),
|
||||
'file://' . __DIR__ . '/Stubs/private.key',
|
||||
'file://' . __DIR__ . '/Stubs/public.key'
|
||||
);
|
||||
|
||||
$request = new ServerRequest(
|
||||
[],
|
||||
[],
|
||||
null,
|
||||
null,
|
||||
'php://input',
|
||||
$headers = [],
|
||||
$cookies = [],
|
||||
$queryParams = [
|
||||
'response_type' => 'code',
|
||||
'client_id' => 'foo',
|
||||
]
|
||||
);
|
||||
|
||||
$server->validateAuthorizationRequest($request);
|
||||
}
|
||||
}
|
||||
|
||||
13
tests/Stubs/AccessTokenEntity.php
Normal file
13
tests/Stubs/AccessTokenEntity.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace LeagueTests\Stubs;
|
||||
|
||||
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\Traits\AccessTokenTrait;
|
||||
use League\OAuth2\Server\Entities\Traits\EntityTrait;
|
||||
use League\OAuth2\Server\Entities\Traits\TokenEntityTrait;
|
||||
|
||||
class AccessTokenEntity implements AccessTokenEntityInterface
|
||||
{
|
||||
use AccessTokenTrait, TokenEntityTrait, EntityTrait;
|
||||
}
|
||||
13
tests/Stubs/AuthCodeEntity.php
Normal file
13
tests/Stubs/AuthCodeEntity.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace LeagueTests\Stubs;
|
||||
|
||||
use League\OAuth2\Server\Entities\AuthCodeEntityInterface;
|
||||
use League\OAuth2\Server\Entities\Traits\AuthCodeTrait;
|
||||
use League\OAuth2\Server\Entities\Traits\EntityTrait;
|
||||
use League\OAuth2\Server\Entities\Traits\TokenEntityTrait;
|
||||
|
||||
class AuthCodeEntity implements AuthCodeEntityInterface
|
||||
{
|
||||
use EntityTrait, TokenEntityTrait, AuthCodeTrait;
|
||||
}
|
||||
@@ -2,91 +2,21 @@
|
||||
|
||||
namespace LeagueTests\Stubs;
|
||||
|
||||
use League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface;
|
||||
use League\OAuth2\Server\Entities\ClientEntityInterface;
|
||||
use League\OAuth2\Server\Entities\Traits\ClientTrait;
|
||||
use League\OAuth2\Server\Entities\Traits\EntityTrait;
|
||||
|
||||
class ClientEntity implements ClientEntityInterface
|
||||
{
|
||||
use EntityTrait;
|
||||
use EntityTrait, ClientTrait;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $secret;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectUri;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
public function setRedirectUri($uri)
|
||||
{
|
||||
return $this->name;
|
||||
$this->redirectUri = $uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function canKeepASecret()
|
||||
{
|
||||
return $this->secret !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setSecret($secret)
|
||||
{
|
||||
$this->secret = password_hash($secret, PASSWORD_DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the hashed client secret
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSecret()
|
||||
{
|
||||
return $this->secret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace LeagueTests\Stubs;
|
||||
|
||||
use League\OAuth2\Server\CryptKey;
|
||||
use League\OAuth2\Server\CryptTrait;
|
||||
|
||||
class CryptTraitStub
|
||||
@@ -10,8 +11,8 @@ class CryptTraitStub
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->setPrivateKeyPath('file://' . __DIR__ . '/private.key');
|
||||
$this->setPublicKeyPath('file://' . __DIR__ . '/public.key');
|
||||
$this->setPrivateKey(new CryptKey('file://' . __DIR__ . '/private.key'));
|
||||
$this->setPublicKey(new CryptKey('file://' . __DIR__ . '/public.key'));
|
||||
}
|
||||
|
||||
public function doEncrypt($unencryptedData)
|
||||
|
||||
12
tests/Stubs/RefreshTokenEntity.php
Normal file
12
tests/Stubs/RefreshTokenEntity.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace LeagueTests\Stubs;
|
||||
|
||||
use League\OAuth2\Server\Entities\RefreshTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\Traits\EntityTrait;
|
||||
use League\OAuth2\Server\Entities\Traits\RefreshTokenTrait;
|
||||
|
||||
class RefreshTokenEntity implements RefreshTokenEntityInterface
|
||||
{
|
||||
use RefreshTokenTrait, EntityTrait;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace LeagueTests\Stubs;
|
||||
|
||||
use League\OAuth2\Server\Entities\Interfaces\ScopeEntityInterface;
|
||||
use League\OAuth2\Server\Entities\ScopeEntityInterface;
|
||||
use League\OAuth2\Server\Entities\Traits\EntityTrait;
|
||||
|
||||
class ScopeEntity implements ScopeEntityInterface
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace LeagueTests\Stubs;
|
||||
|
||||
use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\RefreshTokenEntityInterface;
|
||||
use League\OAuth2\Server\Exception\OAuthServerException;
|
||||
use League\OAuth2\Server\ResponseTypes\AbstractResponseType;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
@@ -27,7 +27,7 @@ class StubResponseType extends AbstractResponseType
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface $accessToken
|
||||
* @param \League\OAuth2\Server\Entities\AccessTokenEntityInterface $accessToken
|
||||
*/
|
||||
public function setAccessToken(AccessTokenEntityInterface $accessToken)
|
||||
{
|
||||
@@ -35,7 +35,7 @@ class StubResponseType extends AbstractResponseType
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface $refreshToken
|
||||
* @param \League\OAuth2\Server\Entities\RefreshTokenEntityInterface $refreshToken
|
||||
*/
|
||||
public function setRefreshToken(RefreshTokenEntityInterface $refreshToken)
|
||||
{
|
||||
|
||||
@@ -2,12 +2,15 @@
|
||||
|
||||
namespace LeagueTests\Stubs;
|
||||
|
||||
use League\OAuth2\Server\Entities\Interfaces\UserEntityInterface;
|
||||
use League\OAuth2\Server\Entities\Traits\EntityTrait;
|
||||
use League\OAuth2\Server\Entities\UserEntityInterface;
|
||||
|
||||
class UserEntity implements UserEntityInterface
|
||||
{
|
||||
public function getIdentifier()
|
||||
use EntityTrait;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
return 123;
|
||||
$this->setIdentifier(123);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user