Merge branch 'develop' into new_locales

This commit is contained in:
ErickSkrauch 2017-06-01 10:36:49 +03:00
commit c60765cc43
21 changed files with 112 additions and 76 deletions

View File

@ -61,6 +61,9 @@ return [
],
'request' => [
'baseUrl' => '/api',
'parsers' => [
'*' => api\request\RequestParser::class,
],
],
'urlManager' => [
'enablePrettyUrl' => true,

View File

@ -3,6 +3,7 @@ namespace api\modules\authserver\controllers;
use api\controllers\Controller;
use api\modules\authserver\models;
use Yii;
class AuthenticationController extends Controller {
@ -25,21 +26,21 @@ class AuthenticationController extends Controller {
public function actionAuthenticate() {
$model = new models\AuthenticationForm();
$model->loadByPost();
$model->load(Yii::$app->request->post());
return $model->authenticate()->getResponseData(true);
}
public function actionRefresh() {
$model = new models\RefreshTokenForm();
$model->loadByPost();
$model->load(Yii::$app->request->post());
return $model->refresh()->getResponseData(false);
}
public function actionValidate() {
$model = new models\ValidateForm();
$model->loadByPost();
$model->load(Yii::$app->request->post());
$model->validateToken();
// В случае успеха ожидается пустой ответ. В случае ошибки же бросается исключение,
// которое обработает ErrorHandler
@ -47,7 +48,7 @@ class AuthenticationController extends Controller {
public function actionSignout() {
$model = new models\SignoutForm();
$model->loadByPost();
$model->load(Yii::$app->request->post());
$model->signout();
// В случае успеха ожидается пустой ответ. В случае ошибки же бросается исключение,
// которое обработает ErrorHandler
@ -55,7 +56,7 @@ class AuthenticationController extends Controller {
public function actionInvalidate() {
$model = new models\InvalidateForm();
$model->loadByPost();
$model->load(Yii::$app->request->post());
$model->invalidateToken();
// В случае успеха ожидается пустой ответ. В случае ошибки же бросается исключение,
// которое обработает ErrorHandler

View File

@ -2,6 +2,7 @@
namespace api\modules\authserver\models;
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\RequiredValidator;
@ -9,7 +10,7 @@ use common\helpers\Error as E;
use common\models\Account;
use common\models\MinecraftAccessKey;
class AuthenticationForm extends Form {
class AuthenticationForm extends ApiForm {
public $username;
public $password;

View File

@ -1,27 +0,0 @@
<?php
namespace api\modules\authserver\models;
use Yii;
use yii\base\Model;
abstract class Form extends Model {
public function formName() {
return '';
}
public function loadByGet() {
return $this->load(Yii::$app->request->get());
}
public function loadByPost() {
$data = Yii::$app->request->post();
if (empty($data)) {
// TODO: помнится у Yii2 есть механизм парсинга данных входящего запроса. Лучше будет сделать это там
$data = json_decode(Yii::$app->request->getRawBody(), true);
}
return $this->load($data);
}
}

View File

@ -1,10 +1,11 @@
<?php
namespace api\modules\authserver\models;
use api\models\base\ApiForm;
use api\modules\authserver\validators\RequiredValidator;
use common\models\MinecraftAccessKey;
class InvalidateForm extends Form {
class InvalidateForm extends ApiForm {
public $accessToken;
public $clientToken;

View File

@ -1,12 +1,13 @@
<?php
namespace api\modules\authserver\models;
use api\models\base\ApiForm;
use api\modules\authserver\exceptions\ForbiddenOperationException;
use api\modules\authserver\validators\RequiredValidator;
use common\models\Account;
use common\models\MinecraftAccessKey;
class RefreshTokenForm extends Form {
class RefreshTokenForm extends ApiForm {
public $accessToken;
public $clientToken;

View File

@ -2,13 +2,14 @@
namespace api\modules\authserver\models;
use api\models\authentication\LoginForm;
use api\models\base\ApiForm;
use api\modules\authserver\exceptions\ForbiddenOperationException;
use api\modules\authserver\validators\RequiredValidator;
use common\helpers\Error as E;
use common\models\MinecraftAccessKey;
use Yii;
class SignoutForm extends Form {
class SignoutForm extends ApiForm {
public $username;
public $password;

View File

@ -1,11 +1,12 @@
<?php
namespace api\modules\authserver\models;
use api\models\base\ApiForm;
use api\modules\authserver\exceptions\ForbiddenOperationException;
use api\modules\authserver\validators\RequiredValidator;
use common\models\MinecraftAccessKey;
class ValidateForm extends Form {
class ValidateForm extends ApiForm {
public $accessToken;

View File

@ -86,10 +86,7 @@ class ApiController extends Controller {
public function actionUuidsByUsernames() {
$usernames = Yii::$app->request->post();
if (empty($usernames)) {
$usernames = json_decode(Yii::$app->request->getRawBody());
if (empty($usernames)) {
return $this->illegalArgumentResponse('Passed array of profile names is an invalid JSON string.');
}
return $this->illegalArgumentResponse('Passed array of profile names is an invalid JSON string.');
}
$usernames = array_unique($usernames);

View File

@ -35,11 +35,6 @@ class SessionController extends ApiController {
Yii::$app->response->format = Response::FORMAT_JSON;
$data = Yii::$app->request->post();
if (empty($data)) {
// TODO: помнится у Yii2 есть механизм парсинга данных входящего запроса. Лучше будет сделать это там
$data = json_decode(Yii::$app->request->getRawBody(), true);
}
$protocol = new ModernJoin($data['accessToken'] ?? '', $data['selectedProfile'] ?? '', $data['serverId'] ?? '');
$joinForm = new JoinForm($protocol);
$joinForm->join();

View File

@ -0,0 +1,43 @@
<?php
namespace api\request;
use Yii;
use yii\web\JsonParser;
use yii\web\RequestParserInterface;
/**
* Т.к. Yii2 не предоставляет возможности сделать fallback для неспаршенного
* request, нужно полностью реимплементировать логику парсинга запроса.
*
* Код взят из \yii\web\Request::getBodyParams() и вывернут таким образом,
* чтобы по нисходящей пытаться спарсить запрос:
* - сначала проверяем, если PHP справился сам, то возвращаем его значение
* - дальше пробуем спарсить JSON, который закодирован в теле
* - если не вышло, то предположим, что это PUT, DELETE или иной другой запрос,
* который PHP автоматически не осиливает спарсить, так что пытаемся его спарсить
* самостоятельно
*/
class RequestParser implements RequestParserInterface {
public function parse($rawBody, $contentType) {
if (!empty($_POST)) {
return $_POST;
}
/** @var JsonParser $parser */
$parser = Yii::createObject(JsonParser::class);
$parser->throwException = false;
$result = $parser->parse($rawBody, $contentType);
if (!empty($result)) {
return $result;
}
mb_parse_str($rawBody, $bodyParams);
if (!empty($bodyParams)) {
return $bodyParams;
}
return [];
}
}

View File

@ -37,7 +37,8 @@
"yiisoft/yii2-debug": "*",
"yiisoft/yii2-faker": "*",
"flow/jsonpath": "^0.3.1",
"codeception/codeception": "2.2.10",
"phpunit/phpunit": "^5.7",
"codeception/codeception": "~2.3",
"codeception/specify": "*",
"codeception/verify": "*",
"phploc/phploc": "^3.0.1",

View File

@ -12,8 +12,9 @@ modules:
config:
Yii2:
configFile: '../config/api/functional.php'
cleanup: false
cleanup: true
Redis:
host: "%REDIS_HOST%"
port: 6379
database: 0
cleanupBefore: 'test'

View File

@ -38,6 +38,17 @@ class AuthorizationCest {
$this->testSuccessResponse($I);
}
public function byNamePassedViaPOSTBody(FunctionalTester $I) {
$I->wantTo('authenticate by username and password sent via post body');
$this->route->authenticate(json_encode([
'username' => 'admin',
'password' => 'password_0',
'clientToken' => Uuid::uuid4()->toString(),
]));
$this->testSuccessResponse($I);
}
public function byEmailWithEnabledTwoFactorAuth(FunctionalTester $I) {
$I->wantTo('get valid error by authenticate account with enabled two factor auth');
$this->route->authenticate([

View File

@ -98,17 +98,6 @@ class UsernamesToUuidsCest {
]);
}
public function passWrongPostBody(FunctionalTester $I) {
$I->wantTo('get specific response when pass invalid json string');
$this->route->uuidsByUsernames('wrong-json');
$I->canSeeResponseCodeIs(400);
$I->canSeeResponseIsJson();
$I->canSeeResponseContainsJson([
'error' => 'IllegalArgumentException',
'errorMessage' => 'Passed array of profile names is an invalid JSON string.',
]);
}
private function validateFewValidUsernames(FunctionalTester $I) {
$I->canSeeResponseCodeIs(200);
$I->canSeeResponseIsJson();

View File

@ -8,4 +8,4 @@ modules:
config:
Yii2:
configFile: '../config/api/unit.php'
cleanup: false
cleanup: true

View File

@ -0,0 +1,20 @@
<?php
namespace tests\codeception\api\unit\request;
use api\request\RequestParser;
use tests\codeception\api\unit\TestCase;
class RequestParserTest extends TestCase {
public function testParse() {
$parser = new RequestParser();
$_POST = ['from' => 'post'];
$this->assertEquals(['from' => 'post'], $parser->parse('from=post', ''));
$this->assertEquals(['from' => 'post'], $parser->parse('', ''));
$_POST = [];
$this->assertEquals(['from' => 'json'], $parser->parse('{"from":"json"}', ''));
$this->assertEquals(['from' => 'body'], $parser->parse('from=body', ''));
$this->assertEquals(['onlykey' => ''], $parser->parse('onlykey', ''));
}
}

View File

@ -28,12 +28,9 @@ class Helper extends Module {
return;
}
// TODO: заменить на assertCount() после релиза Codeception 2.2.7
// https://github.com/Codeception/Codeception/pull/3802
/** @noinspection PhpUnitTestsInspection */
$this->assertEquals(
$this->assertCount(
$num,
count($this->grabSentAmqpMessages($exchange)),
$this->grabSentAmqpMessages($exchange),
'number of created messages is equal to ' . $num
);
}

View File

@ -43,16 +43,16 @@ class TestComponent extends Component {
public function getSentMessages(string $exchangeName = null) : array {
if ($exchangeName !== null) {
return $this->sentMessages[$exchangeName] ?? [];
} else {
$messages = [];
foreach($this->sentMessages as $exchangeGroup) {
foreach ($exchangeGroup as $message) {
$messages[] = $message;
}
}
return $messages;
}
$messages = [];
foreach($this->sentMessages as $exchangeGroup) {
foreach ($exchangeGroup as $message) {
$messages[] = $message;
}
}
return $messages;
}
}

View File

@ -7,4 +7,4 @@ modules:
config:
Yii2:
configFile: '../config/common/unit.php'
cleanup: false
cleanup: true

View File

@ -7,4 +7,4 @@ modules:
config:
Yii2:
configFile: '../config/console/unit.php'
cleanup: false
cleanup: true