![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/vendor/magento/module-two-factor-auth/Test/Api/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ declare(strict_types=1); namespace Magento\TwoFactorAuth\Test\Api; use Magento\Framework\HTTP\ClientInterface; use Magento\Framework\Serialize\SerializerInterface; use Magento\Framework\UrlInterface; use Magento\Framework\Webapi\Rest\Request; use Magento\Integration\Model\Oauth\TokenFactory; use Magento\Integration\Model\ResourceModel\Oauth\Token as TokenResource; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\WebapiAbstract; use Magento\TwoFactorAuth\Api\TfaInterface; use Magento\TwoFactorAuth\Model\Provider\Engine\Google; use Magento\User\Model\UserFactory; use OTPHP\TOTP; /** * Class checks google authentication behaviour */ class GoogleAuthenticateTest extends WebapiAbstract { const SERVICE_VERSION = 'V1'; const SERVICE_NAME = 'twoFactorAuthGoogleAuthenticateV1'; const OPERATION = 'CreateAdminAccessToken'; const RESOURCE_PATH = '/V1/tfa/provider/google/authenticate'; /** * @var UserFactory */ private $userFactory; /** * @var Google */ private $google; /** * @var TfaInterface */ private $tfa; /** * @var ClientInterface */ private $client; /** * @var UrlInterface */ private $url; /** * @var SerializerInterface */ private $json; /** * @var TokenResource */ private $tokenResource; /** * @var TokenFactory */ private $tokenFactory; /** * @inheritdoc */ protected function setUp(): void { $objectManager = Bootstrap::getObjectManager(); $this->userFactory = $objectManager->get(UserFactory::class); $this->google = $objectManager->get(Google::class); $this->tfa = $objectManager->get(TfaInterface::class); $this->client = $objectManager->get(ClientInterface::class); $this->url = $objectManager->get(UrlInterface::class); $this->json = $objectManager->get(SerializerInterface::class); $this->tokenResource = $objectManager->get(TokenResource::class); $this->tokenFactory = $objectManager->get(TokenFactory::class); } /** * @magentoApiDataFixture Magento/User/_files/user_with_custom_role.php * * @return void */ public function testInvalidCredentials(): void { $serviceInfo = $this->buildServiceInfo(); try { $this->_webApiCall( $serviceInfo, [ 'username' => 'customRoleUser', 'password' => 'bad', 'otp' => 'foo' ] ); self::fail('Endpoint should have thrown an exception'); } catch (\Throwable $exception) { $response = json_decode($exception->getMessage(), true); if (json_last_error()) { $message = $exception->getMessage(); } else { $message = $response['message']; } self::assertSame( 'The account sign-in was incorrect or your account is disabled temporarily. ' . 'Please wait and try again later.', $message ); } } /** * @magentoConfigFixture twofactorauth/general/force_providers duo_security * @magentoApiDataFixture Magento/User/_files/user_with_custom_role.php * * @return void */ public function testUnavailableProvider(): void { $serviceInfo = $this->buildServiceInfo(); try { $this->_webApiCall( $serviceInfo, [ 'username' => 'customRoleUser', 'password' => \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD, 'otp' => 'foo' ] ); self::fail('Endpoint should have thrown an exception'); } catch (\Throwable $exception) { $response = json_decode($exception->getMessage(), true); if (json_last_error()) { $message = $exception->getMessage(); } else { $message = $response['message']; } self::assertSame('Provider is not allowed.', $message); } } /** * @magentoConfigFixture twofactorauth/general/force_providers google * @magentoApiDataFixture Magento/User/_files/user_with_custom_role.php * * @return void */ public function testInvalidToken(): void { $userId = $this->getUserId(); $serviceInfo = $this->buildServiceInfo(); $this->tfa->getProviderByCode(Google::CODE) ->activate($userId); try { $this->_webApiCall( $serviceInfo, [ 'username' => 'customRoleUser', 'password' => \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD, 'otp' => 'bad' ] ); self::fail('Endpoint should have thrown an exception'); } catch (\Throwable $exception) { $response = json_decode($exception->getMessage(), true); if (json_last_error()) { $message = $exception->getMessage(); } else { $message = $response['message']; } self::assertSame('Invalid code.', $message); } } /** * @magentoConfigFixture twofactorauth/general/force_providers google * @magentoApiDataFixture Magento/User/_files/user_with_custom_role.php * * @return void */ public function testNotConfiguredProvider(): void { $userId = $this->getUserId(); $serviceInfo = $this->buildServiceInfo(); $this->tfa->getProviderByCode(Google::CODE) ->resetConfiguration($userId); try { $this->_webApiCall( $serviceInfo, [ 'username' => 'customRoleUser', 'password' => \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD, 'otp' => 'foo' ] ); self::fail('Endpoint should have thrown an exception'); } catch (\Throwable $exception) { $response = json_decode($exception->getMessage(), true); if (json_last_error()) { $message = $exception->getMessage(); } else { $message = $response['message']; } self::assertSame('Provider is not configured.', $message); } } /** * @magentoConfigFixture twofactorauth/general/force_providers google * @magentoApiDataFixture Magento/User/_files/user_with_custom_role.php * @magentoConfigFixture twofactorauth/google/otp_window 120 * * @return void */ public function testValidToken(): void { $userId = $this->getUserId(); $otp = $this->getUserOtp(); $serviceInfo = $this->buildServiceInfo(); $this->tfa->getProviderByCode(Google::CODE) ->activate($userId); $response = $this->_webApiCall( $serviceInfo, [ 'username' => 'customRoleUser', 'password' => \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD, 'otp' => $otp ] ); self::assertNotEmpty($response); self::assertMatchesRegularExpression('/^[a-z0-9]{32}$/', $response); } /** * @magentoConfigFixture default/oauth/access_token_lifetime/admin 1 * @magentoConfigFixture twofactorauth/general/force_providers google * * @magentoApiDataFixture Magento/Webapi/_files/webapi_user.php * @magentoApiDataFixture Magento/Customer/_files/customer.php * * @return void */ public function testAdminTokenLifetime(): void { $this->_markTestAsRestOnly(); $this->tfa->getProviderByCode(Google::CODE)->activate($this->getUserId('webapi_user')); $otp = $this->getUserOtp('webapi_user'); $serviceInfo = $this->buildServiceInfo(); $requestData = [ 'otp' => $otp, 'username' => 'webapi_user', 'password' => \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD, ]; $accessToken = $this->_webApiCall($serviceInfo, $requestData); $result = $this->doCustomerRequest($accessToken, 1); $this->assertContains('[email protected]', $this->json->unserialize($result)); $this->updateTokenCreatedTime($accessToken); $result = $this->doCustomerRequest($accessToken, 1); $this->assertContains( 'The consumer isn\'t authorized to access %resources.', $this->json->unserialize($result) ); } /** * @return array */ private function buildServiceInfo(): array { return [ 'rest' => [ // Ensure the default auth is invalidated 'token' => 'invalid', 'resourcePath' => self::RESOURCE_PATH, 'httpMethod' => Request::HTTP_METHOD_POST ], 'soap' => [ // Ensure the default auth is invalidated 'token' => 'invalid', 'service' => self::SERVICE_NAME, 'serviceVersion' => self::SERVICE_VERSION, 'operation' => self::SERVICE_NAME . self::OPERATION ] ]; } /** * Get user id * * @param string $userName * @return int */ private function getUserId($userName = 'customRoleUser'): int { $user = $this->userFactory->create(); $user->loadByUsername($userName); return (int)$user->getId(); } /** * Get user otp * * @param string $userName * @return string */ private function getUserOtp($userName = 'customRoleUser'): string { $user = $this->userFactory->create(); $user->loadByUsername($userName); $totp = TOTP::create($this->google->getSecretCode($user)); return $totp->now(); } /** * Perform request to customers endpoint * * @param string $accessToken * @return string */ private function doCustomerRequest(string $accessToken, $customerId): string { $this->client->addHeader('Authorization', 'Bearer ' . $accessToken); $this->client->get($this->url->getBaseUrl() . 'rest/V1/customers/' . $customerId); return $this->client->getBody(); } /** * Update token created time * * @param string $accessToken * @return void */ private function updateTokenCreatedTime(string $accessToken): void { $token = $this->tokenFactory->create(); $token->loadByToken($accessToken); $createdAt = (new \DateTime('-1 day'))->format('Y-m-d H:i:s'); $token->setCreatedAt($createdAt); $this->tokenResource->save($token); } }