mirror of
https://github.com/elyby/accounts.git
synced 2025-05-31 14:11:46 +05:30
Merge branch 'develop' into new_locales
This commit is contained in:
@@ -61,6 +61,9 @@ return [
|
|||||||
],
|
],
|
||||||
'request' => [
|
'request' => [
|
||||||
'baseUrl' => '/api',
|
'baseUrl' => '/api',
|
||||||
|
'parsers' => [
|
||||||
|
'*' => api\request\RequestParser::class,
|
||||||
|
],
|
||||||
],
|
],
|
||||||
'urlManager' => [
|
'urlManager' => [
|
||||||
'enablePrettyUrl' => true,
|
'enablePrettyUrl' => true,
|
||||||
|
@@ -3,6 +3,7 @@ namespace api\modules\authserver\controllers;
|
|||||||
|
|
||||||
use api\controllers\Controller;
|
use api\controllers\Controller;
|
||||||
use api\modules\authserver\models;
|
use api\modules\authserver\models;
|
||||||
|
use Yii;
|
||||||
|
|
||||||
class AuthenticationController extends Controller {
|
class AuthenticationController extends Controller {
|
||||||
|
|
||||||
@@ -25,21 +26,21 @@ class AuthenticationController extends Controller {
|
|||||||
|
|
||||||
public function actionAuthenticate() {
|
public function actionAuthenticate() {
|
||||||
$model = new models\AuthenticationForm();
|
$model = new models\AuthenticationForm();
|
||||||
$model->loadByPost();
|
$model->load(Yii::$app->request->post());
|
||||||
|
|
||||||
return $model->authenticate()->getResponseData(true);
|
return $model->authenticate()->getResponseData(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function actionRefresh() {
|
public function actionRefresh() {
|
||||||
$model = new models\RefreshTokenForm();
|
$model = new models\RefreshTokenForm();
|
||||||
$model->loadByPost();
|
$model->load(Yii::$app->request->post());
|
||||||
|
|
||||||
return $model->refresh()->getResponseData(false);
|
return $model->refresh()->getResponseData(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function actionValidate() {
|
public function actionValidate() {
|
||||||
$model = new models\ValidateForm();
|
$model = new models\ValidateForm();
|
||||||
$model->loadByPost();
|
$model->load(Yii::$app->request->post());
|
||||||
$model->validateToken();
|
$model->validateToken();
|
||||||
// В случае успеха ожидается пустой ответ. В случае ошибки же бросается исключение,
|
// В случае успеха ожидается пустой ответ. В случае ошибки же бросается исключение,
|
||||||
// которое обработает ErrorHandler
|
// которое обработает ErrorHandler
|
||||||
@@ -47,7 +48,7 @@ class AuthenticationController extends Controller {
|
|||||||
|
|
||||||
public function actionSignout() {
|
public function actionSignout() {
|
||||||
$model = new models\SignoutForm();
|
$model = new models\SignoutForm();
|
||||||
$model->loadByPost();
|
$model->load(Yii::$app->request->post());
|
||||||
$model->signout();
|
$model->signout();
|
||||||
// В случае успеха ожидается пустой ответ. В случае ошибки же бросается исключение,
|
// В случае успеха ожидается пустой ответ. В случае ошибки же бросается исключение,
|
||||||
// которое обработает ErrorHandler
|
// которое обработает ErrorHandler
|
||||||
@@ -55,7 +56,7 @@ class AuthenticationController extends Controller {
|
|||||||
|
|
||||||
public function actionInvalidate() {
|
public function actionInvalidate() {
|
||||||
$model = new models\InvalidateForm();
|
$model = new models\InvalidateForm();
|
||||||
$model->loadByPost();
|
$model->load(Yii::$app->request->post());
|
||||||
$model->invalidateToken();
|
$model->invalidateToken();
|
||||||
// В случае успеха ожидается пустой ответ. В случае ошибки же бросается исключение,
|
// В случае успеха ожидается пустой ответ. В случае ошибки же бросается исключение,
|
||||||
// которое обработает ErrorHandler
|
// которое обработает ErrorHandler
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
namespace api\modules\authserver\models;
|
namespace api\modules\authserver\models;
|
||||||
|
|
||||||
use api\models\authentication\LoginForm;
|
use api\models\authentication\LoginForm;
|
||||||
|
use api\models\base\ApiForm;
|
||||||
use api\modules\authserver\exceptions\ForbiddenOperationException;
|
use api\modules\authserver\exceptions\ForbiddenOperationException;
|
||||||
use api\modules\authserver\Module as Authserver;
|
use api\modules\authserver\Module as Authserver;
|
||||||
use api\modules\authserver\validators\RequiredValidator;
|
use api\modules\authserver\validators\RequiredValidator;
|
||||||
@@ -9,7 +10,7 @@ use common\helpers\Error as E;
|
|||||||
use common\models\Account;
|
use common\models\Account;
|
||||||
use common\models\MinecraftAccessKey;
|
use common\models\MinecraftAccessKey;
|
||||||
|
|
||||||
class AuthenticationForm extends Form {
|
class AuthenticationForm extends ApiForm {
|
||||||
|
|
||||||
public $username;
|
public $username;
|
||||||
public $password;
|
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
|
<?php
|
||||||
namespace api\modules\authserver\models;
|
namespace api\modules\authserver\models;
|
||||||
|
|
||||||
|
use api\models\base\ApiForm;
|
||||||
use api\modules\authserver\validators\RequiredValidator;
|
use api\modules\authserver\validators\RequiredValidator;
|
||||||
use common\models\MinecraftAccessKey;
|
use common\models\MinecraftAccessKey;
|
||||||
|
|
||||||
class InvalidateForm extends Form {
|
class InvalidateForm extends ApiForm {
|
||||||
|
|
||||||
public $accessToken;
|
public $accessToken;
|
||||||
public $clientToken;
|
public $clientToken;
|
||||||
|
@@ -1,12 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace api\modules\authserver\models;
|
namespace api\modules\authserver\models;
|
||||||
|
|
||||||
|
use api\models\base\ApiForm;
|
||||||
use api\modules\authserver\exceptions\ForbiddenOperationException;
|
use api\modules\authserver\exceptions\ForbiddenOperationException;
|
||||||
use api\modules\authserver\validators\RequiredValidator;
|
use api\modules\authserver\validators\RequiredValidator;
|
||||||
use common\models\Account;
|
use common\models\Account;
|
||||||
use common\models\MinecraftAccessKey;
|
use common\models\MinecraftAccessKey;
|
||||||
|
|
||||||
class RefreshTokenForm extends Form {
|
class RefreshTokenForm extends ApiForm {
|
||||||
|
|
||||||
public $accessToken;
|
public $accessToken;
|
||||||
public $clientToken;
|
public $clientToken;
|
||||||
|
@@ -2,13 +2,14 @@
|
|||||||
namespace api\modules\authserver\models;
|
namespace api\modules\authserver\models;
|
||||||
|
|
||||||
use api\models\authentication\LoginForm;
|
use api\models\authentication\LoginForm;
|
||||||
|
use api\models\base\ApiForm;
|
||||||
use api\modules\authserver\exceptions\ForbiddenOperationException;
|
use api\modules\authserver\exceptions\ForbiddenOperationException;
|
||||||
use api\modules\authserver\validators\RequiredValidator;
|
use api\modules\authserver\validators\RequiredValidator;
|
||||||
use common\helpers\Error as E;
|
use common\helpers\Error as E;
|
||||||
use common\models\MinecraftAccessKey;
|
use common\models\MinecraftAccessKey;
|
||||||
use Yii;
|
use Yii;
|
||||||
|
|
||||||
class SignoutForm extends Form {
|
class SignoutForm extends ApiForm {
|
||||||
|
|
||||||
public $username;
|
public $username;
|
||||||
public $password;
|
public $password;
|
||||||
|
@@ -1,11 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace api\modules\authserver\models;
|
namespace api\modules\authserver\models;
|
||||||
|
|
||||||
|
use api\models\base\ApiForm;
|
||||||
use api\modules\authserver\exceptions\ForbiddenOperationException;
|
use api\modules\authserver\exceptions\ForbiddenOperationException;
|
||||||
use api\modules\authserver\validators\RequiredValidator;
|
use api\modules\authserver\validators\RequiredValidator;
|
||||||
use common\models\MinecraftAccessKey;
|
use common\models\MinecraftAccessKey;
|
||||||
|
|
||||||
class ValidateForm extends Form {
|
class ValidateForm extends ApiForm {
|
||||||
|
|
||||||
public $accessToken;
|
public $accessToken;
|
||||||
|
|
||||||
|
@@ -85,12 +85,9 @@ class ApiController extends Controller {
|
|||||||
|
|
||||||
public function actionUuidsByUsernames() {
|
public function actionUuidsByUsernames() {
|
||||||
$usernames = Yii::$app->request->post();
|
$usernames = Yii::$app->request->post();
|
||||||
if (empty($usernames)) {
|
|
||||||
$usernames = json_decode(Yii::$app->request->getRawBody());
|
|
||||||
if (empty($usernames)) {
|
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);
|
$usernames = array_unique($usernames);
|
||||||
if (count($usernames) > 100) {
|
if (count($usernames) > 100) {
|
||||||
|
@@ -35,11 +35,6 @@ class SessionController extends ApiController {
|
|||||||
Yii::$app->response->format = Response::FORMAT_JSON;
|
Yii::$app->response->format = Response::FORMAT_JSON;
|
||||||
|
|
||||||
$data = Yii::$app->request->post();
|
$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'] ?? '');
|
$protocol = new ModernJoin($data['accessToken'] ?? '', $data['selectedProfile'] ?? '', $data['serverId'] ?? '');
|
||||||
$joinForm = new JoinForm($protocol);
|
$joinForm = new JoinForm($protocol);
|
||||||
$joinForm->join();
|
$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 [];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -37,7 +37,8 @@
|
|||||||
"yiisoft/yii2-debug": "*",
|
"yiisoft/yii2-debug": "*",
|
||||||
"yiisoft/yii2-faker": "*",
|
"yiisoft/yii2-faker": "*",
|
||||||
"flow/jsonpath": "^0.3.1",
|
"flow/jsonpath": "^0.3.1",
|
||||||
"codeception/codeception": "2.2.10",
|
"phpunit/phpunit": "^5.7",
|
||||||
|
"codeception/codeception": "~2.3",
|
||||||
"codeception/specify": "*",
|
"codeception/specify": "*",
|
||||||
"codeception/verify": "*",
|
"codeception/verify": "*",
|
||||||
"phploc/phploc": "^3.0.1",
|
"phploc/phploc": "^3.0.1",
|
||||||
|
@@ -12,8 +12,9 @@ modules:
|
|||||||
config:
|
config:
|
||||||
Yii2:
|
Yii2:
|
||||||
configFile: '../config/api/functional.php'
|
configFile: '../config/api/functional.php'
|
||||||
cleanup: false
|
cleanup: true
|
||||||
Redis:
|
Redis:
|
||||||
host: "%REDIS_HOST%"
|
host: "%REDIS_HOST%"
|
||||||
port: 6379
|
port: 6379
|
||||||
database: 0
|
database: 0
|
||||||
|
cleanupBefore: 'test'
|
||||||
|
@@ -38,6 +38,17 @@ class AuthorizationCest {
|
|||||||
$this->testSuccessResponse($I);
|
$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) {
|
public function byEmailWithEnabledTwoFactorAuth(FunctionalTester $I) {
|
||||||
$I->wantTo('get valid error by authenticate account with enabled two factor auth');
|
$I->wantTo('get valid error by authenticate account with enabled two factor auth');
|
||||||
$this->route->authenticate([
|
$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) {
|
private function validateFewValidUsernames(FunctionalTester $I) {
|
||||||
$I->canSeeResponseCodeIs(200);
|
$I->canSeeResponseCodeIs(200);
|
||||||
$I->canSeeResponseIsJson();
|
$I->canSeeResponseIsJson();
|
||||||
|
@@ -8,4 +8,4 @@ modules:
|
|||||||
config:
|
config:
|
||||||
Yii2:
|
Yii2:
|
||||||
configFile: '../config/api/unit.php'
|
configFile: '../config/api/unit.php'
|
||||||
cleanup: false
|
cleanup: true
|
||||||
|
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', ''));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -28,12 +28,9 @@ class Helper extends Module {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: заменить на assertCount() после релиза Codeception 2.2.7
|
$this->assertCount(
|
||||||
// https://github.com/Codeception/Codeception/pull/3802
|
|
||||||
/** @noinspection PhpUnitTestsInspection */
|
|
||||||
$this->assertEquals(
|
|
||||||
$num,
|
$num,
|
||||||
count($this->grabSentAmqpMessages($exchange)),
|
$this->grabSentAmqpMessages($exchange),
|
||||||
'number of created messages is equal to ' . $num
|
'number of created messages is equal to ' . $num
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -43,7 +43,8 @@ class TestComponent extends Component {
|
|||||||
public function getSentMessages(string $exchangeName = null) : array {
|
public function getSentMessages(string $exchangeName = null) : array {
|
||||||
if ($exchangeName !== null) {
|
if ($exchangeName !== null) {
|
||||||
return $this->sentMessages[$exchangeName] ?? [];
|
return $this->sentMessages[$exchangeName] ?? [];
|
||||||
} else {
|
}
|
||||||
|
|
||||||
$messages = [];
|
$messages = [];
|
||||||
foreach($this->sentMessages as $exchangeGroup) {
|
foreach($this->sentMessages as $exchangeGroup) {
|
||||||
foreach ($exchangeGroup as $message) {
|
foreach ($exchangeGroup as $message) {
|
||||||
@@ -53,6 +54,5 @@ class TestComponent extends Component {
|
|||||||
|
|
||||||
return $messages;
|
return $messages;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -7,4 +7,4 @@ modules:
|
|||||||
config:
|
config:
|
||||||
Yii2:
|
Yii2:
|
||||||
configFile: '../config/common/unit.php'
|
configFile: '../config/common/unit.php'
|
||||||
cleanup: false
|
cleanup: true
|
||||||
|
@@ -7,4 +7,4 @@ modules:
|
|||||||
config:
|
config:
|
||||||
Yii2:
|
Yii2:
|
||||||
configFile: '../config/console/unit.php'
|
configFile: '../config/console/unit.php'
|
||||||
cleanup: false
|
cleanup: true
|
||||||
|
Reference in New Issue
Block a user