mirror of
				https://github.com/elyby/accounts.git
				synced 2025-05-31 14:11:46 +05:30 
			
		
		
		
	Add tests for the legacy tokens
This commit is contained in:
		| @@ -14,7 +14,7 @@ use Yii; | ||||
| class RefreshTokenGrant extends BaseRefreshTokenGrant { | ||||
|  | ||||
|     /** | ||||
|      * Previously, refresh tokens was stored in Redis. | ||||
|      * Previously, refresh tokens were stored in Redis. | ||||
|      * If received refresh token is matches the legacy token template, | ||||
|      * restore the information from the legacy storage. | ||||
|      * | ||||
|   | ||||
| @@ -32,7 +32,7 @@ class LegacyOAuth2Identity implements IdentityInterface { | ||||
|      */ | ||||
|     private $session = false; | ||||
|  | ||||
|     private function __construct(string $accessToken, string $sessionId, array $scopes) { | ||||
|     private function __construct(string $accessToken, int $sessionId, array $scopes) { | ||||
|         $this->accessToken = $accessToken; | ||||
|         $this->sessionId = $sessionId; | ||||
|         $this->scopes = $scopes; | ||||
|   | ||||
| @@ -17,4 +17,4 @@ modules: | ||||
|         host: redis | ||||
|         port: 6379 | ||||
|         database: 0 | ||||
|         cleanupBefore: 'test' | ||||
|         cleanupBefore: 'suite' | ||||
|   | ||||
| @@ -4,6 +4,7 @@ declare(strict_types=1); | ||||
| namespace api\tests\functional\oauth; | ||||
|  | ||||
| use api\tests\functional\_steps\OauthSteps; | ||||
| use api\tests\FunctionalTester; | ||||
|  | ||||
| class RefreshTokenCest { | ||||
|  | ||||
| @@ -53,6 +54,18 @@ class RefreshTokenCest { | ||||
|         $this->canSeeRefreshTokenSuccess($I); | ||||
|     } | ||||
|  | ||||
|     public function refreshTokenUsingLegacyToken(FunctionalTester $I) { | ||||
|         $I->wantTo('refresh token using the legacy token'); | ||||
|         $I->sendPOST('/api/oauth2/v1/token', [ | ||||
|             'grant_type' => 'refresh_token', | ||||
|             'refresh_token' => 'op7kPGAgHlsXRBJtkFg7wKOTpodvtHVW5NxR7Tjr', | ||||
|             'client_id' => 'test1', | ||||
|             'client_secret' => 'eEvrKHF47sqiaX94HsX-xXzdGiz3mcsq', | ||||
|             'scope' => 'minecraft_server_session account_info', | ||||
|         ]); | ||||
|         $this->canSeeRefreshTokenSuccess($I); | ||||
|     } | ||||
|  | ||||
|     public function passInvalidRefreshToken(OauthSteps $I) { | ||||
|         $I->wantToTest('behaviour of the server when invalid refresh token passed'); | ||||
|         $I->sendPOST('/api/oauth2/v1/token', [ | ||||
| @@ -85,7 +98,7 @@ class RefreshTokenCest { | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     private function canSeeRefreshTokenSuccess(OauthSteps $I) { | ||||
|     private function canSeeRefreshTokenSuccess(FunctionalTester $I) { | ||||
|         $I->canSeeResponseCodeIs(200); | ||||
|         $I->canSeeResponseContainsJson([ | ||||
|             'token_type' => 'Bearer', | ||||
|   | ||||
| @@ -3,40 +3,30 @@ declare(strict_types=1); | ||||
|  | ||||
| namespace api\tests\unit\components\User; | ||||
|  | ||||
| use api\components\OAuth2\Component; | ||||
| use api\components\OAuth2\Entities\AccessTokenEntity; | ||||
| use api\components\User\IdentityFactory; | ||||
| use api\components\User\JwtIdentity; | ||||
| use api\components\User\LegacyOAuth2Identity; | ||||
| use api\tests\unit\TestCase; | ||||
| use Carbon\Carbon; | ||||
| use League\OAuth2\Server\AbstractServer; | ||||
| use League\OAuth2\Server\Storage\AccessTokenInterface; | ||||
| use Yii; | ||||
| use common\tests\fixtures; | ||||
| use yii\web\UnauthorizedHttpException; | ||||
|  | ||||
| class IdentityFactoryTest extends TestCase { | ||||
|  | ||||
|     public function _fixtures(): array { | ||||
|         return [ | ||||
|             fixtures\LegacyOauthAccessTokenFixture::class, | ||||
|             fixtures\LegacyOauthAccessTokenScopeFixture::class, | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     public function testFindIdentityByAccessToken() { | ||||
|         // Find identity by jwt token | ||||
|         // Find identity by the JWT | ||||
|         $identity = IdentityFactory::findIdentityByAccessToken('eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJlbHktc2NvcGVzIjoiYWNjb3VudHNfd2ViX3VzZXIiLCJpYXQiOjE1NjQ2MTA1NDIsImV4cCI6MTU2NDYxNDE0Miwic3ViIjoiZWx5fDEifQ.4Oidvuo4spvUf9hkpHR72eeqZUh2Zbxh_L8Od3vcgTj--0iOrcOEp6zwmEW6vF7BTHtjz2b3mXce61bqsCjXjQ'); | ||||
|         $this->assertInstanceOf(JwtIdentity::class, $identity); | ||||
|  | ||||
|         // Find identity by oauth2 token | ||||
|         $accessToken = new AccessTokenEntity(mock(AbstractServer::class)); | ||||
|         $accessToken->setExpireTime(time() + 3600); | ||||
|         $accessToken->setId('mock-token'); | ||||
|  | ||||
|         /** @var AccessTokenInterface|\Mockery\MockInterface $accessTokensStorage */ | ||||
|         $accessTokensStorage = mock(AccessTokenInterface::class); | ||||
|         $accessTokensStorage->shouldReceive('get')->with('mock-token')->andReturn($accessToken); | ||||
|  | ||||
|         /** @var Component|\Mockery\MockInterface $component */ | ||||
|         $component = mock(Component::class); | ||||
|         $component->shouldReceive('getAccessTokenStorage')->andReturn($accessTokensStorage); | ||||
|         Yii::$app->set('oauth', $component); | ||||
|  | ||||
|         $identity = IdentityFactory::findIdentityByAccessToken('mock-token'); | ||||
|         // Find identity by the legacy OAuth2 token | ||||
|         $identity = IdentityFactory::findIdentityByAccessToken('ZZQP8sS9urzriy8N9h6FwFNMOH3PkZ5T5PLqS6SX'); | ||||
|         $this->assertInstanceOf(LegacyOAuth2Identity::class, $identity); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -3,52 +3,37 @@ declare(strict_types=1); | ||||
|  | ||||
| namespace api\tests\unit\components\User; | ||||
|  | ||||
| use api\components\OAuth2\Component; | ||||
| use api\components\OAuth2\Entities\AccessTokenEntity; | ||||
| use api\components\User\LegacyOAuth2Identity; | ||||
| use api\tests\unit\TestCase; | ||||
| use Yii; | ||||
| use common\tests\fixtures; | ||||
| use yii\web\UnauthorizedHttpException; | ||||
|  | ||||
| class LegacyOAuth2IdentityTest extends TestCase { | ||||
|  | ||||
|     public function testFindIdentityByAccessToken() { | ||||
|         $accessToken = new AccessTokenEntity(mock(AbstractServer::class)); | ||||
|         $accessToken->setExpireTime(time() + 3600); | ||||
|         $accessToken->setId('mock-token'); | ||||
|         $this->mockFoundedAccessToken($accessToken); | ||||
|     public function _fixtures(): array { | ||||
|         return [ | ||||
|             fixtures\LegacyOauthAccessTokenFixture::class, | ||||
|             fixtures\LegacyOauthAccessTokenScopeFixture::class, | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|         $identity = LegacyOAuth2Identity::findIdentityByAccessToken('mock-token'); | ||||
|         $this->assertSame('mock-token', $identity->getId()); | ||||
|     public function testFindIdentityByAccessToken() { | ||||
|         $identity = LegacyOAuth2Identity::findIdentityByAccessToken('ZZQP8sS9urzriy8N9h6FwFNMOH3PkZ5T5PLqS6SX'); | ||||
|         $this->assertSame('ZZQP8sS9urzriy8N9h6FwFNMOH3PkZ5T5PLqS6SX', $identity->getId()); | ||||
|     } | ||||
|  | ||||
|     public function testFindIdentityByAccessTokenWithNonExistsToken() { | ||||
|         $this->expectException(UnauthorizedHttpException::class); | ||||
|         $this->expectExceptionMessage('Incorrect token'); | ||||
|  | ||||
|         LegacyOAuth2Identity::findIdentityByAccessToken('not exists token'); | ||||
|         LegacyOAuth2Identity::findIdentityByAccessToken('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'); | ||||
|     } | ||||
|  | ||||
|     public function testFindIdentityByAccessTokenWithExpiredToken() { | ||||
|         $this->expectException(UnauthorizedHttpException::class); | ||||
|         $this->expectExceptionMessage('Token expired'); | ||||
|  | ||||
|         $accessToken = new AccessTokenEntity(mock(AbstractServer::class)); | ||||
|         $accessToken->setExpireTime(time() - 3600); | ||||
|         $this->mockFoundedAccessToken($accessToken); | ||||
|  | ||||
|         LegacyOAuth2Identity::findIdentityByAccessToken('mock-token'); | ||||
|     } | ||||
|  | ||||
|     private function mockFoundedAccessToken(AccessTokenEntity $accessToken) { | ||||
|         /** @var AccessTokenInterface|\Mockery\MockInterface $accessTokensStorage */ | ||||
|         $accessTokensStorage = mock(AccessTokenInterface::class); | ||||
|         $accessTokensStorage->shouldReceive('get')->with('mock-token')->andReturn($accessToken); | ||||
|  | ||||
|         /** @var Component|\Mockery\MockInterface $component */ | ||||
|         $component = mock(Component::class); | ||||
|         $component->shouldReceive('getAccessTokenStorage')->andReturn($accessTokensStorage); | ||||
|         Yii::$app->set('oauth', $component); | ||||
|         LegacyOAuth2Identity::findIdentityByAccessToken('rc0sOF1SLdOxuD3bJcCQENmGTeYrGgy12qJScMx4'); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -52,7 +52,11 @@ class FixtureHelper extends Module { | ||||
|             'usernamesHistory' => fixtures\UsernameHistoryFixture::class, | ||||
|             'oauthClients' => fixtures\OauthClientFixture::class, | ||||
|             'oauthSessions' => fixtures\OauthSessionFixture::class, | ||||
|             'legacyOauthSessionsScopes' => fixtures\LegacyOauthSessionScopeFixtures::class, | ||||
|             'legacyOauthAccessTokens' => fixtures\LegacyOauthAccessTokenFixture::class, | ||||
|             'legacyOauthAccessTokensScopes' => fixtures\LegacyOauthAccessTokenScopeFixture::class, | ||||
|             'oauthRefreshTokens' => fixtures\OauthRefreshTokensFixture::class, | ||||
|             'legacyOauthRefreshTokens' => fixtures\LegacyOauthRefreshTokenFixture::class, | ||||
|             'minecraftAccessKeys' => fixtures\MinecraftAccessKeyFixture::class, | ||||
|         ]; | ||||
|     } | ||||
|   | ||||
							
								
								
									
										82
									
								
								common/tests/_support/Redis/Fixture.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								common/tests/_support/Redis/Fixture.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace common\tests\_support\Redis; | ||||
|  | ||||
| use InvalidArgumentException; | ||||
| use yii\base\ArrayAccessTrait; | ||||
| use yii\di\Instance; | ||||
| use yii\helpers\ArrayHelper; | ||||
| use yii\helpers\Json; | ||||
| use yii\redis\Connection; | ||||
| use yii\test\FileFixtureTrait; | ||||
| use yii\test\Fixture as BaseFixture; | ||||
|  | ||||
| class Fixture extends BaseFixture { | ||||
|     use ArrayAccessTrait; | ||||
|     use FileFixtureTrait; | ||||
|  | ||||
|     /** | ||||
|      * @var Connection | ||||
|      */ | ||||
|     public $redis = 'redis'; | ||||
|  | ||||
|     public $keysPrefix = ''; | ||||
|  | ||||
|     public $keysPostfix = ''; | ||||
|  | ||||
|     public $data = []; | ||||
|  | ||||
|     public function init() { | ||||
|         parent::init(); | ||||
|         $this->redis = Instance::ensure($this->redis, Connection::class); | ||||
|     } | ||||
|  | ||||
|     public function load() { | ||||
|         $this->data = []; | ||||
|         foreach ($this->getData() as $key => $data) { | ||||
|             $key = $this->buildKey($key); | ||||
|             $preparedData = $this->prepareData($data); | ||||
|             if (is_array($preparedData)) { | ||||
|                 $this->redis->sadd($key, ...$preparedData); | ||||
|             } else { | ||||
|                 $this->redis->set($key, $preparedData); | ||||
|             } | ||||
|  | ||||
|             $this->data[$key] = $data; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function unload() { | ||||
|         $this->redis->flushdb(); | ||||
|     } | ||||
|  | ||||
|     protected function getData(): array { | ||||
|         return $this->loadData($this->dataFile); | ||||
|     } | ||||
|  | ||||
|     protected function prepareData($input) { | ||||
|         if (is_string($input)) { | ||||
|             return $input; | ||||
|         } | ||||
|  | ||||
|         if (is_int($input) || is_bool($input)) { | ||||
|             return (string)$input; | ||||
|         } | ||||
|  | ||||
|         if (is_array($input)) { | ||||
|             if (!ArrayHelper::isAssociative($input)) { | ||||
|                 return $input; | ||||
|             } | ||||
|  | ||||
|             return Json::encode($input); | ||||
|         } | ||||
|  | ||||
|         throw new InvalidArgumentException('Unsupported input type'); | ||||
|     } | ||||
|  | ||||
|     protected function buildKey($key): string { | ||||
|         return $this->keysPrefix . $key . $this->keysPostfix; | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										14
									
								
								common/tests/fixtures/LegacyOauthAccessTokenFixture.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								common/tests/fixtures/LegacyOauthAccessTokenFixture.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace common\tests\fixtures; | ||||
|  | ||||
| use common\tests\_support\Redis\Fixture; | ||||
|  | ||||
| class LegacyOauthAccessTokenFixture extends Fixture { | ||||
|  | ||||
|     public $dataFile = '@root/common/tests/fixtures/data/legacy-oauth-access-tokens.php'; | ||||
|  | ||||
|     public $keysPrefix = 'oauth:access:tokens:'; | ||||
|  | ||||
| } | ||||
							
								
								
									
										16
									
								
								common/tests/fixtures/LegacyOauthAccessTokenScopeFixture.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								common/tests/fixtures/LegacyOauthAccessTokenScopeFixture.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace common\tests\fixtures; | ||||
|  | ||||
| use common\tests\_support\Redis\Fixture; | ||||
|  | ||||
| class LegacyOauthAccessTokenScopeFixture extends Fixture { | ||||
|  | ||||
|     public $dataFile = '@root/common/tests/fixtures/data/legacy-oauth-access-tokens-scopes.php'; | ||||
|  | ||||
|     public $keysPrefix = 'oauth:access:tokens:'; | ||||
|  | ||||
|     public $keysPostfix = ':scopes'; | ||||
|  | ||||
| } | ||||
							
								
								
									
										14
									
								
								common/tests/fixtures/LegacyOauthRefreshTokenFixture.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								common/tests/fixtures/LegacyOauthRefreshTokenFixture.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace common\tests\fixtures; | ||||
|  | ||||
| use common\tests\_support\Redis\Fixture; | ||||
|  | ||||
| class LegacyOauthRefreshTokenFixture extends Fixture { | ||||
|  | ||||
|     public $dataFile = '@root/common/tests/fixtures/data/legacy-oauth-refresh-tokens.php'; | ||||
|  | ||||
|     public $keysPrefix = 'oauth:refresh:tokens:'; | ||||
|  | ||||
| } | ||||
							
								
								
									
										16
									
								
								common/tests/fixtures/LegacyOauthSessionScopeFixtures.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								common/tests/fixtures/LegacyOauthSessionScopeFixtures.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace common\tests\fixtures; | ||||
|  | ||||
| use common\tests\_support\Redis\Fixture; | ||||
|  | ||||
| class LegacyOauthSessionScopeFixtures extends Fixture { | ||||
|  | ||||
|     public $dataFile = '@root/common/tests/fixtures/data/legacy-oauth-sessions-scopes.php'; | ||||
|  | ||||
|     public $keysPrefix = 'oauth:sessions:'; | ||||
|  | ||||
|     public $keysPostfix = ':scopes'; | ||||
|  | ||||
| } | ||||
							
								
								
									
										4
									
								
								common/tests/fixtures/data/legacy-oauth-access-tokens-scopes.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								common/tests/fixtures/data/legacy-oauth-access-tokens-scopes.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| <?php | ||||
| return [ | ||||
|     'ZZQP8sS9urzriy8N9h6FwFNMOH3PkZ5T5PLqS6SX' => ['minecraft_server_session', 'obtain_own_account_info'], | ||||
| ]; | ||||
							
								
								
									
										16
									
								
								common/tests/fixtures/data/legacy-oauth-access-tokens.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								common/tests/fixtures/data/legacy-oauth-access-tokens.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| <?php | ||||
|  | ||||
| use Carbon\Carbon; | ||||
|  | ||||
| return [ | ||||
|     'ZZQP8sS9urzriy8N9h6FwFNMOH3PkZ5T5PLqS6SX' => [ | ||||
|         'id' => 'ZZQP8sS9urzriy8N9h6FwFNMOH3PkZ5T5PLqS6SX', | ||||
|         'session_id' => 1, | ||||
|         'expire_time' => Carbon::now()->addHour()->getTimestamp(), | ||||
|     ], | ||||
|     'rc0sOF1SLdOxuD3bJcCQENmGTeYrGgy12qJScMx4' => [ | ||||
|         'id' => 'rc0sOF1SLdOxuD3bJcCQENmGTeYrGgy12qJScMx4', | ||||
|         'session_id' => 1, | ||||
|         'expire_time' => Carbon::now()->subHour()->getTimestamp(), | ||||
|     ], | ||||
| ]; | ||||
							
								
								
									
										8
									
								
								common/tests/fixtures/data/legacy-oauth-refresh-tokens.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								common/tests/fixtures/data/legacy-oauth-refresh-tokens.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| <?php | ||||
| return [ | ||||
|     'op7kPGAgHlsXRBJtkFg7wKOTpodvtHVW5NxR7Tjr' => [ | ||||
|         'id' => 'op7kPGAgHlsXRBJtkFg7wKOTpodvtHVW5NxR7Tjr', | ||||
|         'access_token_id' => 'cynbpR53GK5HyvHuTtriHP7JpdqvFaYnWSS1twXX', | ||||
|         'session_id' => 1, | ||||
|     ], | ||||
| ]; | ||||
							
								
								
									
										4
									
								
								common/tests/fixtures/data/legacy-oauth-sessions-scopes.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								common/tests/fixtures/data/legacy-oauth-sessions-scopes.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| <?php | ||||
| return [ | ||||
|     1 => ['minecraft_server_session', 'obtain_own_account_info'], | ||||
| ]; | ||||
| @@ -3,24 +3,28 @@ return [ | ||||
|     'admin-test1' => [ | ||||
|         'account_id' => 1, | ||||
|         'client_id' => 'test1', | ||||
|         'legacy_id' => 1, | ||||
|         'scopes' => null, | ||||
|         'created_at' => 1479944472, | ||||
|     ], | ||||
|     'banned-account-session' => [ | ||||
|         'account_id' => 10, | ||||
|         'client_id' => 'test1', | ||||
|         'legacy_id' => 2, | ||||
|         'scopes' => null, | ||||
|         'created_at' => 1481421663, | ||||
|     ], | ||||
|     'deleted-client-session' => [ | ||||
|         'account_id' => 1, | ||||
|         'client_id' => 'deleted-oauth-client-with-sessions', | ||||
|         'legacy_id' => 3, | ||||
|         'scopes' => null, | ||||
|         'created_at' => 1519510065, | ||||
|     ], | ||||
|     'actual-deleted-client-session' => [ | ||||
|         'account_id' => 2, | ||||
|         'client_id' => 'deleted-oauth-client-with-sessions', | ||||
|         'legacy_id' => 4, | ||||
|         'scopes' => null, | ||||
|         'created_at' => 1519511568, | ||||
|     ], | ||||
|   | ||||
		Reference in New Issue
	
	Block a user