Skip to content

Commit

Permalink
Add tests for middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
bakura10 committed Aug 26, 2015
1 parent 6c2898d commit d442ffe
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 39 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ it very early in your pipeline.
couldn't take advantage of batch optimization deletions in database. You should instead use a more reliable and efficient way to delete
expired tokens (either through a CRON task, or database scheduling manager).

* [BC] The `isTokenValid` method has been removed from the ResourceServer. Use the `isValid` method from the token instead.

* Tokens now have a `isValid` method to check if a given token (either authorization, access or refresh) is valid against
some scopes.

## v0.7.1

* Now properly triggers an `EVENT_CODE_CREATED` event instead of `EVENT_CODE_FAILED` when response is between 200 and 399 (previously,
Expand Down
31 changes: 20 additions & 11 deletions src/Server/AuthorizationMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public function __construct(AuthorizationServerInterface $authorizationServer)

$this->pipe('/authorize', [$this, 'handleAuthorizeRequest']);
$this->pipe('/token', [$this, 'handleTokenRequest']);
$this->pipe('/revoke', [$this, 'handleRevokeRequest']);
$this->pipe('/revoke', [$this, 'handleRevocationRequest']);
}

/**
Expand All @@ -63,22 +63,31 @@ public function handleAuthorizeRequest(Request $request, Response $response, cal
}

/**
* @param Request $request
* @param Response $response
* @param callable|null $next
* Generate a new access token for the given request
*
* @param Request $request
* @param Response $response
* @param callable|null $next
* @return Response
*/
public function handleTokenRequest(Request $request, Response $response, callable $next = null)
{
throw new \RuntimeException('Not implemented yet');
// @TODO: we should integrate with an authentication service to pass the logged user, if any. Currently,
// it will work out of the box for password grant

return $this->authorizationServer->handleTokenRequest($request);
}

/**
* @param Request $request
* @param Response $response
* @param callable|null $next
* Revoke a given token
*
* @param Request $request
* @param Response $response
* @param callable|null $next
* @return Response
*/
public function handleRevokeRequest(Request $request, Response $response, callable $next = nul)
public function handleRevocationRequest(Request $request, Response $response, callable $next = null)
{
throw new \RuntimeException('Not implemented yet');
return $this->authorizationServer->handleRevocationRequest($request);
}
}
}
19 changes: 19 additions & 0 deletions src/Server/Entity/AbstractToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -202,4 +202,23 @@ public function matchScopes($scopes)

return empty($diff);
}

/**
* Check if the token is valid, according to the given scope and expiration dates
*
* @param array $scopes
* @return bool
*/
public function isValid($scopes = [])
{
if ($this->isExpired()) {
return false;
}

if (!empty($scopes) && !$this->matchScopes($scopes)) {
return false;
}

return true;
}
}
22 changes: 1 addition & 21 deletions src/Server/ResourceServer.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public function getAccessToken(ServerRequestInterface $request, $scopes = [])

$token = $this->accessTokenService->getToken($token);

if ($token === null || !$this->isTokenValid($token, $scopes)) {
if ($token === null || !$token->isValid($scopes)) {
throw new InvalidAccessTokenException('Access token has expired or has been deleted');
}

Expand Down Expand Up @@ -101,24 +101,4 @@ private function extractAccessToken(ServerRequestInterface $request)

return isset($queryParams['access_token']) ? $queryParams['access_token'] : null;
}

/**
* Check if the given token is valid (not expired and/or match the given scopes)
*
* @param AccessToken $accessToken
* @param array $scopes
* @return bool
*/
private function isTokenValid(AccessToken $accessToken, $scopes = [])
{
if ($accessToken->isExpired()) {
return false;
}

if (!empty($scopes) && !$accessToken->matchScopes($scopes)) {
return false;
}

return true;
}
}
10 changes: 5 additions & 5 deletions src/Server/ResourceServerMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@
/**
* Middleware for a resource server
*
* This middleware aims to sit very early in your pipeline. It will check if a request has an access token, and if so, will
* try to validate it. If the token is invalid, the middleware will immediately return.
* This middleware aims to sit very early in your pipeline. It will check if a request has an access token, and if so,
* will try to validate it. If the token is invalid, the middleware will immediately return.
*
* If the token is valid, it will store it as part of the request under the attribute "oauth_token", so that it can be used later
* one by a permission system, for instance
* If the token is valid, it will store it as part of the request under the attribute "oauth_token", so that it can
* be used later one by a permission system, for instance
*/
class ResourceServerMiddleware implements MiddlewareInterface
{
Expand Down Expand Up @@ -66,4 +66,4 @@ public function __invoke(ServerRequestInterface $request, ResponseInterface $res

return $out ? $out($request->withAttribute('oauth_token', $token), $response) : $response;
}
}
}
66 changes: 66 additions & 0 deletions tests/Server/AuthorizationMiddlewareTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license.
*/

namespace ZfrOAuth2Test\Server;

use Psr\Http\Message\ServerRequestInterface as RequestInterface;
use Psr\Http\Message\ResponseInterface;
use ZfrOAuth2\Server\AuthorizationMiddleware;
use ZfrOAuth2\Server\AuthorizationServerInterface;

/**
* @author Michaël Gallego <mic.gallego@gmail.com>
* @licence MIT
* @covers \ZfrOAuth2\Server\AuthorizationMiddleware
*/
class AuthorizationMiddlewareTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \PHPUnit_Framework_MockObject_MockObject|AuthorizationServerInterface
*/
private $authorizationServer;

/**
* @var AuthorizationMiddleware
*/
private $authorizationMiddleware;

public function setUp()
{
$this->authorizationServer = $this->getMock(AuthorizationServerInterface::class);
$this->authorizationMiddleware = new AuthorizationMiddleware($this->authorizationServer);
}

public function testCanHandleTokenRequest()
{
$request = $this->getMock(RequestInterface::class);
$response = $this->getMock(ResponseInterface::class);

$this->authorizationServer->expects($this->once())->method('handleTokenRequest')->with($request);
$this->authorizationMiddleware->handleTokenRequest($request, $response);
}

public function testCanHandleRevocationRequest()
{
$request = $this->getMock(RequestInterface::class);
$response = $this->getMock(ResponseInterface::class);

$this->authorizationServer->expects($this->once())->method('handleRevocationRequest')->with($request);
$this->authorizationMiddleware->handleRevocationRequest($request, $response);
}
}
4 changes: 2 additions & 2 deletions tests/Server/ResourceServerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public function testCanExtractAccessTokenFromAuthorizationHeader()
$request->expects($this->once())->method('getHeaderLine')->will($this->returnValue('Bearer token'));

$token = $this->getMock(AccessToken::class);
$token->expects($this->once())->method('isExpired')->will($this->returnValue(false));
$token->expects($this->once())->method('isValid')->will($this->returnValue(true));

$this->tokenService->expects($this->once())
->method('getToken')
Expand All @@ -73,7 +73,7 @@ public function testCanExtractAccessTokenFromQueryString()
$request->expects($this->once())->method('getQueryParams')->will($this->returnValue(['access_token' => 'token']));

$token = $this->getMock(AccessToken::class);
$token->expects($this->once())->method('isExpired')->will($this->returnValue(false));
$token->expects($this->once())->method('isValid')->will($this->returnValue(true));

$this->tokenService->expects($this->once())
->method('getToken')
Expand Down

0 comments on commit d442ffe

Please sign in to comment.