mirror of
https://github.com/elyby/accounts.git
synced 2025-01-11 06:22:16 +05:30
Теперь при передаче запроса как json, закодированный в теле, он автоматически парсится
This commit is contained in:
parent
30fedc51ef
commit
400f0e87b9
@ -61,6 +61,9 @@ return [
|
||||
],
|
||||
'request' => [
|
||||
'baseUrl' => '/api',
|
||||
'parsers' => [
|
||||
'*' => api\request\RequestParser::class,
|
||||
],
|
||||
],
|
||||
'urlManager' => [
|
||||
'enablePrettyUrl' => true,
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
43
api/request/RequestParser.php
Normal file
43
api/request/RequestParser.php
Normal 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 [];
|
||||
}
|
||||
|
||||
}
|
@ -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([
|
||||
|
@ -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();
|
||||
|
20
tests/codeception/api/unit/request/RequestParserTest.php
Normal file
20
tests/codeception/api/unit/request/RequestParserTest.php
Normal 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', ''));
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user