From 79bbc12206818d36d4d1e50d02ae4f84907cf838 Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Sun, 18 Dec 2016 02:20:53 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D0=BB=D0=B5?= =?UTF-8?q?=D1=80=20=D0=B4=D0=BB=D1=8F=20=D0=B1=D0=BB=D0=BE=D0=BA=D0=B8?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=BA=D0=B8=20=D0=B0=D0=BA=D0=BA=D0=B0=D1=83?= =?UTF-8?q?=D0=BD=D1=82=D0=B0=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20client=5Fcredentials=20grant=20=D0=B4=D0=BB=D1=8F=20oA?= =?UTF-8?q?uth=20=D0=A0=D0=B5=D1=84=D0=B0=D0=BA=D1=82=D0=BE=D1=80=D0=B8?= =?UTF-8?q?=D0=BD=D0=B3=20=D1=81=D1=82=D1=80=D1=83=D0=BA=D1=82=D1=83=D1=80?= =?UTF-8?q?=D1=8B=20OauthScopes=20=D1=87=D1=82=D0=BE=D0=B1=D1=8B=20=D0=BC?= =?UTF-8?q?=D0=BE=D0=B6=D0=BD=D0=BE=20=D0=B1=D1=8B=D0=BB=D0=BE=20=D1=80?= =?UTF-8?q?=D0=B0=D0=B7=D0=B4=D0=B5=D0=BB=D0=B8=D1=82=D1=8C=20=D0=B2=D0=BB?= =?UTF-8?q?=D0=B0=D0=B4=D0=B5=D0=BB=D1=8C=D1=86=D0=B0=20=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=20=D0=BD=D0=B0=20=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1=81=D0=BA=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=B8=20=D0=BE=D0=B1=D1=89=D0=B8=D0=B5=20(=D0=BC=D0=B0=D1=88?= =?UTF-8?q?=D0=B8=D0=BD=D0=BD=D1=8B=D0=B5)=20=D0=98=D1=81=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D1=81=D1=82=D0=B8=D0=BB?= =?UTF-8?q?=D0=B8=D1=81=D1=82=D0=B8=D0=BA=D0=B0=20=D0=BA=D0=BE=D0=B4=D0=B0?= =?UTF-8?q?,=20=D0=B2=D0=BD=D0=B5=D0=B4=D1=80=D1=8F=D1=8E=D1=82=D1=81?= =?UTF-8?q?=D1=8F=20=D1=84=D0=B8=D1=88=D0=BA=D0=B8=20PHP=207.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/components/ApiUser/Component.php | 4 +- api/components/ApiUser/Identity.php | 13 ++--- .../OAuth2/Entities/ClientEntity.php | 10 ++++ .../OAuth2/Grants/ClientCredentialsGrant.php | 20 ++++++++ .../OAuth2/Storage/ClientStorage.php | 1 + .../OAuth2/Storage/ScopeStorage.php | 24 ++++++++- api/config/config.php | 8 ++- api/controllers/OauthController.php | 13 ++--- api/modules/internal/Module.php | 19 +++++++ .../controllers/AccountsController.php | 11 ++-- api/modules/internal/helpers/Error.php | 8 +++ .../models/{BlockForm.php => BanForm.php} | 22 ++++++-- common/models/OauthScope.php | 41 +++++++-------- common/models/OauthScopeQuery.php | 50 +++++++++++++++++++ ..._oauth_clients_allow_null_redirect_uri.php | 15 ++++++ .../codeception/api/_pages/InternalRoute.php | 16 ++++++ .../api/functional/_steps/OauthSteps.php | 21 ++++++-- .../api/functional/internal/BanCest.php | 47 +++++++++++++++++ .../{BlockFormTest.php => BanFormTest.php} | 25 ++++++++-- .../common/fixtures/data/oauth-clients.php | 20 ++++++++ .../common/unit/models/OauthScopeTest.php | 12 ----- 21 files changed, 332 insertions(+), 68 deletions(-) create mode 100644 api/components/OAuth2/Grants/ClientCredentialsGrant.php create mode 100644 api/modules/internal/Module.php create mode 100644 api/modules/internal/helpers/Error.php rename api/modules/internal/models/{BlockForm.php => BanForm.php} (76%) create mode 100644 common/models/OauthScopeQuery.php create mode 100644 console/migrations/m161228_101022_oauth_clients_allow_null_redirect_uri.php create mode 100644 tests/codeception/api/_pages/InternalRoute.php create mode 100644 tests/codeception/api/functional/internal/BanCest.php rename tests/codeception/api/unit/modules/internal/models/{BlockFormTest.php => BanFormTest.php} (64%) delete mode 100644 tests/codeception/common/unit/models/OauthScopeTest.php diff --git a/api/components/ApiUser/Component.php b/api/components/ApiUser/Component.php index 46acfc1..d6f4655 100644 --- a/api/components/ApiUser/Component.php +++ b/api/components/ApiUser/Component.php @@ -6,8 +6,8 @@ use yii\web\User as YiiUserComponent; /** * @property Identity|null $identity * - * @method Identity|null getIdentity() - * @method Identity|null loginByAccessToken(string $token, $type = null) + * @method Identity|null getIdentity($autoRenew = true) + * @method Identity|null loginByAccessToken($token, $type = null) */ class Component extends YiiUserComponent { diff --git a/api/components/ApiUser/Identity.php b/api/components/ApiUser/Identity.php index fb3510d..953b5a7 100644 --- a/api/components/ApiUser/Identity.php +++ b/api/components/ApiUser/Identity.php @@ -26,7 +26,8 @@ class Identity implements IdentityInterface { /** * @inheritdoc */ - public static function findIdentityByAccessToken($token, $type = null) { + public static function findIdentityByAccessToken($token, $type = null): self { + /** @var AccessTokenEntity|null $model */ $model = Yii::$app->oauth->getAuthServer()->getAccessTokenStorage()->get($token); if ($model === null) { throw new UnauthorizedHttpException('Incorrect token'); @@ -41,19 +42,19 @@ class Identity implements IdentityInterface { $this->_accessToken = $accessToken; } - public function getAccount() : Account { + public function getAccount(): Account { return $this->getSession()->account; } - public function getClient() : OauthClient { + public function getClient(): OauthClient { return $this->getSession()->client; } - public function getSession() : OauthSession { + public function getSession(): OauthSession { return OauthSession::findOne($this->_accessToken->getSessionId()); } - public function getAccessToken() : AccessTokenEntity { + public function getAccessToken(): AccessTokenEntity { return $this->_accessToken; } @@ -62,7 +63,7 @@ class Identity implements IdentityInterface { * У нас права привязываются к токенам, так что возвращаем именно его id. * @inheritdoc */ - public function getId() { + public function getId(): string { return $this->_accessToken->getId(); } diff --git a/api/components/OAuth2/Entities/ClientEntity.php b/api/components/OAuth2/Entities/ClientEntity.php index 8636cf1..e88f424 100644 --- a/api/components/OAuth2/Entities/ClientEntity.php +++ b/api/components/OAuth2/Entities/ClientEntity.php @@ -3,6 +3,8 @@ namespace api\components\OAuth2\Entities; class ClientEntity extends \League\OAuth2\Server\Entity\ClientEntity { + private $isTrusted; + public function setId(string $id) { $this->id = $id; } @@ -19,4 +21,12 @@ class ClientEntity extends \League\OAuth2\Server\Entity\ClientEntity { $this->redirectUri = $redirectUri; } + public function setIsTrusted(bool $isTrusted) { + $this->isTrusted = $isTrusted; + } + + public function isTrusted(): bool { + return $this->isTrusted; + } + } diff --git a/api/components/OAuth2/Grants/ClientCredentialsGrant.php b/api/components/OAuth2/Grants/ClientCredentialsGrant.php new file mode 100644 index 0000000..4e7b467 --- /dev/null +++ b/api/components/OAuth2/Grants/ClientCredentialsGrant.php @@ -0,0 +1,20 @@ +server); + } + + protected function createRefreshTokenEntity() { + return new Entities\RefreshTokenEntity($this->server); + } + + protected function createSessionEntity() { + return new Entities\SessionEntity($this->server); + } + +} diff --git a/api/components/OAuth2/Storage/ClientStorage.php b/api/components/OAuth2/Storage/ClientStorage.php index 90d024b..9a339f0 100644 --- a/api/components/OAuth2/Storage/ClientStorage.php +++ b/api/components/OAuth2/Storage/ClientStorage.php @@ -74,6 +74,7 @@ class ClientStorage extends AbstractStorage implements ClientInterface { $entity->setId($model->id); $entity->setName($model->name); $entity->setSecret($model->secret); + $entity->setIsTrusted($model->is_trusted); $entity->setRedirectUri($model->redirect_uri); return $entity; diff --git a/api/components/OAuth2/Storage/ScopeStorage.php b/api/components/OAuth2/Storage/ScopeStorage.php index f653af8..d5223e5 100644 --- a/api/components/OAuth2/Storage/ScopeStorage.php +++ b/api/components/OAuth2/Storage/ScopeStorage.php @@ -1,10 +1,12 @@ onlyPublic()->usersScopes(); + } elseif ($grantType === 'client_credentials') { + $query->machineScopes(); + $isTrusted = false; + if ($clientId !== null) { + $client = $this->server->getClientStorage()->get($clientId); + if (!$client instanceof ClientEntity) { + throw new ErrorException('client storage must return instance of ' . ClientEntity::class); + } + + $isTrusted = $client->isTrusted(); + } + + if (!$isTrusted) { + $query->onlyPublic(); + } + } + + $scopes = $query->all(); if (!in_array($scope, $scopes, true)) { return null; } diff --git a/api/config/config.php b/api/config/config.php index 68e83c2..fcb7178 100644 --- a/api/config/config.php +++ b/api/config/config.php @@ -7,7 +7,7 @@ $params = array_merge( return [ 'id' => 'accounts-site-api', 'basePath' => dirname(__DIR__), - 'bootstrap' => ['log', 'authserver'], + 'bootstrap' => ['log', 'authserver', 'internal'], 'controllerNamespace' => 'api\controllers', 'params' => $params, 'components' => [ @@ -75,10 +75,11 @@ return [ ], 'oauth' => [ 'class' => api\components\OAuth2\Component::class, - 'grantTypes' => ['authorization_code'], + 'grantTypes' => ['authorization_code', 'client_credentials'], 'grantMap' => [ 'authorization_code' => api\components\OAuth2\Grants\AuthCodeGrant::class, 'refresh_token' => api\components\OAuth2\Grants\RefreshTokenGrant::class, + 'client_credentials' => api\components\OAuth2\Grants\ClientCredentialsGrant::class, ], ], 'errorHandler' => [ @@ -96,5 +97,8 @@ return [ 'mojang' => [ 'class' => api\modules\mojang\Module::class, ], + 'internal' => [ + 'class' => api\modules\internal\Module::class, + ], ], ]; diff --git a/api/controllers/OauthController.php b/api/controllers/OauthController.php index 8df62a0..9428287 100644 --- a/api/controllers/OauthController.php +++ b/api/controllers/OauthController.php @@ -7,7 +7,9 @@ use api\components\OAuth2\Exception\AccessDeniedException; use common\models\Account; use common\models\OauthClient; use common\models\OauthScope; +use League\OAuth2\Server\AuthorizationServer; use League\OAuth2\Server\Exception\OAuthException; +use League\OAuth2\Server\Grant\AuthCodeGrant; use Yii; use yii\filters\AccessControl; use yii\helpers\ArrayHelper; @@ -274,17 +276,12 @@ class OauthController extends Controller { return $response; } - /** - * @return \League\OAuth2\Server\AuthorizationServer - */ - private function getServer() { + private function getServer(): AuthorizationServer { return Yii::$app->oauth->authServer; } - /** - * @return \League\OAuth2\Server\Grant\AuthCodeGrant - */ - private function getGrantType() { + private function getGrantType(): AuthCodeGrant { + /** @noinspection PhpIncompatibleReturnTypeInspection */ return $this->getServer()->getGrantType('authorization_code'); } diff --git a/api/modules/internal/Module.php b/api/modules/internal/Module.php new file mode 100644 index 0000000..5213e72 --- /dev/null +++ b/api/modules/internal/Module.php @@ -0,0 +1,19 @@ +getUrlManager()->addRules([ + '/internal///' => "{$this->id}//", + ], false); + } + +} diff --git a/api/modules/internal/controllers/AccountsController.php b/api/modules/internal/controllers/AccountsController.php index fd4eb56..e666a0c 100644 --- a/api/modules/internal/controllers/AccountsController.php +++ b/api/modules/internal/controllers/AccountsController.php @@ -3,7 +3,7 @@ namespace api\modules\internal\controllers; use api\components\ApiUser\AccessControl; use api\controllers\Controller; -use api\modules\internal\models\BlockForm; +use api\modules\internal\models\BanForm; use common\models\Account; use common\models\OauthScope as S; use Yii; @@ -14,11 +14,14 @@ class AccountsController extends Controller { public function behaviors() { return ArrayHelper::merge(parent::behaviors(), [ + 'authenticator' => [ + 'user' => Yii::$app->apiUser, + ], 'access' => [ 'class' => AccessControl::class, 'rules' => [ [ - 'actions' => ['block'], + 'actions' => ['ban'], 'allow' => true, 'roles' => [S::ACCOUNT_BLOCK], ], @@ -27,9 +30,9 @@ class AccountsController extends Controller { ]); } - public function actionBlock(int $accountId) { + public function actionBan(int $accountId) { $account = $this->findAccount($accountId); - $model = new BlockForm($account); + $model = new BanForm($account); $model->load(Yii::$app->request->post()); if (!$model->ban()) { return [ diff --git a/api/modules/internal/helpers/Error.php b/api/modules/internal/helpers/Error.php new file mode 100644 index 0000000..86b45b5 --- /dev/null +++ b/api/modules/internal/helpers/Error.php @@ -0,0 +1,8 @@ + self::DURATION_FOREVER], [['message'], 'string'], + [['account'], 'validateAccountActivity'], ]; } @@ -46,7 +48,17 @@ class BlockForm extends ApiForm { return $this->account; } + public function validateAccountActivity() { + if ($this->account->status === Account::STATUS_BANNED) { + $this->addError('account', E::ACCOUNT_ALREADY_BANNED); + } + } + public function ban(): bool { + if (!$this->validate()) { + return false; + } + $transaction = Yii::$app->db->beginTransaction(); $account = $this->account; @@ -62,7 +74,7 @@ class BlockForm extends ApiForm { return true; } - public function createTask() { + public function createTask(): void { $model = new AccountBanned(); $model->accountId = $this->account->id; $model->duration = $this->duration; diff --git a/common/models/OauthScope.php b/common/models/OauthScope.php index 958d2da..bb4da54 100644 --- a/common/models/OauthScope.php +++ b/common/models/OauthScope.php @@ -4,32 +4,33 @@ namespace common\models; use common\components\Annotations\Reader; use ReflectionClass; use Yii; -use yii\helpers\ArrayHelper; class OauthScope { + /** + * @owner user + */ const OFFLINE_ACCESS = 'offline_access'; + /** + * @owner user + */ const MINECRAFT_SERVER_SESSION = 'minecraft_server_session'; + /** + * @owner user + */ const ACCOUNT_INFO = 'account_info'; + /** + * @owner user + */ const ACCOUNT_EMAIL = 'account_email'; - - /** @internal */ + /** + * @internal + * @owner machine + */ const ACCOUNT_BLOCK = 'account_block'; - public static function getScopes(): array { - return ArrayHelper::getColumn(static::queryScopes(), 'value'); - } - - public static function getPublicScopes(): array { - return ArrayHelper::getColumn(array_filter(static::queryScopes(), function($value) { - return !isset($value['internal']); - }), 'value'); - } - - public static function getInternalScopes(): array { - return ArrayHelper::getColumn(array_filter(static::queryScopes(), function($value) { - return isset($value['internal']); - }), 'value'); + public static function find(): OauthScopeQuery { + return new OauthScopeQuery(static::queryScopes()); } private static function queryScopes(): array { @@ -43,12 +44,12 @@ class OauthScope { foreach ($constants as $constName => $value) { $annotations = $reader->getConstantAnnotations(static::class, $constName); $isInternal = $annotations->get('internal', false); + $owner = $annotations->get('owner', 'user'); $keyValue = [ 'value' => $value, + 'internal' => $isInternal, + 'owner' => $owner, ]; - if ($isInternal) { - $keyValue['internal'] = true; - } $scopes[$constName] = $keyValue; } diff --git a/common/models/OauthScopeQuery.php b/common/models/OauthScopeQuery.php new file mode 100644 index 0000000..27577c5 --- /dev/null +++ b/common/models/OauthScopeQuery.php @@ -0,0 +1,50 @@ +internal = false; + return $this; + } + + public function onlyInternal(): self { + $this->internal = true; + return $this; + } + + public function usersScopes(): self { + $this->owner = 'user'; + return $this; + } + + public function machineScopes(): self { + $this->owner = 'machine'; + return $this; + } + + public function all(): array { + return ArrayHelper::getColumn(array_filter($this->scopes, function($value) { + $shouldCheckInternal = $this->internal !== null; + $isInternalMatch = $value['internal'] === $this->internal; + $shouldCheckOwner = $this->owner !== null; + $isOwnerMatch = $value['owner'] === $this->owner; + + return (!$shouldCheckInternal || $isInternalMatch) + && (!$shouldCheckOwner || $isOwnerMatch); + }), 'value'); + } + + public function __construct(array $scopes) { + $this->scopes = $scopes; + } + +} diff --git a/console/migrations/m161228_101022_oauth_clients_allow_null_redirect_uri.php b/console/migrations/m161228_101022_oauth_clients_allow_null_redirect_uri.php new file mode 100644 index 0000000..1734f95 --- /dev/null +++ b/console/migrations/m161228_101022_oauth_clients_allow_null_redirect_uri.php @@ -0,0 +1,15 @@ +alterColumn('{{%oauth_clients}}', 'redirect_uri', $this->string()); + } + + public function safeDown() { + $this->alterColumn('{{%oauth_clients}}', 'redirect_uri', $this->string()->notNull()); + } + +} diff --git a/tests/codeception/api/_pages/InternalRoute.php b/tests/codeception/api/_pages/InternalRoute.php new file mode 100644 index 0000000..36ce520 --- /dev/null +++ b/tests/codeception/api/_pages/InternalRoute.php @@ -0,0 +1,16 @@ +route = '/internal/accounts/' . $accountId . '/ban'; + $this->actor->sendPOST($this->getUrl()); + } + +} diff --git a/tests/codeception/api/functional/_steps/OauthSteps.php b/tests/codeception/api/functional/_steps/OauthSteps.php index c16aaf6..3e0c467 100644 --- a/tests/codeception/api/functional/_steps/OauthSteps.php +++ b/tests/codeception/api/functional/_steps/OauthSteps.php @@ -3,11 +3,12 @@ namespace tests\codeception\api\functional\_steps; use common\models\OauthScope as S; use tests\codeception\api\_pages\OauthRoute; +use tests\codeception\api\FunctionalTester; -class OauthSteps extends \tests\codeception\api\FunctionalTester { +class OauthSteps extends FunctionalTester { public function getAuthCode(array $permissions = []) { - // TODO: по идее можно напрямую сделать зпись в базу, что ускорит процесс тестирования + // TODO: по идее можно напрямую сделать запись в базу, что ускорит процесс тестирования $this->loggedInAsActiveAccount(); $route = new OauthRoute($this); $route->complete([ @@ -31,7 +32,7 @@ class OauthSteps extends \tests\codeception\api\FunctionalTester { } public function getRefreshToken(array $permissions = []) { - // TODO: по идее можно напрямую сделать зпись в базу, что ускорит процесс тестирования + // TODO: по идее можно напрямую сделать запись в базу, что ускорит процесс тестирования $authCode = $this->getAuthCode(array_merge([S::OFFLINE_ACCESS], $permissions)); $response = $this->issueToken($authCode); @@ -51,4 +52,18 @@ class OauthSteps extends \tests\codeception\api\FunctionalTester { return json_decode($this->grabResponse(), true); } + public function getAccessTokenByClientCredentialsGrant(array $permissions = [], $useTrusted = true) { + $route = new OauthRoute($this); + $route->issueToken([ + 'client_id' => $useTrusted ? 'trusted-client' : 'default-client', + 'client_secret' => $useTrusted ? 'tXBbyvMcyaOgHMOAXBpN2EC7uFoJAaL9' : 'AzWRy7ZjS1yRQUk2vRBDic8fprOKDB1W', + 'grant_type' => 'client_credentials', + 'scope' => implode(',', $permissions), + ]); + + $response = json_decode($this->grabResponse(), true); + + return $response['access_token']; + } + } diff --git a/tests/codeception/api/functional/internal/BanCest.php b/tests/codeception/api/functional/internal/BanCest.php new file mode 100644 index 0000000..9f46806 --- /dev/null +++ b/tests/codeception/api/functional/internal/BanCest.php @@ -0,0 +1,47 @@ +route = new InternalRoute($I); + } + + public function testBanAccount(OauthSteps $I) { + $accessToken = $I->getAccessTokenByClientCredentialsGrant([S::ACCOUNT_BLOCK]); + $I->amBearerAuthenticated($accessToken); + + $this->route->ban(1); + $I->canSeeResponseCodeIs(200); + $I->canSeeResponseIsJson(); + $I->canSeeResponseContainsJson([ + 'success' => true, + ]); + } + + public function testBanBannedAccount(OauthSteps $I) { + $accessToken = $I->getAccessTokenByClientCredentialsGrant([S::ACCOUNT_BLOCK]); + $I->amBearerAuthenticated($accessToken); + + $this->route->ban(10); + $I->canSeeResponseCodeIs(200); + $I->canSeeResponseIsJson(); + $I->canSeeResponseContainsJson([ + 'success' => false, + 'errors' => [ + 'account' => 'error.account_already_banned', + ], + ]); + } + +} diff --git a/tests/codeception/api/unit/modules/internal/models/BlockFormTest.php b/tests/codeception/api/unit/modules/internal/models/BanFormTest.php similarity index 64% rename from tests/codeception/api/unit/modules/internal/models/BlockFormTest.php rename to tests/codeception/api/unit/modules/internal/models/BanFormTest.php index 055eaec..b63c15a 100644 --- a/tests/codeception/api/unit/modules/internal/models/BlockFormTest.php +++ b/tests/codeception/api/unit/modules/internal/models/BanFormTest.php @@ -1,11 +1,26 @@ status = Account::STATUS_ACTIVE; + $form = new BanForm($account); + $form->validateAccountActivity(); + $this->assertEmpty($form->getErrors('account')); + + $account = new Account(); + $account->status = Account::STATUS_BANNED; + $form = new BanForm($account); + $form->validateAccountActivity(); + $this->assertEquals([E::ACCOUNT_ALREADY_BANNED], $form->getErrors('account')); + } public function testBan() { /** @var Account|\PHPUnit_Framework_MockObject_MockObject $account */ @@ -17,7 +32,7 @@ class BlockFormTest extends TestCase { ->method('save') ->willReturn(true); - $model = new BlockForm($account); + $model = new BanForm($account); $this->assertTrue($model->ban()); $this->assertEquals(Account::STATUS_BANNED, $account->status); $this->tester->canSeeAmqpMessageIsCreated('events'); @@ -27,14 +42,14 @@ class BlockFormTest extends TestCase { $account = new Account(); $account->id = 3; - $model = new BlockForm($account); + $model = new BanForm($account); $model->createTask(); $message = json_decode($this->tester->grabLastSentAmqpMessage('events')->body, true); $this->assertSame(3, $message['accountId']); $this->assertSame(-1, $message['duration']); $this->assertSame('', $message['message']); - $model = new BlockForm($account); + $model = new BanForm($account); $model->duration = 123; $model->message = 'test'; $model->createTask(); diff --git a/tests/codeception/common/fixtures/data/oauth-clients.php b/tests/codeception/common/fixtures/data/oauth-clients.php index e7ddba5..e8c2dfc 100644 --- a/tests/codeception/common/fixtures/data/oauth-clients.php +++ b/tests/codeception/common/fixtures/data/oauth-clients.php @@ -30,4 +30,24 @@ return [ 'is_trusted' => 0, 'created_at' => 1479937982, ], + 'trustedClient' => [ + 'id' => 'trusted-client', + 'secret' => 'tXBbyvMcyaOgHMOAXBpN2EC7uFoJAaL9', + 'name' => 'Trusted client', + 'description' => 'Это клиент, которому мы доверяем', + 'redirect_uri' => null, + 'account_id' => null, + 'is_trusted' => 1, + 'created_at' => 1482922663, + ], + 'defaultClient' => [ + 'id' => 'default-client', + 'secret' => 'AzWRy7ZjS1yRQUk2vRBDic8fprOKDB1W', + 'name' => 'Default client', + 'description' => 'Это обычный клиент, каких может быть много', + 'redirect_uri' => null, + 'account_id' => null, + 'is_trusted' => 0, + 'created_at' => 1482922711, + ], ]; diff --git a/tests/codeception/common/unit/models/OauthScopeTest.php b/tests/codeception/common/unit/models/OauthScopeTest.php deleted file mode 100644 index 8adbca6..0000000 --- a/tests/codeception/common/unit/models/OauthScopeTest.php +++ /dev/null @@ -1,12 +0,0 @@ -