123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\Integration\Model;
- use Magento\Framework\Exception\InputException;
- use Magento\Integration\Model\Oauth\Token as TokenModel;
- use Magento\TestFramework\Helper\Bootstrap;
- use Magento\TestFramework\TestCase\WebapiAbstract;
- use Magento\User\Model\User as UserModel;
- use Magento\Framework\Webapi\Exception as HTTPExceptionCodes;
- use Magento\Integration\Model\Oauth\Token\RequestLog\Config as TokenThrottlerConfig;
- /**
- * api-functional test for \Magento\Integration\Model\AdminTokenService.
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
- class AdminTokenServiceTest extends WebapiAbstract
- {
- const SERVICE_NAME = "integrationAdminTokenServiceV1";
- const SERVICE_VERSION = "V1";
- const RESOURCE_PATH_ADMIN_TOKEN = "/V1/integration/admin/token";
- /**
- * @var \Magento\Integration\Api\AdminTokenServiceInterface
- */
- private $tokenService;
- /**
- * @var TokenModel
- */
- private $tokenModel;
- /**
- * @var UserModel
- */
- private $userModel;
- /**
- * @var int
- */
- private $attemptsCountToLockAccount;
- /**
- * Setup AdminTokenService
- */
- public function setUp()
- {
- $this->_markTestAsRestOnly();
- $this->tokenService = Bootstrap::getObjectManager()->get(\Magento\Integration\Model\AdminTokenService::class);
- $this->tokenModel = Bootstrap::getObjectManager()->get(\Magento\Integration\Model\Oauth\Token::class);
- $this->userModel = Bootstrap::getObjectManager()->get(\Magento\User\Model\User::class);
- /** @var TokenThrottlerConfig $tokenThrottlerConfig */
- $tokenThrottlerConfig = Bootstrap::getObjectManager()->get(TokenThrottlerConfig::class);
- $this->attemptsCountToLockAccount = $tokenThrottlerConfig->getMaxFailuresCount();
- }
- /**
- * @magentoApiDataFixture Magento/Webapi/_files/webapi_user.php
- */
- public function testCreateAdminAccessToken()
- {
- $adminUserNameFromFixture = 'webapi_user';
- $serviceInfo = [
- 'rest' => [
- 'resourcePath' => self::RESOURCE_PATH_ADMIN_TOKEN,
- 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST,
- ],
- ];
- $requestData = [
- 'username' => $adminUserNameFromFixture,
- 'password' => \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD,
- ];
- $accessToken = $this->_webApiCall($serviceInfo, $requestData);
- $this->assertToken($adminUserNameFromFixture, $accessToken);
- }
- /**
- * Provider to test input validation
- *
- * @return array
- */
- public function validationDataProvider()
- {
- return [
- 'Check for empty credentials' => ['', ''],
- 'Check for null credentials' => [null, null]
- ];
- }
- /**
- * @dataProvider validationDataProvider
- */
- public function testCreateAdminAccessTokenEmptyOrNullCredentials()
- {
- $noExceptionOccurred = false;
- try {
- $serviceInfo = [
- 'rest' => [
- 'resourcePath' => self::RESOURCE_PATH_ADMIN_TOKEN,
- 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST,
- ],
- ];
- $requestData = ['username' => '', 'password' => ''];
- $this->_webApiCall($serviceInfo, $requestData);
- $noExceptionOccurred = true;
- } catch (\Exception $exception) {
- $this->assertInputExceptionMessages($exception);
- }
- if ($noExceptionOccurred) {
- $this->fail("Exception was expected to be thrown when provided credentials are invalid.");
- }
- }
- public function testCreateAdminAccessTokenInvalidCredentials()
- {
- $customerUserName = 'invalid';
- $password = 'invalid';
- $noExceptionOccurred = false;
- try {
- $serviceInfo = [
- 'rest' => [
- 'resourcePath' => self::RESOURCE_PATH_ADMIN_TOKEN,
- 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST,
- ],
- ];
- $requestData = ['username' => $customerUserName, 'password' => $password];
- $this->_webApiCall($serviceInfo, $requestData);
- $noExceptionOccurred = true;
- } catch (\Exception $exception) {
- $this->assertInvalidCredentialsException($exception);
- }
- if ($noExceptionOccurred) {
- $this->fail("Exception was expected to be thrown when provided credentials are invalid.");
- }
- }
- /**
- * @magentoApiDataFixture Magento/Webapi/_files/webapi_user.php
- */
- public function testUseAdminAccessTokenInactiveAdmin()
- {
- $adminUserNameFromFixture = 'webapi_user';
- $serviceInfo = [
- 'rest' => [
- 'resourcePath' => self::RESOURCE_PATH_ADMIN_TOKEN,
- 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST,
- ],
- ];
- $requestData = [
- 'username' => $adminUserNameFromFixture,
- 'password' => \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD,
- ];
- $accessToken = $this->_webApiCall($serviceInfo, $requestData);
- $this->assertToken($adminUserNameFromFixture, $accessToken);
- $serviceInfo = [
- 'rest' => [
- 'resourcePath' => '/V1/store/storeConfigs',
- 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
- 'token' => $accessToken
- ]
- ];
- $requestData = [
- 'storeCodes' => ['default'],
- ];
- $storeConfigs = $this->_webApiCall($serviceInfo, $requestData);
- $this->assertNotNull($storeConfigs);
- $adminUser = $this->userModel->loadByUsername($adminUserNameFromFixture);
- $adminUser->setData("is_active", 0);
- $adminUser->save();
- $serviceInfo = [
- 'rest' => [
- 'resourcePath' => '/V1/store/storeConfigs',
- 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
- 'token' => $accessToken
- ]
- ];
- $requestData = [
- 'storeCodes' => ['default'],
- ];
- $noExceptionOccurred = false;
- try {
- $this->_webApiCall($serviceInfo, $requestData);
- $noExceptionOccurred = true;
- } catch (\Exception $exception) {
- $this->assertUnauthorizedAccessException($exception);
- }
- if ($noExceptionOccurred) {
- $this->fail("Exception was expected to be thrown when provided token is expired.");
- }
- }
- /**
- * @magentoApiDataFixture Magento/Webapi/_files/webapi_user.php
- */
- public function testThrottlingMaxAttempts()
- {
- $adminUserNameFromFixture = 'webapi_user';
- $serviceInfo = [
- 'rest' => [
- 'resourcePath' => self::RESOURCE_PATH_ADMIN_TOKEN,
- 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST,
- ],
- ];
- $invalidCredentials = [
- 'username' => $adminUserNameFromFixture,
- 'password' => 'invalid',
- ];
- $validCredentials = [
- 'username' => $adminUserNameFromFixture,
- 'password' => \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD,
- ];
- /* Try to get token using invalid credentials for 5 times (account is locked after 6 attempts) */
- $noExceptionOccurred = false;
- for ($i = 0; $i < ($this->attemptsCountToLockAccount - 1); $i++) {
- try {
- $this->_webApiCall($serviceInfo, $invalidCredentials);
- $noExceptionOccurred = true;
- } catch (\Exception $exception) {
- }
- }
- if ($noExceptionOccurred) {
- $this->fail(
- "Precondition failed: exception should have occurred when token was requested with invalid credentials."
- );
- }
- /** On 6th attempt it still should be possible to get token if valid credentials are specified */
- $accessToken = $this->_webApiCall($serviceInfo, $validCredentials);
- $this->assertToken($adminUserNameFromFixture, $accessToken);
- }
- /**
- * @magentoApiDataFixture Magento/Webapi/_files/webapi_user.php
- */
- public function testThrottlingAccountLockout()
- {
- $adminUserNameFromFixture = 'webapi_user';
- $serviceInfo = [
- 'rest' => [
- 'resourcePath' => self::RESOURCE_PATH_ADMIN_TOKEN,
- 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST,
- ],
- ];
- $invalidCredentials = [
- 'username' => $adminUserNameFromFixture,
- 'password' => 'invalid',
- ];
- $validCredentials = [
- 'username' => $adminUserNameFromFixture,
- 'password' => \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD,
- ];
- /* Try to get token using invalid credentials for 5 times (account would be locked after 6 attempts) */
- $noExceptionOccurred = false;
- for ($i = 0; $i < $this->attemptsCountToLockAccount; $i++) {
- try {
- $this->_webApiCall($serviceInfo, $invalidCredentials);
- $noExceptionOccurred = true;
- } catch (\Exception $exception) {
- $this->assertInvalidCredentialsException($exception);
- }
- if ($noExceptionOccurred) {
- $this->fail("Exception was expected to be thrown when provided credentials are invalid.");
- }
- }
- $noExceptionOccurred = false;
- try {
- $this->_webApiCall($serviceInfo, $validCredentials);
- $noExceptionOccurred = true;
- } catch (\Exception $exception) {
- $this->assertInvalidCredentialsException($exception);
- }
- if ($noExceptionOccurred) {
- $this->fail("Exception was expected to be thrown because account should have been locked at this point.");
- }
- }
- /**
- * Assert for presence of Input exception messages
- *
- * @param \Exception $exception
- */
- private function assertInputExceptionMessages($exception)
- {
- $this->assertEquals(HTTPExceptionCodes::HTTP_BAD_REQUEST, $exception->getCode());
- $exceptionData = $this->processRestExceptionResult($exception);
- $expectedExceptionData = [
- 'message' => 'One or more input exceptions have occurred.',
- 'errors' => [
- [
- 'message' => '"%fieldName" is required. Enter and try again.',
- 'parameters' => [
- 'fieldName' => 'username',
- ],
- ],
- [
- 'message' => '"%fieldName" is required. Enter and try again.',
- 'parameters' => [
- 'fieldName' => 'password',
- ]
- ],
- ],
- ];
- $this->assertEquals($expectedExceptionData, $exceptionData);
- }
- /**
- * Make sure that status code and message are correct in case of authentication failure.
- *
- * @param \Exception $exception
- */
- private function assertInvalidCredentialsException($exception)
- {
- $this->assertEquals(
- HTTPExceptionCodes::HTTP_UNAUTHORIZED,
- $exception->getCode(),
- "Response HTTP code is invalid."
- );
- $exceptionData = $this->processRestExceptionResult($exception);
- $expectedExceptionData = [
- 'message' => 'The account sign-in was incorrect or your account is disabled temporarily. '
- . 'Please wait and try again later.'
- ];
- $this->assertEquals($expectedExceptionData, $exceptionData, "Exception message is invalid.");
- }
- /**
- * Make sure that status code and message are correct in case of authentication failure.
- *
- * @param \Exception $exception
- */
- private function assertUnauthorizedAccessException($exception)
- {
- $this->assertEquals(
- HTTPExceptionCodes::HTTP_UNAUTHORIZED,
- $exception->getCode(),
- "Response HTTP code is invalid."
- );
- $exceptionData = $this->processRestExceptionResult($exception);
- $expectedExceptionData = [
- 'message' => "The consumer isn't authorized to access %resources.",
- 'parameters' => [
- 'resources' => 'Magento_Backend::store'
- ]
- ];
- $this->assertEquals($expectedExceptionData, $exceptionData, "Exception message is invalid.");
- }
- /**
- * Make sure provided token is valid and belongs to the specified user.
- *
- * @param string $username
- * @param string $accessToken
- */
- private function assertToken($username, $accessToken)
- {
- $adminUserId = $this->userModel->loadByUsername($username)->getId();
- /** @var $token TokenModel */
- $token = $this->tokenModel
- ->loadByAdminId($adminUserId)
- ->getToken();
- $this->assertEquals($accessToken, $token);
- }
- }
|