From a48c1432c64eb59001f1f68708155ce1cf476dd1 Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Sat, 6 Aug 2016 16:36:24 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=BE?= =?UTF-8?q?=D0=BD=D0=B0=D0=BB=20=D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D0=B8=20=D0=BE=D0=B1=20=D0=B0=D0=BA=D0=BA=D0=B0=D1=83?= =?UTF-8?q?=D1=82=D0=B5=20=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=20=D0=B2=D1=8B?= =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F=20oAuth=20?= =?UTF-8?q?=D0=B0=D0=B2=D1=82=D0=BE=D1=80=D0=B8=D0=B7=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/components/ApiUser/AccessControl.php | 8 +++ api/components/ApiUser/Component.php | 6 +- api/config/routes.php | 2 + api/controllers/IdentityInfoController.php | 9 +-- common/models/OauthScope.php | 1 + .../m160803_185857_account_permissions.php | 18 +++++ ...m160803_185857_permission_email_access.php | 15 ----- .../api/_pages/IdentityInfoRoute.php | 16 +++++ .../api/functional/IdentityInfoCest.php | 66 +++++++++++++++++++ .../api/functional/OauthAccessTokenCest.php | 4 +- .../api/functional/OauthRefreshTokenCest.php | 11 ++-- .../api/functional/_steps/OauthSteps.php | 26 ++++++-- .../common/_support/FixtureHelper.php | 5 -- .../common/fixtures/OauthScopeFixture.php | 11 ---- .../common/fixtures/data/oauth-scopes.php | 12 ---- 15 files changed, 147 insertions(+), 63 deletions(-) create mode 100644 api/components/ApiUser/AccessControl.php create mode 100644 console/migrations/m160803_185857_account_permissions.php delete mode 100644 console/migrations/m160803_185857_permission_email_access.php create mode 100644 tests/codeception/api/_pages/IdentityInfoRoute.php create mode 100644 tests/codeception/api/functional/IdentityInfoCest.php delete mode 100644 tests/codeception/common/fixtures/OauthScopeFixture.php delete mode 100644 tests/codeception/common/fixtures/data/oauth-scopes.php diff --git a/api/components/ApiUser/AccessControl.php b/api/components/ApiUser/AccessControl.php new file mode 100644 index 0000000..b145828 --- /dev/null +++ b/api/components/ApiUser/AccessControl.php @@ -0,0 +1,8 @@ + 'accounts/change-email-confirm-new-email', '/oauth2/v1/' => 'oauth/', + + '/account/v1/info' => 'identity-info/index', ]; diff --git a/api/controllers/IdentityInfoController.php b/api/controllers/IdentityInfoController.php index dd56800..8dbf3ab 100644 --- a/api/controllers/IdentityInfoController.php +++ b/api/controllers/IdentityInfoController.php @@ -1,9 +1,9 @@ ['index'], 'allow' => true, - 'roles' => ['@'], + 'roles' => [S::ACCOUNT_INFO], ], ], ], @@ -28,12 +28,13 @@ class IdentityInfoController extends ApiController { $response = [ 'id' => $account->id, 'uuid' => $account->uuid, + 'username' => $account->username, 'registeredAt' => $account->created_at, 'profileLink' => $account->getProfileLink(), 'preferredLanguage' => $account->lang, ]; - if (Yii::$app->apiUser->can(OauthScope::ACCOUNT_EMAIL)) { + if (Yii::$app->apiUser->can(S::ACCOUNT_EMAIL)) { $response['email'] = $account->email; } diff --git a/common/models/OauthScope.php b/common/models/OauthScope.php index bb19198..ab392bf 100644 --- a/common/models/OauthScope.php +++ b/common/models/OauthScope.php @@ -11,6 +11,7 @@ class OauthScope extends ActiveRecord { const OFFLINE_ACCESS = 'offline_access'; const MINECRAFT_SERVER_SESSION = 'minecraft_server_session'; + const ACCOUNT_INFO = 'account_info'; const ACCOUNT_EMAIL = 'account_email'; public static function tableName() { diff --git a/console/migrations/m160803_185857_account_permissions.php b/console/migrations/m160803_185857_account_permissions.php new file mode 100644 index 0000000..734115c --- /dev/null +++ b/console/migrations/m160803_185857_account_permissions.php @@ -0,0 +1,18 @@ +batchInsert('{{%oauth_scopes}}', ['id'], [ + ['account_info'], + ['account_email'], + ]); + } + + public function safeDown() { + $this->delete('{{%oauth_scopes}}', ['id' => ['account_info', 'account_email']]); + } + +} diff --git a/console/migrations/m160803_185857_permission_email_access.php b/console/migrations/m160803_185857_permission_email_access.php deleted file mode 100644 index 5c2cbf1..0000000 --- a/console/migrations/m160803_185857_permission_email_access.php +++ /dev/null @@ -1,15 +0,0 @@ -insert('{{%oauth_scopes}}', ['id' => 'account_email']); - } - - public function safeDown() { - $this->delete('{{%oauth_scopes}}', ['id' => 'account_email']); - } - -} diff --git a/tests/codeception/api/_pages/IdentityInfoRoute.php b/tests/codeception/api/_pages/IdentityInfoRoute.php new file mode 100644 index 0000000..75cd984 --- /dev/null +++ b/tests/codeception/api/_pages/IdentityInfoRoute.php @@ -0,0 +1,16 @@ +route = ['identity-info/index']; + $this->actor->sendGET($this->getUrl()); + } + +} diff --git a/tests/codeception/api/functional/IdentityInfoCest.php b/tests/codeception/api/functional/IdentityInfoCest.php new file mode 100644 index 0000000..0050a32 --- /dev/null +++ b/tests/codeception/api/functional/IdentityInfoCest.php @@ -0,0 +1,66 @@ +route = new IdentityInfoRoute($I); + } + + public function testGetErrorIfNotEnoughPerms(OauthSteps $I) { + $accessToken = $I->getAccessToken(); + $I->amBearerAuthenticated($accessToken); + $this->route->info(); + $I->canSeeResponseCodeIs(403); + $I->canSeeResponseIsJson(); + $I->canSeeResponseContainsJson([ + 'name' => 'Forbidden', + 'status' => 403, + ]); + } + + public function testGetInfo(OauthSteps $I) { + $accessToken = $I->getAccessToken([S::ACCOUNT_INFO]); + $I->amBearerAuthenticated($accessToken); + $this->route->info(); + $I->canSeeResponseCodeIs(200); + $I->canSeeResponseIsJson(); + $I->canSeeResponseContainsJson([ + 'id' => 1, + 'uuid' => 'df936908-b2e1-544d-96f8-2977ec213022', + 'username' => 'Admin', + 'registeredAt' => 1451775316, + 'profileLink' => 'http://ely.by/u1', + 'preferredLanguage' => 'en', + ]); + $I->cantSeeResponseJsonMatchesJsonPath('$.email'); + } + + public function testGetInfoWithEmail(OauthSteps $I) { + $accessToken = $I->getAccessToken([S::ACCOUNT_INFO, S::ACCOUNT_EMAIL]); + $I->amBearerAuthenticated($accessToken); + $this->route->info(); + $I->canSeeResponseCodeIs(200); + $I->canSeeResponseIsJson(); + $I->canSeeResponseContainsJson([ + 'id' => 1, + 'uuid' => 'df936908-b2e1-544d-96f8-2977ec213022', + 'username' => 'Admin', + 'registeredAt' => 1451775316, + 'profileLink' => 'http://ely.by/u1', + 'preferredLanguage' => 'en', + 'email' => 'admin@ely.by', + ]); + } + +} diff --git a/tests/codeception/api/functional/OauthAccessTokenCest.php b/tests/codeception/api/functional/OauthAccessTokenCest.php index a2c1275..1ee1e4c 100644 --- a/tests/codeception/api/functional/OauthAccessTokenCest.php +++ b/tests/codeception/api/functional/OauthAccessTokenCest.php @@ -1,9 +1,9 @@ getAuthCode(false); + $authCode = $I->getAuthCode([S::OFFLINE_ACCESS]); $this->route->issueToken($this->buildParams( $authCode, 'ely', diff --git a/tests/codeception/api/functional/OauthRefreshTokenCest.php b/tests/codeception/api/functional/OauthRefreshTokenCest.php index 4c29bad..dc6307a 100644 --- a/tests/codeception/api/functional/OauthRefreshTokenCest.php +++ b/tests/codeception/api/functional/OauthRefreshTokenCest.php @@ -1,10 +1,9 @@ getRefreshToken(); + $refreshToken = $I->getRefreshToken([S::MINECRAFT_SERVER_SESSION]); $this->route->issueToken($this->buildParams( $refreshToken, 'ely', 'ZuM1vGchJz-9_UZ5HC3H3Z9Hg5PzdbkM', - [OauthScope::MINECRAFT_SERVER_SESSION, OauthScope::OFFLINE_ACCESS] + [S::MINECRAFT_SERVER_SESSION, S::OFFLINE_ACCESS] )); $I->canSeeResponseCodeIs(200); $I->canSeeResponseIsJson(); @@ -53,12 +52,12 @@ class OauthRefreshTokenCest { } public function testRefreshTokenWithNewScopes(OauthSteps $I) { - $refreshToken = $I->getRefreshToken(); + $refreshToken = $I->getRefreshToken([S::MINECRAFT_SERVER_SESSION]); $this->route->issueToken($this->buildParams( $refreshToken, 'ely', 'ZuM1vGchJz-9_UZ5HC3H3Z9Hg5PzdbkM', - [OauthScope::MINECRAFT_SERVER_SESSION, OauthScope::OFFLINE_ACCESS, 'change_skin'] + [S::MINECRAFT_SERVER_SESSION, S::OFFLINE_ACCESS, S::ACCOUNT_EMAIL] )); $I->canSeeResponseCodeIs(400); $I->canSeeResponseIsJson(); diff --git a/tests/codeception/api/functional/_steps/OauthSteps.php b/tests/codeception/api/functional/_steps/OauthSteps.php index 000bc88..c16aaf6 100644 --- a/tests/codeception/api/functional/_steps/OauthSteps.php +++ b/tests/codeception/api/functional/_steps/OauthSteps.php @@ -1,11 +1,12 @@ loggedInAsActiveAccount(); $route = new OauthRoute($this); @@ -13,7 +14,7 @@ class OauthSteps extends \tests\codeception\api\FunctionalTester { 'client_id' => 'ely', 'redirect_uri' => 'http://ely.by', 'response_type' => 'code', - 'scope' => 'minecraft_server_session' . ($online ? '' : ',offline_access'), + 'scope' => implode(',', $permissions), ], ['accept' => true]); $this->canSeeResponseJsonMatchesJsonPath('$.redirectUri'); $response = json_decode($this->grabResponse(), true); @@ -22,9 +23,22 @@ class OauthSteps extends \tests\codeception\api\FunctionalTester { return $matches[1]; } - public function getRefreshToken() { + public function getAccessToken(array $permissions = []) { + $authCode = $this->getAuthCode($permissions); + $response = $this->issueToken($authCode); + + return $response['access_token']; + } + + public function getRefreshToken(array $permissions = []) { // TODO: по идее можно напрямую сделать зпись в базу, что ускорит процесс тестирования - $authCode = $this->getAuthCode(false); + $authCode = $this->getAuthCode(array_merge([S::OFFLINE_ACCESS], $permissions)); + $response = $this->issueToken($authCode); + + return $response['refresh_token']; + } + + public function issueToken($authCode) { $route = new OauthRoute($this); $route->issueToken([ 'code' => $authCode, @@ -34,9 +48,7 @@ class OauthSteps extends \tests\codeception\api\FunctionalTester { 'grant_type' => 'authorization_code', ]); - $response = json_decode($this->grabResponse(), true); - - return $response['refresh_token']; + return json_decode($this->grabResponse(), true); } } diff --git a/tests/codeception/common/_support/FixtureHelper.php b/tests/codeception/common/_support/FixtureHelper.php index 4ec7f8e..c96fcc4 100644 --- a/tests/codeception/common/_support/FixtureHelper.php +++ b/tests/codeception/common/_support/FixtureHelper.php @@ -7,7 +7,6 @@ use tests\codeception\common\fixtures\AccountFixture; use tests\codeception\common\fixtures\AccountSessionFixture; use tests\codeception\common\fixtures\EmailActivationFixture; use tests\codeception\common\fixtures\OauthClientFixture; -use tests\codeception\common\fixtures\OauthScopeFixture; use tests\codeception\common\fixtures\OauthSessionFixture; use tests\codeception\common\fixtures\UsernameHistoryFixture; use yii\test\FixtureTrait; @@ -56,10 +55,6 @@ class FixtureHelper extends Module { 'class' => OauthClientFixture::class, 'dataFile' => '@tests/codeception/common/fixtures/data/oauth-clients.php', ], - 'oauthScopes' => [ - 'class' => OauthScopeFixture::class, - 'dataFile' => '@tests/codeception/common/fixtures/data/oauth-scopes.php', - ], 'oauthSessions' => [ 'class' => OauthSessionFixture::class, 'dataFile' => '@tests/codeception/common/fixtures/data/oauth-sessions.php', diff --git a/tests/codeception/common/fixtures/OauthScopeFixture.php b/tests/codeception/common/fixtures/OauthScopeFixture.php deleted file mode 100644 index 2ce4ef2..0000000 --- a/tests/codeception/common/fixtures/OauthScopeFixture.php +++ /dev/null @@ -1,11 +0,0 @@ - [ - 'id' => 'minecraft_server_session', - ], - 'change_skin' => [ - 'id' => 'change_skin', - ], - 'offline_access' => [ - 'id' => 'offline_access', - ], -];