From 71d9511d8ed10d68d3a13ae4d64a81e252c55c98 Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Wed, 3 Aug 2016 22:05:19 +0300 Subject: [PATCH 1/3] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20oauth2=20=D0=BF=D0=B5=D1=80=D0=BC=D0=B8=D1=88=D0=B5?= =?UTF-8?q?=D0=BD=20=D0=BD=D0=B0=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81=20?= =?UTF-8?q?E-mail=20=D0=B0=D0=B4=D1=80=D0=B5=D1=81=D0=B0=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/models/OauthScope.php | 2 +- .../m160803_185857_permission_email_access.php | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 console/migrations/m160803_185857_permission_email_access.php diff --git a/common/models/OauthScope.php b/common/models/OauthScope.php index 74d3901..bb19198 100644 --- a/common/models/OauthScope.php +++ b/common/models/OauthScope.php @@ -1,7 +1,6 @@ insert('{{%oauth_scopes}}', ['id' => 'account_email']); + } + + public function safeDown() { + $this->delete('{{%oauth_scopes}}', ['id' => 'account_email']); + } + +} From 26b37c2f6baedeeb63d45bd9396d5056ff981831 Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Thu, 4 Aug 2016 01:07:21 +0300 Subject: [PATCH 2/3] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=8B=D1=82=D0=BA=D0=B0?= =?UTF-8?q?=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE=D0=B2=D0=B0=D1=82?= =?UTF-8?q?=D1=8C=20=D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9?= =?UTF-8?q?=20=D0=BA=D0=BE=D0=BC=D0=BF=D0=BE=D0=BD=D0=B5=D0=BD=D1=82=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20oAuth=20=D0=B0=D0=B2=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8=20=D0=B2=20=D1=81=D0=B2?= =?UTF-8?q?=D0=BE=D0=B9=20=D0=B6=D0=B5=20API.=20=D0=9D=D0=B5=20=D1=82?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BB,=20?= =?UTF-8?q?=D0=BD=D0=B5=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D1=8F=D0=BB?= =?UTF-8?q?=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=83,=20=D0=BF=D1=80=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D0=BE=20=D0=BF=D1=83=D1=88=D0=BD=D1=83=D0=BB,=20?= =?UTF-8?q?=D1=87=D1=82=D0=BE=D0=B1=D1=8B=20=D0=BF=D0=BE=D1=82=D0=BE=D0=BC?= =?UTF-8?q?=20=D0=BF=D1=80=D0=BE=D0=B4=D0=BE=D0=BB=D0=B6=D0=B8=D1=82=D1=8C?= =?UTF-8?q?=20=20=D0=B2=20=D0=B4=D1=80=D0=B3=D1=83=D0=BE=D0=BC=20=D0=BC?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D0=B5.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/components/ApiUser/AuthChecker.php | 22 +++++ api/components/ApiUser/Component.php | 19 +++++ api/components/ApiUser/Identity.php | 81 +++++++++++++++++++ api/components/User/Component.php | 6 ++ api/config/main.php | 6 +- api/controllers/ApiController.php | 31 +++++++ api/controllers/Controller.php | 2 + api/controllers/IdentityInfoController.php | 43 ++++++++++ autocompletion.php | 1 + common/helpers/StringHelper.php | 14 +++- common/models/Account.php | 11 ++- common/models/OauthAccessToken.php | 7 +- .../common/unit/helpers/StringHelperTest.php | 6 ++ 13 files changed, 241 insertions(+), 8 deletions(-) create mode 100644 api/components/ApiUser/AuthChecker.php create mode 100644 api/components/ApiUser/Component.php create mode 100644 api/components/ApiUser/Identity.php create mode 100644 api/controllers/ApiController.php create mode 100644 api/controllers/IdentityInfoController.php diff --git a/api/components/ApiUser/AuthChecker.php b/api/components/ApiUser/AuthChecker.php new file mode 100644 index 0000000..ef3dae5 --- /dev/null +++ b/api/components/ApiUser/AuthChecker.php @@ -0,0 +1,22 @@ +getScopes()->exists($permissionName); + } + +} diff --git a/api/components/ApiUser/Component.php b/api/components/ApiUser/Component.php new file mode 100644 index 0000000..9d6780a --- /dev/null +++ b/api/components/ApiUser/Component.php @@ -0,0 +1,19 @@ +isExpired()) { + throw new UnauthorizedHttpException('Token expired'); + } + + return new static($model); + } + + private function __construct(OauthAccessToken $accessToken) { + $this->_accessToken = $accessToken; + } + + public function getAccount() : Account { + return $this->getSession()->account; + } + + public function getClient() : OauthClient { + return $this->getSession()->client; + } + + public function getSession() : OauthSession { + return $this->_accessToken->session; + } + + public function getAccessToken() : OauthAccessToken { + return $this->_accessToken; + } + + /** + * Этот метод используется для получения пользователя, к которому привязаны права. + * У нас права привязываются к токенам, так что возвращаем именно его id. + * @inheritdoc + */ + public function getId() { + return $this->_accessToken->access_token; + } + + public function getAuthKey() { + throw new NotSupportedException('This method used for cookie auth, except we using Bearer auth'); + } + + public function validateAuthKey($authKey) { + throw new NotSupportedException('This method used for cookie auth, except we using Bearer auth'); + } + + public static function findIdentity($id) { + throw new NotSupportedException('This method used for cookie auth, except we using Bearer auth'); + } + +} diff --git a/api/components/User/Component.php b/api/components/User/Component.php index ab8ea39..bf22613 100644 --- a/api/components/User/Component.php +++ b/api/components/User/Component.php @@ -26,6 +26,12 @@ use yii\web\User as YiiUserComponent; */ class Component extends YiiUserComponent { + public $enableSession = false; + + public $loginUrl = null; + + public $identityClass = AccountIdentity::class; + public $secret; public $expirationTimeout = 3600; // 1h diff --git a/api/config/main.php b/api/config/main.php index e82ba86..8066d9c 100644 --- a/api/config/main.php +++ b/api/config/main.php @@ -15,11 +15,11 @@ return [ 'components' => [ 'user' => [ 'class' => \api\components\User\Component::class, - 'identityClass' => \api\models\AccountIdentity::class, - 'enableSession' => false, - 'loginUrl' => null, 'secret' => $params['userSecret'], ], + 'apiUser' => [ + 'class' => \api\components\ApiUser\Component::class, + ], 'log' => [ 'traceLevel' => YII_DEBUG ? 3 : 0, 'targets' => [ diff --git a/api/controllers/ApiController.php b/api/controllers/ApiController.php new file mode 100644 index 0000000..81a0455 --- /dev/null +++ b/api/controllers/ApiController.php @@ -0,0 +1,31 @@ + HttpBearerAuth::class, + 'user' => Yii::$app->apiUser, + ]; + + // xml нам не понадобится + unset($parentBehaviors['contentNegotiator']['formats']['application/xml']); + // rate limiter здесь не применяется + unset($parentBehaviors['rateLimiter']); + + return $parentBehaviors; + } + +} diff --git a/api/controllers/Controller.php b/api/controllers/Controller.php index 8f22f8e..8c655d6 100644 --- a/api/controllers/Controller.php +++ b/api/controllers/Controller.php @@ -2,6 +2,7 @@ namespace api\controllers; use api\traits\ApiNormalize; +use Yii; use yii\filters\auth\HttpBearerAuth; /** @@ -18,6 +19,7 @@ class Controller extends \yii\rest\Controller { // Добавляем авторизатор для входа по jwt токенам $parentBehaviors['authenticator'] = [ 'class' => HttpBearerAuth::class, + 'user' => Yii::$app->getUser(), ]; // xml нам не понадобится diff --git a/api/controllers/IdentityInfoController.php b/api/controllers/IdentityInfoController.php new file mode 100644 index 0000000..dd56800 --- /dev/null +++ b/api/controllers/IdentityInfoController.php @@ -0,0 +1,43 @@ + [ + 'class' => AccessControl::class, + 'rules' => [ + [ + 'actions' => ['index'], + 'allow' => true, + 'roles' => ['@'], + ], + ], + ], + ]); + } + + public function actionIndex() { + $account = Yii::$app->apiUser->getIdentity()->getAccount(); + $response = [ + 'id' => $account->id, + 'uuid' => $account->uuid, + 'registeredAt' => $account->created_at, + 'profileLink' => $account->getProfileLink(), + 'preferredLanguage' => $account->lang, + ]; + + if (Yii::$app->apiUser->can(OauthScope::ACCOUNT_EMAIL)) { + $response['email'] = $account->email; + } + + return $response; + } + +} diff --git a/autocompletion.php b/autocompletion.php index a0e847c..c3fcedf 100644 --- a/autocompletion.php +++ b/autocompletion.php @@ -28,6 +28,7 @@ abstract class BaseApplication extends yii\base\Application { * Include only Web application related components here * * @property \api\components\User\Component $user User component. + * @property \api\components\ApiUser\Component $apiUser Api User component. * @property \api\components\ReCaptcha\Component $reCaptcha * @property \common\components\oauth\Component $oauth * diff --git a/common/helpers/StringHelper.php b/common/helpers/StringHelper.php index d81186a..5e4c300 100644 --- a/common/helpers/StringHelper.php +++ b/common/helpers/StringHelper.php @@ -3,7 +3,7 @@ namespace common\helpers; class StringHelper { - public static function getEmailMask($email) { + public static function getEmailMask(string $email) : string { $username = explode('@', $email)[0]; $usernameLength = mb_strlen($username); $maskChars = '**'; @@ -21,4 +21,16 @@ class StringHelper { return $mask . mb_substr($email, $usernameLength); } + /** + * Проверяет на то, что переданная строка является валидным UUID + * Regex найдено на просторах интернета: http://stackoverflow.com/a/6223221 + * + * @param string $uuid + * @return bool + */ + public static function isUuid(string $uuid) : bool { + $re = '/[a-f0-9]{8}\-[a-f0-9]{4}\-4[a-f0-9]{3}\-(8|9|a|b)[a-f0-9]{3}\-[a-f0-9]{12}/'; + return preg_match($re, $uuid, $matches) === 1; + } + } diff --git a/common/models/Account.php b/common/models/Account.php index 98b61c4..8a90596 100644 --- a/common/models/Account.php +++ b/common/models/Account.php @@ -25,7 +25,8 @@ use yii\db\ActiveRecord; * @property integer $password_changed_at * * Геттеры-сеттеры: - * @property string $password пароль пользователя (только для записи) + * @property string $password пароль пользователя (только для записи) + * @property string $profileLink ссылка на профиль на Ely без поддержки static url (только для записи) * * Отношения: * @property EmailActivation[] $emailActivations @@ -144,7 +145,7 @@ class Account extends ActiveRecord { * * @return bool */ - public function canAutoApprove(OauthClient $client, array $scopes = []) { + public function canAutoApprove(OauthClient $client, array $scopes = []) : bool { if ($client->is_trusted) { return true; } @@ -165,10 +166,14 @@ class Account extends ActiveRecord { * Выполняет проверку, принадлежит ли этому нику аккаунт у Mojang * @return bool */ - public function hasMojangUsernameCollision() { + public function hasMojangUsernameCollision() : bool { return MojangUsername::find() ->andWhere(['username' => $this->username]) ->exists(); } + public function getProfileLink() : string { + return 'http://ely.by/u' . $this->id; + } + } diff --git a/common/models/OauthAccessToken.php b/common/models/OauthAccessToken.php index 7053cb8..9c60bed 100644 --- a/common/models/OauthAccessToken.php +++ b/common/models/OauthAccessToken.php @@ -2,7 +2,6 @@ namespace common\models; use common\components\redis\Set; -use Yii; use yii\db\ActiveRecord; /** @@ -13,6 +12,8 @@ use yii\db\ActiveRecord; * @property integer $expire_time * * @property Set $scopes + * + * @property OauthSession $session */ class OauthAccessToken extends ActiveRecord { @@ -38,4 +39,8 @@ class OauthAccessToken extends ActiveRecord { return true; } + public function isExpired() { + return time() > $this->expire_time; + } + } diff --git a/tests/codeception/common/unit/helpers/StringHelperTest.php b/tests/codeception/common/unit/helpers/StringHelperTest.php index 872331d..50c7297 100644 --- a/tests/codeception/common/unit/helpers/StringHelperTest.php +++ b/tests/codeception/common/unit/helpers/StringHelperTest.php @@ -13,4 +13,10 @@ class StringHelperTest extends \PHPUnit_Framework_TestCase { $this->assertEquals('эр**уч@елу.бел', StringHelper::getEmailMask('эрикскрауч@елу.бел')); } + public function testIsUuid() { + $this->assertTrue(StringHelper::isUuid('a80b4487-a5c6-45a5-9829-373b4a494135')); + $this->assertFalse(StringHelper::isUuid('12345678')); + $this->assertFalse(StringHelper::isUuid('12345678-1234-1234-1234-123456789123')); + } + } From a48c1432c64eb59001f1f68708155ce1cf476dd1 Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Sat, 6 Aug 2016 16:36:24 +0300 Subject: [PATCH 3/3] =?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', - ], -];