diff --git a/composer.json b/composer.json index 689fbe4..2734f1e 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "yiisoft/yii2": "2.0.10", "yiisoft/yii2-swiftmailer": "*", "ramsey/uuid": "^3.5.0", - "league/oauth2-server": "dev-improvements#b9277ccd664dcb80a766b73674d21de686cb9dda", + "league/oauth2-server": "dev-improvements#fbaa9b0bd3d8050235ba7dde90f731764122bc20", "yiisoft/yii2-redis": "~2.0.0", "guzzlehttp/guzzle": "^6.0.0", "php-amqplib/php-amqplib": "^2.6.2", diff --git a/tests/codeception/api/functional/OauthClientCredentialsGrantCest.php b/tests/codeception/api/functional/OauthClientCredentialsGrantCest.php new file mode 100644 index 0000000..e27ccbb --- /dev/null +++ b/tests/codeception/api/functional/OauthClientCredentialsGrantCest.php @@ -0,0 +1,120 @@ +route = new OauthRoute($I); + } + + public function testIssueTokenWithWrongArgs(FunctionalTester $I) { + $I->wantTo('check behavior on on request without any credentials'); + $this->route->issueToken($this->buildParams()); + $I->canSeeResponseCodeIs(400); + $I->canSeeResponseContainsJson([ + 'error' => 'invalid_request', + ]); + + $I->wantTo('check behavior on passing invalid client_id'); + $this->route->issueToken($this->buildParams( + 'invalid-client', + 'invalid-secret', + ['invalid-scope'] + )); + $I->canSeeResponseCodeIs(401); + $I->canSeeResponseContainsJson([ + 'error' => 'invalid_client', + ]); + + $I->wantTo('check behavior on passing invalid client_secret'); + $this->route->issueToken($this->buildParams( + 'ely', + 'invalid-secret', + ['invalid-scope'] + )); + $I->canSeeResponseCodeIs(401); + $I->canSeeResponseContainsJson([ + 'error' => 'invalid_client', + ]); + + $I->wantTo('check behavior on passing invalid client_secret'); + $this->route->issueToken($this->buildParams( + 'ely', + 'invalid-secret', + ['invalid-scope'] + )); + $I->canSeeResponseCodeIs(401); + $I->canSeeResponseContainsJson([ + 'error' => 'invalid_client', + ]); + } + + public function testIssueTokenWithPublicScopes(OauthSteps $I) { + // TODO: у нас пока нет публичных скоупов, поэтому тест прогоняется с пустым набором + $this->route->issueToken($this->buildParams( + 'ely', + 'ZuM1vGchJz-9_UZ5HC3H3Z9Hg5PzdbkM', + [] + )); + $I->canSeeResponseCodeIs(200); + $I->canSeeResponseIsJson(); + $I->canSeeResponseContainsJson([ + 'token_type' => 'Bearer', + ]); + $I->canSeeResponseJsonMatchesJsonPath('$.access_token'); + $I->canSeeResponseJsonMatchesJsonPath('$.expires_in'); + } + + public function testIssueTokenWithInternalScopes(OauthSteps $I) { + $this->route->issueToken($this->buildParams( + 'ely', + 'ZuM1vGchJz-9_UZ5HC3H3Z9Hg5PzdbkM', + [S::ACCOUNT_BLOCK] + )); + $I->canSeeResponseCodeIs(400); + $I->canSeeResponseIsJson(); + $I->canSeeResponseContainsJson([ + 'error' => 'invalid_scope', + ]); + + $this->route->issueToken($this->buildParams( + 'trusted-client', + 'tXBbyvMcyaOgHMOAXBpN2EC7uFoJAaL9', + [S::ACCOUNT_BLOCK] + )); + $I->canSeeResponseCodeIs(200); + $I->canSeeResponseIsJson(); + $I->canSeeResponseContainsJson([ + 'token_type' => 'Bearer', + ]); + $I->canSeeResponseJsonMatchesJsonPath('$.access_token'); + $I->canSeeResponseJsonMatchesJsonPath('$.expires_in'); + } + + private function buildParams($clientId = null, $clientSecret = null, array $scopes = null) { + $params = ['grant_type' => 'client_credentials']; + if ($clientId !== null) { + $params['client_id'] = $clientId; + } + + if ($clientSecret !== null) { + $params['client_secret'] = $clientSecret; + } + + if ($scopes !== null) { + $params['scope'] = implode(',', $scopes); + } + + return $params; + } + +}