From 1d92e87d5025aa83696851a156f727ce9586a3fa Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 7 Aug 2016 10:26:34 +0200 Subject: [PATCH] Updated AuthenticateAction to use the APiKeyService instead of the RestTokenService --- module/Rest/src/Action/AuthenticateAction.php | 37 ++++++++++--------- module/Rest/src/Util/RestUtils.php | 1 + .../test/Action/AuthenticateActionTest.php | 31 +++++++--------- 3 files changed, 33 insertions(+), 36 deletions(-) diff --git a/module/Rest/src/Action/AuthenticateAction.php b/module/Rest/src/Action/AuthenticateAction.php index 7ac531df..0fcac3f9 100644 --- a/module/Rest/src/Action/AuthenticateAction.php +++ b/module/Rest/src/Action/AuthenticateAction.php @@ -4,35 +4,34 @@ namespace Shlinkio\Shlink\Rest\Action; use Acelaya\ZsmAnnotatedServices\Annotation\Inject; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; -use Shlinkio\Shlink\Rest\Exception\AuthenticationException; -use Shlinkio\Shlink\Rest\Service\RestTokenService; -use Shlinkio\Shlink\Rest\Service\RestTokenServiceInterface; +use Shlinkio\Shlink\Rest\Service\ApiKeyService; +use Shlinkio\Shlink\Rest\Service\ApiKeyServiceInterface; use Shlinkio\Shlink\Rest\Util\RestUtils; use Zend\Diactoros\Response\JsonResponse; use Zend\I18n\Translator\TranslatorInterface; class AuthenticateAction extends AbstractRestAction { - /** - * @var RestTokenServiceInterface - */ - private $restTokenService; /** * @var TranslatorInterface */ private $translator; + /** + * @var ApiKeyService|ApiKeyServiceInterface + */ + private $apiKeyService; /** * AuthenticateAction constructor. - * @param RestTokenServiceInterface|RestTokenService $restTokenService + * @param ApiKeyServiceInterface|ApiKeyService $apiKeyService * @param TranslatorInterface $translator * - * @Inject({RestTokenService::class, "translator"}) + * @Inject({ApiKeyService::class, "translator"}) */ - public function __construct(RestTokenServiceInterface $restTokenService, TranslatorInterface $translator) + public function __construct(ApiKeyServiceInterface $apiKeyService, TranslatorInterface $translator) { - $this->restTokenService = $restTokenService; $this->translator = $translator; + $this->apiKeyService = $apiKeyService; } /** @@ -44,7 +43,7 @@ class AuthenticateAction extends AbstractRestAction public function dispatch(Request $request, Response $response, callable $out = null) { $authData = $request->getParsedBody(); - if (! isset($authData['apiKey']) && ! isset($authData['username'], $authData['password'])) { + if (! isset($authData['apiKey'])) { return new JsonResponse([ 'error' => RestUtils::INVALID_ARGUMENT_ERROR, 'message' => $this->translator->translate( @@ -53,14 +52,16 @@ class AuthenticateAction extends AbstractRestAction ], 400); } - try { - $token = $this->restTokenService->createToken($authData['username'], $authData['password']); - return new JsonResponse(['token' => $token->getToken()]); - } catch (AuthenticationException $e) { + // Authenticate using provided API key + if (! $this->apiKeyService->check($authData['apiKey'])) { return new JsonResponse([ - 'error' => RestUtils::getRestErrorCodeFromException($e), - 'message' => $this->translator->translate('Invalid username and/or password'), + 'error' => RestUtils::INVALID_API_KEY_ERROR, + 'message' => $this->translator->translate('Provided API key does not exist or is invalid.'), ], 401); } + + // TODO Generate a JSON Web Token that will be used for authorization in next requests + + return new JsonResponse(['token' => '']); } } diff --git a/module/Rest/src/Util/RestUtils.php b/module/Rest/src/Util/RestUtils.php index b67491ed..8326487e 100644 --- a/module/Rest/src/Util/RestUtils.php +++ b/module/Rest/src/Util/RestUtils.php @@ -12,6 +12,7 @@ class RestUtils const INVALID_ARGUMENT_ERROR = 'INVALID_ARGUMENT'; const INVALID_CREDENTIALS_ERROR = 'INVALID_CREDENTIALS'; const INVALID_AUTH_TOKEN_ERROR = 'INVALID_AUTH_TOKEN'; + const INVALID_API_KEY_ERROR = 'INVALID_API_KEY'; const NOT_FOUND_ERROR = 'NOT_FOUND'; const UNKNOWN_ERROR = 'UNKNOWN_ERROR'; diff --git a/module/Rest/test/Action/AuthenticateActionTest.php b/module/Rest/test/Action/AuthenticateActionTest.php index d61da421..57522852 100644 --- a/module/Rest/test/Action/AuthenticateActionTest.php +++ b/module/Rest/test/Action/AuthenticateActionTest.php @@ -3,10 +3,8 @@ namespace ShlinkioTest\Shlink\Rest\Action; use PHPUnit_Framework_TestCase as TestCase; use Prophecy\Prophecy\ObjectProphecy; -use Shlinkio\Shlink\Core\Entity\RestToken; use Shlinkio\Shlink\Rest\Action\AuthenticateAction; -use Shlinkio\Shlink\Rest\Exception\AuthenticationException; -use Shlinkio\Shlink\Rest\Service\RestTokenService; +use Shlinkio\Shlink\Rest\Service\ApiKeyService; use Zend\Diactoros\Response; use Zend\Diactoros\ServerRequestFactory; use Zend\I18n\Translator\Translator; @@ -20,12 +18,12 @@ class AuthenticateActionTest extends TestCase /** * @var ObjectProphecy */ - protected $tokenService; + protected $apiKeyService; public function setUp() { - $this->tokenService = $this->prophesize(RestTokenService::class); - $this->action = new AuthenticateAction($this->tokenService->reveal(), Translator::factory([])); + $this->apiKeyService = $this->prophesize(ApiKeyService::class); + $this->action = new AuthenticateAction($this->apiKeyService->reveal(), Translator::factory([])); } /** @@ -40,34 +38,31 @@ class AuthenticateActionTest extends TestCase /** * @test */ - public function properCredentialsReturnTokenInResponse() + public function properApiKeyReturnsTokenInResponse() { - $this->tokenService->createToken('foo', 'bar')->willReturn( - (new RestToken())->setToken('abc-ABC') - )->shouldBeCalledTimes(1); + $this->apiKeyService->check('foo')->willReturn(true) + ->shouldBeCalledTimes(1); $request = ServerRequestFactory::fromGlobals()->withParsedBody([ - 'username' => 'foo', - 'password' => 'bar', + 'apiKey' => 'foo', ]); $response = $this->action->__invoke($request, new Response()); $this->assertEquals(200, $response->getStatusCode()); $response->getBody()->rewind(); - $this->assertEquals(['token' => 'abc-ABC'], json_decode($response->getBody()->getContents(), true)); + $this->assertTrue(strpos($response->getBody()->getContents(), '"token"') > 0); } /** * @test */ - public function authenticationExceptionsReturnErrorResponse() + public function invalidApiKeyReturnsErrorResponse() { - $this->tokenService->createToken('foo', 'bar')->willThrow(new AuthenticationException()) - ->shouldBeCalledTimes(1); + $this->apiKeyService->check('foo')->willReturn(false) + ->shouldBeCalledTimes(1); $request = ServerRequestFactory::fromGlobals()->withParsedBody([ - 'username' => 'foo', - 'password' => 'bar', + 'apiKey' => 'foo', ]); $response = $this->action->__invoke($request, new Response()); $this->assertEquals(401, $response->getStatusCode());