mirror of
				https://github.com/elyby/accounts.git
				synced 2025-05-31 14:11:46 +05:30 
			
		
		
		
	Протестирована логика подписи access_token и refresh_token, добавлены базовые скоупы, подчищен проект
This commit is contained in:
		@@ -18,4 +18,9 @@ class OauthRoute extends BasePage {
 | 
			
		||||
        $this->actor->sendPOST($this->getUrl($queryParams), $postParams);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function issueToken($postParams = []) {
 | 
			
		||||
        $this->route = ['oauth/issue-token'];
 | 
			
		||||
        $this->actor->sendPOST($this->getUrl(), $postParams);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										99
									
								
								tests/codeception/api/functional/OauthAccessTokenCest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								tests/codeception/api/functional/OauthAccessTokenCest.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,99 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace tests\codeception\api;
 | 
			
		||||
 | 
			
		||||
use Codeception\Scenario;
 | 
			
		||||
use tests\codeception\api\_pages\OauthRoute;
 | 
			
		||||
use tests\codeception\api\functional\_steps\OauthSteps;
 | 
			
		||||
use Yii;
 | 
			
		||||
 | 
			
		||||
class OauthAccessTokenCest {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var OauthRoute
 | 
			
		||||
     */
 | 
			
		||||
    private $route;
 | 
			
		||||
 | 
			
		||||
    public function _before(FunctionalTester $I) {
 | 
			
		||||
        $this->route = new OauthRoute($I);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testIssueTokenWithWrongArgs(FunctionalTester $I) {
 | 
			
		||||
        $I->wantTo('check behavior on on request without any credentials');
 | 
			
		||||
        $this->route->issueToken();
 | 
			
		||||
        $I->canSeeResponseCodeIs(400);
 | 
			
		||||
        $I->canSeeResponseContainsJson([
 | 
			
		||||
            'error' => 'invalid_request',
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        $I->wantTo('check behavior on passing invalid auth code');
 | 
			
		||||
        $this->route->issueToken($this->buildParams(
 | 
			
		||||
            'wrong-auth-code',
 | 
			
		||||
            'ely',
 | 
			
		||||
            'ZuM1vGchJz-9_UZ5HC3H3Z9Hg5PzdbkM',
 | 
			
		||||
            'http://ely.by'
 | 
			
		||||
        ));
 | 
			
		||||
        $I->canSeeResponseCodeIs(400);
 | 
			
		||||
        $I->canSeeResponseContainsJson([
 | 
			
		||||
            'error' => 'invalid_request',
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testIssueToken(FunctionalTester $I, Scenario $scenario) {
 | 
			
		||||
        $I = new OauthSteps($scenario);
 | 
			
		||||
        $authCode = $I->getAuthCode();
 | 
			
		||||
        $this->route->issueToken($this->buildParams(
 | 
			
		||||
            $authCode,
 | 
			
		||||
            'ely',
 | 
			
		||||
            'ZuM1vGchJz-9_UZ5HC3H3Z9Hg5PzdbkM',
 | 
			
		||||
            'http://ely.by'
 | 
			
		||||
        ));
 | 
			
		||||
        $I->canSeeResponseCodeIs(200);
 | 
			
		||||
        $I->canSeeResponseIsJson();
 | 
			
		||||
        $I->canSeeResponseContainsJson([
 | 
			
		||||
            'token_type' => 'Bearer',
 | 
			
		||||
        ]);
 | 
			
		||||
        $I->canSeeResponseJsonMatchesJsonPath('$.access_token');
 | 
			
		||||
        $I->canSeeResponseJsonMatchesJsonPath('$.expires_in');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testIssueTokenWithRefreshToken(FunctionalTester $I, Scenario $scenario) {
 | 
			
		||||
        $I = new OauthSteps($scenario);
 | 
			
		||||
        $authCode = $I->getAuthCode(false);
 | 
			
		||||
        $this->route->issueToken($this->buildParams(
 | 
			
		||||
            $authCode,
 | 
			
		||||
            'ely',
 | 
			
		||||
            'ZuM1vGchJz-9_UZ5HC3H3Z9Hg5PzdbkM',
 | 
			
		||||
            'http://ely.by'
 | 
			
		||||
        ));
 | 
			
		||||
        $I->canSeeResponseCodeIs(200);
 | 
			
		||||
        $I->canSeeResponseIsJson();
 | 
			
		||||
        $I->canSeeResponseContainsJson([
 | 
			
		||||
            'token_type' => 'Bearer',
 | 
			
		||||
        ]);
 | 
			
		||||
        $I->canSeeResponseJsonMatchesJsonPath('$.access_token');
 | 
			
		||||
        $I->canSeeResponseJsonMatchesJsonPath('$.refresh_token');
 | 
			
		||||
        $I->canSeeResponseJsonMatchesJsonPath('$.expires_in');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function buildParams($code = null, $clientId = null, $clientSecret = null, $redirectUri = null) {
 | 
			
		||||
        $params = ['grant_type' => 'authorization_code'];
 | 
			
		||||
        if ($code !== null) {
 | 
			
		||||
            $params['code'] = $code;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($clientId !== null) {
 | 
			
		||||
            $params['client_id'] = $clientId;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($clientSecret !== null) {
 | 
			
		||||
            $params['client_secret'] = $clientSecret;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($redirectUri !== null) {
 | 
			
		||||
            $params['redirect_uri'] = $redirectUri;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $params;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -3,8 +3,9 @@ namespace tests\codeception\api;
 | 
			
		||||
 | 
			
		||||
use tests\codeception\api\_pages\OauthRoute;
 | 
			
		||||
use tests\codeception\api\functional\_steps\AccountSteps;
 | 
			
		||||
use Yii;
 | 
			
		||||
 | 
			
		||||
class OauthCest {
 | 
			
		||||
class OauthAuthCodeCest {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var OauthRoute
 | 
			
		||||
							
								
								
									
										99
									
								
								tests/codeception/api/functional/OauthRefreshTokenCest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								tests/codeception/api/functional/OauthRefreshTokenCest.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,99 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace tests\codeception\api;
 | 
			
		||||
 | 
			
		||||
use Codeception\Scenario;
 | 
			
		||||
use common\models\OauthScope;
 | 
			
		||||
use tests\codeception\api\_pages\OauthRoute;
 | 
			
		||||
use tests\codeception\api\functional\_steps\OauthSteps;
 | 
			
		||||
use Yii;
 | 
			
		||||
 | 
			
		||||
class OauthRefreshTokenCest {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var OauthRoute
 | 
			
		||||
     */
 | 
			
		||||
    private $route;
 | 
			
		||||
 | 
			
		||||
    public function _before(FunctionalTester $I) {
 | 
			
		||||
        $this->route = new OauthRoute($I);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testRefreshToken(FunctionalTester $I, Scenario $scenario) {
 | 
			
		||||
        $I = new OauthSteps($scenario);
 | 
			
		||||
        $refreshToken = $I->getRefreshToken();
 | 
			
		||||
        $this->route->issueToken($this->buildParams(
 | 
			
		||||
            $refreshToken,
 | 
			
		||||
            'ely',
 | 
			
		||||
            'ZuM1vGchJz-9_UZ5HC3H3Z9Hg5PzdbkM'
 | 
			
		||||
        ));
 | 
			
		||||
        $I->canSeeResponseCodeIs(200);
 | 
			
		||||
        $I->canSeeResponseIsJson();
 | 
			
		||||
        $I->canSeeResponseContainsJson([
 | 
			
		||||
            'token_type' => 'Bearer',
 | 
			
		||||
        ]);
 | 
			
		||||
        $I->canSeeResponseJsonMatchesJsonPath('$.access_token');
 | 
			
		||||
        $I->canSeeResponseJsonMatchesJsonPath('$.refresh_token');
 | 
			
		||||
        $I->canSeeResponseJsonMatchesJsonPath('$.expires_in');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testRefreshTokenWithSameScopes(FunctionalTester $I, Scenario $scenario) {
 | 
			
		||||
        $I = new OauthSteps($scenario);
 | 
			
		||||
        $refreshToken = $I->getRefreshToken();
 | 
			
		||||
        $this->route->issueToken($this->buildParams(
 | 
			
		||||
            $refreshToken,
 | 
			
		||||
            'ely',
 | 
			
		||||
            'ZuM1vGchJz-9_UZ5HC3H3Z9Hg5PzdbkM',
 | 
			
		||||
            [OauthScope::MINECRAFT_SERVER_SESSION, OauthScope::OFFLINE_ACCESS]
 | 
			
		||||
        ));
 | 
			
		||||
        $I->canSeeResponseCodeIs(200);
 | 
			
		||||
        $I->canSeeResponseIsJson();
 | 
			
		||||
        $I->canSeeResponseContainsJson([
 | 
			
		||||
            'token_type' => 'Bearer',
 | 
			
		||||
        ]);
 | 
			
		||||
        $I->canSeeResponseJsonMatchesJsonPath('$.access_token');
 | 
			
		||||
        $I->canSeeResponseJsonMatchesJsonPath('$.refresh_token');
 | 
			
		||||
        $I->canSeeResponseJsonMatchesJsonPath('$.expires_in');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testRefreshTokenWithNewScopes(FunctionalTester $I, Scenario $scenario) {
 | 
			
		||||
        $I = new OauthSteps($scenario);
 | 
			
		||||
        $refreshToken = $I->getRefreshToken();
 | 
			
		||||
        $this->route->issueToken($this->buildParams(
 | 
			
		||||
            $refreshToken,
 | 
			
		||||
            'ely',
 | 
			
		||||
            'ZuM1vGchJz-9_UZ5HC3H3Z9Hg5PzdbkM',
 | 
			
		||||
            [OauthScope::MINECRAFT_SERVER_SESSION, OauthScope::OFFLINE_ACCESS, 'change_skin']
 | 
			
		||||
        ));
 | 
			
		||||
        $I->canSeeResponseCodeIs(400);
 | 
			
		||||
        $I->canSeeResponseIsJson();
 | 
			
		||||
        $I->canSeeResponseContainsJson([
 | 
			
		||||
            'error' => 'invalid_scope',
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function buildParams($refreshToken = null, $clientId = null, $clientSecret = null, $scopes = []) {
 | 
			
		||||
        $params = ['grant_type' => 'refresh_token'];
 | 
			
		||||
        if ($refreshToken !== null) {
 | 
			
		||||
            $params['refresh_token'] = $refreshToken;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($clientId !== null) {
 | 
			
		||||
            $params['client_id'] = $clientId;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($clientSecret !== null) {
 | 
			
		||||
            $params['client_secret'] = $clientSecret;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!empty($scopes)) {
 | 
			
		||||
            if (is_array($scopes)) {
 | 
			
		||||
                $scopes = implode(',', $scopes);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $params['scope'] = $scopes;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $params;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								tests/codeception/api/functional/_steps/OauthSteps.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								tests/codeception/api/functional/_steps/OauthSteps.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace tests\codeception\api\functional\_steps;
 | 
			
		||||
 | 
			
		||||
use tests\codeception\api\_pages\OauthRoute;
 | 
			
		||||
 | 
			
		||||
class OauthSteps extends AccountSteps {
 | 
			
		||||
 | 
			
		||||
    public function getAuthCode($online = true) {
 | 
			
		||||
        // TODO: по идее можно напрямую сделать зпись в базу, что ускорит процесс тестирования
 | 
			
		||||
        $this->loggedInAsActiveAccount();
 | 
			
		||||
        $route = new OauthRoute($this);
 | 
			
		||||
        $route->complete([
 | 
			
		||||
            'client_id' => 'ely',
 | 
			
		||||
            'redirect_uri' => 'http://ely.by',
 | 
			
		||||
            'response_type' => 'code',
 | 
			
		||||
            'scope' => 'minecraft_server_session' . ($online ? '' : ',offline_access'),
 | 
			
		||||
        ], ['accept' => true]);
 | 
			
		||||
        $this->canSeeResponseJsonMatchesJsonPath('$.redirectUri');
 | 
			
		||||
        $response = json_decode($this->grabResponse(), true);
 | 
			
		||||
        preg_match('/code=(\w+)/', $response['redirectUri'], $matches);
 | 
			
		||||
 | 
			
		||||
        return $matches[1];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getRefreshToken() {
 | 
			
		||||
        // TODO: по идее можно напрямую сделать зпись в базу, что ускорит процесс тестирования
 | 
			
		||||
        $authCode = $this->getAuthCode(false);
 | 
			
		||||
        $route = new OauthRoute($this);
 | 
			
		||||
        $route->issueToken([
 | 
			
		||||
            'code' => $authCode,
 | 
			
		||||
            'client_id' => 'ely',
 | 
			
		||||
            'client_secret' => 'ZuM1vGchJz-9_UZ5HC3H3Z9Hg5PzdbkM',
 | 
			
		||||
            'redirect_uri' => 'http://ely.by',
 | 
			
		||||
            'grant_type' => 'authorization_code',
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        $response = json_decode($this->grabResponse(), true);
 | 
			
		||||
 | 
			
		||||
        return $response['refresh_token'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user