mirror of
https://github.com/elyby/accounts.git
synced 2024-11-30 02:32:26 +05:30
Тесты для AuthorizationForm и кастомного RequiredValidator
В модуль Authserver добавлены хелперы для логирования Исправлена ошибка в MinecraftAccessKey Ускорено тестирование всего приложения
This commit is contained in:
parent
d37a865e14
commit
9c658f5bd9
@ -52,7 +52,6 @@ class LoginForm extends ApiForm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function validateActivity($attribute) {
|
public function validateActivity($attribute) {
|
||||||
// TODO: проверить, не заблокирован ли аккаунт
|
|
||||||
if (!$this->hasErrors()) {
|
if (!$this->hasErrors()) {
|
||||||
$account = $this->getAccount();
|
$account = $this->getAccount();
|
||||||
if ($account->status === Account::STATUS_BANNED) {
|
if ($account->status === Account::STATUS_BANNED) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace api\modules\authserver;
|
namespace api\modules\authserver;
|
||||||
|
|
||||||
|
use Yii;
|
||||||
use yii\base\BootstrapInterface;
|
use yii\base\BootstrapInterface;
|
||||||
use yii\base\InvalidConfigException;
|
use yii\base\InvalidConfigException;
|
||||||
|
|
||||||
@ -31,4 +32,12 @@ class Module extends \yii\base\Module implements BootstrapInterface {
|
|||||||
], false);
|
], false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function info($message) {
|
||||||
|
Yii::info($message, 'legacy-authserver');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function error($message) {
|
||||||
|
Yii::info($message, 'legacy-authserver');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,11 @@ namespace api\modules\authserver\models;
|
|||||||
|
|
||||||
use api\models\authentication\LoginForm;
|
use api\models\authentication\LoginForm;
|
||||||
use api\modules\authserver\exceptions\ForbiddenOperationException;
|
use api\modules\authserver\exceptions\ForbiddenOperationException;
|
||||||
|
use api\modules\authserver\Module as Authserver;
|
||||||
use api\modules\authserver\validators\RequiredValidator;
|
use api\modules\authserver\validators\RequiredValidator;
|
||||||
|
use common\helpers\Error as E;
|
||||||
|
use common\models\Account;
|
||||||
use common\models\MinecraftAccessKey;
|
use common\models\MinecraftAccessKey;
|
||||||
use Yii;
|
|
||||||
|
|
||||||
class AuthenticationForm extends Form {
|
class AuthenticationForm extends Form {
|
||||||
|
|
||||||
@ -26,17 +28,22 @@ class AuthenticationForm extends Form {
|
|||||||
public function authenticate() {
|
public function authenticate() {
|
||||||
$this->validate();
|
$this->validate();
|
||||||
|
|
||||||
Yii::info("Trying to authenticate user by login = '{$this->username}'.", 'legacy-authentication');
|
Authserver::info("Trying to authenticate user by login = '{$this->username}'.");
|
||||||
|
|
||||||
$loginForm = new LoginForm();
|
$loginForm = $this->createLoginForm();
|
||||||
$loginForm->login = $this->username;
|
$loginForm->login = $this->username;
|
||||||
$loginForm->password = $this->password;
|
$loginForm->password = $this->password;
|
||||||
if (!$loginForm->validate()) {
|
if (!$loginForm->validate()) {
|
||||||
$errors = $loginForm->getFirstErrors();
|
$errors = $loginForm->getFirstErrors();
|
||||||
if (isset($errors['login'])) {
|
if (isset($errors['login'])) {
|
||||||
Yii::error("Cannot find user by login = '{$this->username}", 'legacy-authentication');
|
if ($errors['login'] === E::ACCOUNT_BANNED) {
|
||||||
|
Authserver::error("User with login = '{$this->username}' is banned");
|
||||||
|
throw new ForbiddenOperationException('This account has been suspended.');
|
||||||
|
} else {
|
||||||
|
Authserver::error("Cannot find user by login = '{$this->username}'");
|
||||||
|
}
|
||||||
} elseif (isset($errors['password'])) {
|
} elseif (isset($errors['password'])) {
|
||||||
Yii::error("User with login = '{$this->username}' passed wrong password.", 'legacy-authentication');
|
Authserver::error("User with login = '{$this->username}' passed wrong password.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// На старом сервере авторизации использовалось поле nickname, а не username, так что сохраняем эту логику
|
// На старом сервере авторизации использовалось поле nickname, а не username, так что сохраняем эту логику
|
||||||
@ -45,16 +52,27 @@ class AuthenticationForm extends Form {
|
|||||||
$attribute = 'nickname';
|
$attribute = 'nickname';
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: если аккаунт заблокирован, то возвращалось сообщение return "This account has been suspended."
|
|
||||||
// TODO: эта логика дублируется с логикой в SignoutForm
|
// TODO: эта логика дублируется с логикой в SignoutForm
|
||||||
|
|
||||||
throw new ForbiddenOperationException("Invalid credentials. Invalid {$attribute} or password.");
|
throw new ForbiddenOperationException("Invalid credentials. Invalid {$attribute} or password.");
|
||||||
}
|
}
|
||||||
|
|
||||||
$account = $loginForm->getAccount();
|
$account = $loginForm->getAccount();
|
||||||
|
$accessTokenModel = $this->createMinecraftAccessToken($account);
|
||||||
|
$dataModel = new AuthenticateData($accessTokenModel);
|
||||||
|
|
||||||
|
Authserver::info("User with id = {$account->id}, username = '{$account->username}' and email = '{$account->email}' successfully logged in.");
|
||||||
|
|
||||||
|
return $dataModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function createMinecraftAccessToken(Account $account) : MinecraftAccessKey {
|
||||||
/** @var MinecraftAccessKey|null $accessTokenModel */
|
/** @var MinecraftAccessKey|null $accessTokenModel */
|
||||||
$accessTokenModel = MinecraftAccessKey::findOne(['client_token' => $this->clientToken]);
|
$accessTokenModel = MinecraftAccessKey::findOne([
|
||||||
|
'client_token' => $this->clientToken,
|
||||||
|
'account_id' => $account->id,
|
||||||
|
]);
|
||||||
|
|
||||||
if ($accessTokenModel === null) {
|
if ($accessTokenModel === null) {
|
||||||
$accessTokenModel = new MinecraftAccessKey();
|
$accessTokenModel = new MinecraftAccessKey();
|
||||||
$accessTokenModel->client_token = $this->clientToken;
|
$accessTokenModel->client_token = $this->clientToken;
|
||||||
@ -64,11 +82,11 @@ class AuthenticationForm extends Form {
|
|||||||
$accessTokenModel->refreshPrimaryKeyValue();
|
$accessTokenModel->refreshPrimaryKeyValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
$dataModel = new AuthenticateData($accessTokenModel);
|
return $accessTokenModel;
|
||||||
|
}
|
||||||
|
|
||||||
Yii::info("User with id = {$account->id}, username = '{$account->username}' and email = '{$account->email}' successfully logged in.", 'legacy-authentication');
|
protected function createLoginForm() : LoginForm {
|
||||||
|
return new LoginForm();
|
||||||
return $dataModel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ class MinecraftAccessKey extends ActiveRecord {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function isActual() : bool {
|
public function isActual() : bool {
|
||||||
return $this->timestamp + self::LIFETIME >= time();
|
return $this->updated_at + self::LIFETIME >= time();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,147 @@
|
|||||||
|
<?php
|
||||||
|
namespace codeception\api\unit\modules\authserver\models;
|
||||||
|
|
||||||
|
use api\models\AccountIdentity;
|
||||||
|
use api\models\authentication\LoginForm;
|
||||||
|
use api\modules\authserver\models\AuthenticateData;
|
||||||
|
use api\modules\authserver\models\AuthenticationForm;
|
||||||
|
use common\models\Account;
|
||||||
|
use common\models\MinecraftAccessKey;
|
||||||
|
use Ramsey\Uuid\Uuid;
|
||||||
|
use tests\codeception\api\unit\DbTestCase;
|
||||||
|
use tests\codeception\common\_support\ProtectedCaller;
|
||||||
|
use tests\codeception\common\fixtures\AccountFixture;
|
||||||
|
use tests\codeception\common\fixtures\MinecraftAccessKeyFixture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property AccountFixture $accounts
|
||||||
|
* @property MinecraftAccessKeyFixture $minecraftAccessKeys
|
||||||
|
*/
|
||||||
|
class AuthenticationFormTest extends DbTestCase {
|
||||||
|
use ProtectedCaller;
|
||||||
|
|
||||||
|
public function fixtures() {
|
||||||
|
return [
|
||||||
|
'accounts' => AccountFixture::class,
|
||||||
|
'minecraftAccessKeys' => MinecraftAccessKeyFixture::class,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \api\modules\authserver\exceptions\ForbiddenOperationException
|
||||||
|
* @expectedExceptionMessage Invalid credentials. Invalid nickname or password.
|
||||||
|
*/
|
||||||
|
public function testAuthenticateByWrongNicknamePass() {
|
||||||
|
$authForm = $this->createAuthForm();
|
||||||
|
|
||||||
|
$authForm->username = 'wrong-username';
|
||||||
|
$authForm->password = 'wrong-password';
|
||||||
|
$authForm->clientToken = Uuid::uuid4();
|
||||||
|
|
||||||
|
$authForm->authenticate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \api\modules\authserver\exceptions\ForbiddenOperationException
|
||||||
|
* @expectedExceptionMessage Invalid credentials. Invalid email or password.
|
||||||
|
*/
|
||||||
|
public function testAuthenticateByWrongEmailPass() {
|
||||||
|
$authForm = $this->createAuthForm();
|
||||||
|
|
||||||
|
$authForm->username = 'wrong-email@ely.by';
|
||||||
|
$authForm->password = 'wrong-password';
|
||||||
|
$authForm->clientToken = Uuid::uuid4();
|
||||||
|
|
||||||
|
$authForm->authenticate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \api\modules\authserver\exceptions\ForbiddenOperationException
|
||||||
|
* @expectedExceptionMessage This account has been suspended.
|
||||||
|
*/
|
||||||
|
public function testAuthenticateByValidCredentialsIntoBlockedAccount() {
|
||||||
|
$authForm = $this->createAuthForm(Account::STATUS_BANNED);
|
||||||
|
|
||||||
|
$authForm->username = 'dummy';
|
||||||
|
$authForm->password = 'password_0';
|
||||||
|
$authForm->clientToken = Uuid::uuid4();
|
||||||
|
|
||||||
|
$authForm->authenticate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAuthenticateByValidCredentials() {
|
||||||
|
$authForm = $this->createAuthForm();
|
||||||
|
|
||||||
|
$minecraftAccessKey = new MinecraftAccessKey();
|
||||||
|
$minecraftAccessKey->access_token = Uuid::uuid4();
|
||||||
|
$authForm->expects($this->once())
|
||||||
|
->method('createMinecraftAccessToken')
|
||||||
|
->will($this->returnValue($minecraftAccessKey));
|
||||||
|
|
||||||
|
$authForm->username = 'dummy';
|
||||||
|
$authForm->password = 'password_0';
|
||||||
|
$authForm->clientToken = Uuid::uuid4();
|
||||||
|
|
||||||
|
$result = $authForm->authenticate();
|
||||||
|
$this->assertInstanceOf(AuthenticateData::class, $result);
|
||||||
|
$this->assertEquals($minecraftAccessKey->access_token, $result->getMinecraftAccessKey()->access_token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCreateMinecraftAccessToken() {
|
||||||
|
$authForm = new AuthenticationForm();
|
||||||
|
$fixturesCount = count($this->minecraftAccessKeys->data);
|
||||||
|
$authForm->clientToken = Uuid::uuid4();
|
||||||
|
/** @var Account $account */
|
||||||
|
$account = $this->accounts->getModel('admin');
|
||||||
|
/** @var MinecraftAccessKey $result */
|
||||||
|
$result = $this->callProtected($authForm, 'createMinecraftAccessToken', $account);
|
||||||
|
$this->assertInstanceOf(MinecraftAccessKey::class, $result);
|
||||||
|
$this->assertEquals($account->id, $result->account_id);
|
||||||
|
$this->assertEquals($authForm->clientToken, $result->client_token);
|
||||||
|
$this->assertEquals($fixturesCount + 1, MinecraftAccessKey::find()->count());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCreateMinecraftAccessTokenWithExistsClientId() {
|
||||||
|
$authForm = new AuthenticationForm();
|
||||||
|
$fixturesCount = count($this->minecraftAccessKeys->data);
|
||||||
|
$authForm->clientToken = $this->minecraftAccessKeys[0]['client_token'];
|
||||||
|
/** @var Account $account */
|
||||||
|
$account = $this->accounts->getModel('admin');
|
||||||
|
/** @var MinecraftAccessKey $result */
|
||||||
|
$result = $this->callProtected($authForm, 'createMinecraftAccessToken', $account);
|
||||||
|
$this->assertInstanceOf(MinecraftAccessKey::class, $result);
|
||||||
|
$this->assertEquals($account->id, $result->account_id);
|
||||||
|
$this->assertEquals($authForm->clientToken, $result->client_token);
|
||||||
|
$this->assertEquals($fixturesCount, MinecraftAccessKey::find()->count());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createAuthForm($status = Account::STATUS_ACTIVE) {
|
||||||
|
/** @var LoginForm|\PHPUnit_Framework_MockObject_MockObject $loginForm */
|
||||||
|
$loginForm = $this->getMockBuilder(LoginForm::class)
|
||||||
|
->setMethods(['getAccount'])
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$account = new AccountIdentity();
|
||||||
|
$account->username = 'dummy';
|
||||||
|
$account->email = 'dummy@ely.by';
|
||||||
|
$account->status = $status;
|
||||||
|
$account->setPassword('password_0');
|
||||||
|
|
||||||
|
$loginForm->expects($this->any())
|
||||||
|
->method('getAccount')
|
||||||
|
->will($this->returnValue($account));
|
||||||
|
|
||||||
|
/** @var AuthenticationForm|\PHPUnit_Framework_MockObject_MockObject $authForm */
|
||||||
|
$authForm = $this->getMockBuilder(AuthenticationForm::class)
|
||||||
|
->setMethods(['createLoginForm', 'createMinecraftAccessToken'])
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$authForm->expects($this->any())
|
||||||
|
->method('createLoginForm')
|
||||||
|
->will($this->returnValue($loginForm));
|
||||||
|
|
||||||
|
return $authForm;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
namespace codeception\api\unit\modules\authserver\validators;
|
||||||
|
|
||||||
|
use api\modules\authserver\validators\RequiredValidator;
|
||||||
|
use tests\codeception\api\unit\TestCase;
|
||||||
|
use tests\codeception\common\_support\ProtectedCaller;
|
||||||
|
|
||||||
|
class RequiredValidatorTest extends TestCase {
|
||||||
|
use ProtectedCaller;
|
||||||
|
|
||||||
|
public function testValidateValueNormal() {
|
||||||
|
$validator = new RequiredValidator();
|
||||||
|
$this->assertNull($this->callProtected($validator, 'validateValue', 'dummy'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \api\modules\authserver\exceptions\IllegalArgumentException
|
||||||
|
*/
|
||||||
|
public function testValidateValueEmpty() {
|
||||||
|
$validator = new RequiredValidator();
|
||||||
|
$this->assertNull($this->callProtected($validator, 'validateValue', ''));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
namespace tests\codeception\common\fixtures;
|
||||||
|
|
||||||
|
use common\models\MinecraftAccessKey;
|
||||||
|
use yii\test\ActiveFixture;
|
||||||
|
|
||||||
|
class MinecraftAccessKeyFixture extends ActiveFixture {
|
||||||
|
|
||||||
|
public $modelClass = MinecraftAccessKey::class;
|
||||||
|
|
||||||
|
public $dataFile = '@tests/codeception/common/fixtures/data/minecraft-access-keys.php';
|
||||||
|
|
||||||
|
public $depends = [
|
||||||
|
AccountFixture::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
'access_token' => 'e7bb6648-2183-4981-9b86-eba5e7f87b42',
|
||||||
|
'client_token' => '6f380440-0c05-47bd-b7c6-d011f1b5308f',
|
||||||
|
'account_id' => 1,
|
||||||
|
'created_at' => 1472423530,
|
||||||
|
'updated_at' => 1472423530,
|
||||||
|
],
|
||||||
|
];
|
@ -30,5 +30,9 @@ return [
|
|||||||
'password' => 'tester-password',
|
'password' => 'tester-password',
|
||||||
'vhost' => '/account.ely.by/tests',
|
'vhost' => '/account.ely.by/tests',
|
||||||
],
|
],
|
||||||
|
'security' => [
|
||||||
|
// Для тестов нам не сильно важна безопасность, а вот время прохождения тестов значительно сокращается
|
||||||
|
'passwordHashCost' => 4,
|
||||||
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
Loading…
Reference in New Issue
Block a user