diff --git a/api/aop/AspectKernel.php b/api/aop/AspectKernel.php index fc30542..bd03dc3 100644 --- a/api/aop/AspectKernel.php +++ b/api/aop/AspectKernel.php @@ -2,12 +2,15 @@ namespace api\aop; use api\aop\aspects; +use Doctrine\Common\Annotations\AnnotationReader; use Go\Core\AspectContainer; use Go\Core\AspectKernel as BaseAspectKernel; class AspectKernel extends BaseAspectKernel { protected function configureAop(AspectContainer $container): void { + AnnotationReader::addGlobalIgnoredName('url'); + $container->registerAspect(new aspects\MockDataAspect()); $container->registerAspect(new aspects\CollectMetricsAspect()); } diff --git a/api/models/OauthProcess.php b/api/models/OauthProcess.php index 5d50582..bfc6021 100644 --- a/api/models/OauthProcess.php +++ b/api/models/OauthProcess.php @@ -126,8 +126,8 @@ class OauthProcess { /** * Метод выполняется сервером приложения, которому был выдан auth_token или refresh_token. * - * Входными данными является стандартный список GET параметров по стандарту oAuth: - * $_GET = [ + * Входными данными является стандартный список POST параметров по стандарту oAuth: + * $_POST = [ * client_id, * client_secret, * redirect_uri, @@ -135,7 +135,7 @@ class OauthProcess { * grant_type, * ] * для запроса grant_type = authentication_code. - * $_GET = [ + * $_POST = [ * client_id, * client_secret, * refresh_token, @@ -145,12 +145,15 @@ class OauthProcess { * @return array */ public function getToken(): array { + $grantType = Yii::$app->request->post('grant_type', 'null'); try { - Yii::$app->statsd->inc('oauth.issueToken.attempt'); + Yii::$app->statsd->inc("oauth.issueToken_{$grantType}.attempt"); $response = $this->server->issueAccessToken(); - Yii::$app->statsd->inc('oauth.issueToken.success'); + $clientId = Yii::$app->request->post('client_id'); + Yii::$app->statsd->inc("oauth.issueToken_client.{$clientId}"); + Yii::$app->statsd->inc("oauth.issueToken_{$grantType}.success"); } catch (OAuthException $e) { - Yii::$app->statsd->inc('oauth.issueToken.fail'); + Yii::$app->statsd->inc("oauth.issueToken_{$grantType}.fail"); Yii::$app->response->statusCode = $e->httpStatusCode; $response = [ 'error' => $e->errorType, diff --git a/api/modules/authserver/exceptions/IllegalArgumentException.php b/api/modules/authserver/exceptions/IllegalArgumentException.php index 11adfa6..898daee 100644 --- a/api/modules/authserver/exceptions/IllegalArgumentException.php +++ b/api/modules/authserver/exceptions/IllegalArgumentException.php @@ -3,8 +3,8 @@ namespace api\modules\authserver\exceptions; class IllegalArgumentException extends AuthserverException { - public function __construct($status = null, $message = null, $code = 0, \Exception $previous = null) { - parent::__construct(400, 'credentials can not be null.', $code, $previous); + public function __construct($message = 'credentials can not be null.') { + parent::__construct(400, $message); } } diff --git a/api/modules/authserver/models/AuthenticationForm.php b/api/modules/authserver/models/AuthenticationForm.php index aab29bd..b8c8921 100644 --- a/api/modules/authserver/models/AuthenticationForm.php +++ b/api/modules/authserver/models/AuthenticationForm.php @@ -5,6 +5,7 @@ use api\models\authentication\LoginForm; use api\models\base\ApiForm; use api\modules\authserver\exceptions\ForbiddenOperationException; use api\modules\authserver\Module as Authserver; +use api\modules\authserver\validators\ClientTokenValidator; use api\modules\authserver\validators\RequiredValidator; use common\helpers\Error as E; use common\models\Account; @@ -19,6 +20,7 @@ class AuthenticationForm extends ApiForm { public function rules() { return [ [['username', 'password', 'clientToken'], RequiredValidator::class], + [['clientToken'], ClientTokenValidator::class], ]; } diff --git a/api/modules/authserver/validators/ClientTokenValidator.php b/api/modules/authserver/validators/ClientTokenValidator.php new file mode 100644 index 0000000..8825b8f --- /dev/null +++ b/api/modules/authserver/validators/ClientTokenValidator.php @@ -0,0 +1,25 @@ + 255) { + throw new IllegalArgumentException('clientToken is too long.'); + } + + return null; + } + +} diff --git a/api/modules/session/models/JoinForm.php b/api/modules/session/models/JoinForm.php index f53d7f5..8b47053 100644 --- a/api/modules/session/models/JoinForm.php +++ b/api/modules/session/models/JoinForm.php @@ -53,7 +53,7 @@ class JoinForm extends Model { $serverId = $this->serverId; $accessToken = $this->accessToken; Session::info("User with access_token = '{$accessToken}' trying join to server with server_id = '{$serverId}'."); - Yii::$app->statsd->inc('sessionserver.join.attempts'); + Yii::$app->statsd->inc('sessionserver.join.attempt'); if (!$this->validate()) { return false; } diff --git a/common/config/config.php b/common/config/config.php index b258bb4..4e9e107 100644 --- a/common/config/config.php +++ b/common/config/config.php @@ -1,6 +1,6 @@ '1.1.22', + 'version' => '1.1.23', 'vendorPath' => dirname(__DIR__, 2) . '/vendor', 'components' => [ 'cache' => [ diff --git a/common/tasks/SendCurrentEmailConfirmation.php b/common/tasks/SendCurrentEmailConfirmation.php index 55e96ef..fe0285e 100644 --- a/common/tasks/SendCurrentEmailConfirmation.php +++ b/common/tasks/SendCurrentEmailConfirmation.php @@ -5,6 +5,7 @@ namespace common\tasks; use common\emails\EmailHelper; use common\emails\templates\ChangeEmailConfirmCurrentEmail; use common\models\confirmations\CurrentEmailConfirmation; +use Yii; use yii\queue\RetryableJobInterface; class SendCurrentEmailConfirmation implements RetryableJobInterface { @@ -36,6 +37,7 @@ class SendCurrentEmailConfirmation implements RetryableJobInterface { * @param \yii\queue\Queue $queue */ public function execute($queue) { + Yii::$app->statsd->inc('queue.sendCurrentEmailConfirmation.attempt'); $to = EmailHelper::buildTo($this->username, $this->email); $template = new ChangeEmailConfirmCurrentEmail($to, $this->code); $template->send(); diff --git a/common/tasks/SendNewEmailConfirmation.php b/common/tasks/SendNewEmailConfirmation.php index 25d4edc..da034ff 100644 --- a/common/tasks/SendNewEmailConfirmation.php +++ b/common/tasks/SendNewEmailConfirmation.php @@ -5,6 +5,7 @@ namespace common\tasks; use common\emails\EmailHelper; use common\emails\templates\ChangeEmailConfirmNewEmail; use common\models\confirmations\NewEmailConfirmation; +use Yii; use yii\queue\RetryableJobInterface; class SendNewEmailConfirmation implements RetryableJobInterface { @@ -36,6 +37,7 @@ class SendNewEmailConfirmation implements RetryableJobInterface { * @param \yii\queue\Queue $queue */ public function execute($queue) { + Yii::$app->statsd->inc('queue.sendNewEmailConfirmation.attempt'); $to = EmailHelper::buildTo($this->username, $this->email); $template = new ChangeEmailConfirmNewEmail($to, $this->username, $this->code); $template->send(); diff --git a/common/tasks/SendPasswordRecoveryEmail.php b/common/tasks/SendPasswordRecoveryEmail.php index 394ab75..0dba85b 100644 --- a/common/tasks/SendPasswordRecoveryEmail.php +++ b/common/tasks/SendPasswordRecoveryEmail.php @@ -47,6 +47,7 @@ class SendPasswordRecoveryEmail implements RetryableJobInterface { * @throws \common\emails\exceptions\CannotSendEmailException */ public function execute($queue) { + Yii::$app->statsd->inc('queue.sendPasswordRecovery.attempt'); $params = new ForgotPasswordParams($this->username, $this->code, $this->link); $to = EmailHelper::buildTo($this->username, $this->email); $template = new ForgotPasswordEmail($to, $this->locale, $params); diff --git a/common/tasks/SendRegistrationEmail.php b/common/tasks/SendRegistrationEmail.php index f6aebc5..a960e96 100644 --- a/common/tasks/SendRegistrationEmail.php +++ b/common/tasks/SendRegistrationEmail.php @@ -47,6 +47,7 @@ class SendRegistrationEmail implements RetryableJobInterface { * @throws \common\emails\exceptions\CannotSendEmailException */ public function execute($queue) { + Yii::$app->statsd->inc('queue.sendRegistrationEmail.attempt'); $params = new RegistrationEmailParams($this->username, $this->code, $this->link); $to = EmailHelper::buildTo($this->username, $this->email); $template = new RegistrationEmail($to, $this->locale, $params); diff --git a/console/migrations/m180102_164624_increase_minecraft_access_keys_client_token_length.php b/console/migrations/m180102_164624_increase_minecraft_access_keys_client_token_length.php new file mode 100644 index 0000000..56c3fbd --- /dev/null +++ b/console/migrations/m180102_164624_increase_minecraft_access_keys_client_token_length.php @@ -0,0 +1,15 @@ +alterColumn('{{%minecraft_access_keys}}', 'client_token', $this->string()->notNull()); + } + + public function safeDown() { + $this->alterColumn('{{%minecraft_access_keys}}', 'client_token', $this->string(36)->notNull()); + } + +} diff --git a/tests/codeception/api/functional/authserver/AuthorizationCest.php b/tests/codeception/api/functional/authserver/AuthorizationCest.php index 626adb6..2b17c1e 100644 --- a/tests/codeception/api/functional/authserver/AuthorizationCest.php +++ b/tests/codeception/api/functional/authserver/AuthorizationCest.php @@ -75,6 +75,31 @@ class AuthorizationCest { $this->testSuccessResponse($I); } + public function longClientToken(FunctionalTester $I) { + $I->wantTo('send non uuid clientToken, but less then 255 characters'); + $this->route->authenticate([ + 'username' => 'admin@ely.by', + 'password' => 'password_0', + 'clientToken' => str_pad('', 255, 'x'), + ]); + $this->testSuccessResponse($I); + } + + public function tooLongClientToken(FunctionalTester $I) { + $I->wantTo('send non uuid clientToken with more then 255 characters length'); + $this->route->authenticate([ + 'username' => 'admin@ely.by', + 'password' => 'password_0', + 'clientToken' => str_pad('', 256, 'x'), + ]); + $I->canSeeResponseCodeIs(400); + $I->canSeeResponseIsJson(); + $I->canSeeResponseContainsJson([ + 'error' => 'IllegalArgumentException', + 'errorMessage' => 'clientToken is too long.', + ]); + } + public function wrongArguments(FunctionalTester $I) { $I->wantTo('get error on wrong amount of arguments'); $this->route->authenticate([