Добавлена логика HasJoined для сервера авторизации Minecraft

Исправлена ошибка в JoinForm
Добавлено базовое API для общения с сервером системы скинов
This commit is contained in:
ErickSkrauch
2016-09-06 12:56:39 +03:00
parent 198e440b8d
commit 68ce8b3fb6
17 changed files with 444 additions and 4 deletions

View File

@@ -4,9 +4,12 @@ namespace api\modules\session\controllers;
use api\controllers\ApiController;
use api\modules\session\exceptions\ForbiddenOperationException;
use api\modules\session\exceptions\SessionServerException;
use api\modules\session\models\HasJoinedForm;
use api\modules\session\models\JoinForm;
use api\modules\session\models\protocols\LegacyJoin;
use api\modules\session\models\protocols\ModernHasJoined;
use api\modules\session\models\protocols\ModernJoin;
use common\models\Textures;
use Yii;
use yii\web\Response;
@@ -57,4 +60,38 @@ class SessionController extends ApiController {
return 'OK';
}
public function actionHasJoined() {
Yii::$app->response->format = Response::FORMAT_JSON;
$data = Yii::$app->request->get();
$protocol = new ModernHasJoined($data['username'] ?? '', $data['serverId'] ?? '');
$hasJoinedForm = new HasJoinedForm($protocol);
$account = $hasJoinedForm->hasJoined();
$textures = new Textures($account);
return $textures->getMinecraftResponse();
}
public function actionHasJoinedLegacy() {
Yii::$app->response->format = Response::FORMAT_RAW;
$data = Yii::$app->request->get();
$protocol = new ModernHasJoined($data['user'] ?? '', $data['serverId'] ?? '');
$hasJoinedForm = new HasJoinedForm($protocol);
try {
$hasJoinedForm->hasJoined();
} catch (SessionServerException $e) {
Yii::$app->response->statusCode = $e->statusCode;
if ($e instanceof ForbiddenOperationException) {
$message = 'NO';
} else {
$message = $e->getMessage();
}
return $message;
}
return 'YES';
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace api\modules\session\models;
use api\modules\session\exceptions\ForbiddenOperationException;
use api\modules\session\exceptions\IllegalArgumentException;
use api\modules\session\models\protocols\HasJoinedInterface;
use api\modules\session\Module as Session;
use common\models\Account;
use yii\base\ErrorException;
use yii\base\Model;
class HasJoinedForm extends Model {
private $protocol;
public function __construct(HasJoinedInterface $protocol, array $config = []) {
$this->protocol = $protocol;
parent::__construct($config);
}
public function hasJoined() : Account {
if (!$this->protocol->validate()) {
throw new IllegalArgumentException();
}
$serverId = $this->protocol->getServerId();
$username = $this->protocol->getUsername();
Session::info(
"Server with server_id = '{$serverId}' trying to verify has joined user with username = '{$username}'."
);
$joinModel = SessionModel::find($username, $serverId);
if ($joinModel === null) {
Session::error("Not found join operation for username = '{$username}'.");
throw new ForbiddenOperationException('Invalid token.');
}
$joinModel->delete();
$account = $joinModel->getAccount();
if ($account === null) {
throw new ErrorException('Account must exists');
}
Session::info(
"User with username = '{$username}' successfully verified by server with server_id = '{$serverId}'."
);
return $account;
}
}

View File

@@ -18,9 +18,9 @@ use yii\web\UnauthorizedHttpException;
class JoinForm extends Model {
private $accessToken;
private $selectedProfile;
private $serverId;
public $accessToken;
public $selectedProfile;
public $serverId;
/**
* @var Account|null

View File

@@ -1,6 +1,7 @@
<?php
namespace api\modules\session\models;
use common\models\Account;
use Yii;
class SessionModel {
@@ -50,7 +51,15 @@ class SessionModel {
return Yii::$app->redis->executeCommand('DEL', [static::buildKey($this->username, $this->serverId)]);
}
protected static function buildKey($username, $serverId) {
/**
* @return Account|null
* TODO: после перехода на PHP 7.1 установить тип как ?Account
*/
public function getAccount() {
return Account::findOne(['username' => $this->username]);
}
protected static function buildKey($username, $serverId) : string {
return md5('minecraft:join-server:' . mb_strtolower($username) . ':' . $serverId);
}

View File

@@ -0,0 +1,31 @@
<?php
namespace api\modules\session\models\protocols;
use yii\validators\RequiredValidator;
abstract class BaseHasJoined implements HasJoinedInterface {
private $username;
private $serverId;
public function __construct(string $username, string $serverId) {
$this->username = $username;
$this->serverId = $serverId;
}
public function getUsername() : string {
return $this->username;
}
public function getServerId() : string {
return $this->serverId;
}
public function validate() : bool {
$validator = new RequiredValidator();
return $validator->validate($this->username)
&& $validator->validate($this->serverId);
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace api\modules\session\models\protocols;
interface HasJoinedInterface {
public function getUsername() : string;
public function getServerId() : string;
public function validate() : bool;
}

View File

@@ -0,0 +1,6 @@
<?php
namespace api\modules\session\models\protocols;
class LegacyHasJoined extends BaseHasJoined {
}

View File

@@ -0,0 +1,6 @@
<?php
namespace api\modules\session\models\protocols;
class ModernHasJoined extends BaseHasJoined {
}