Add totp field for Minecraft auth protocol to login into accounts, protected with 2FA [deploy]

This commit is contained in:
ErickSkrauch
2021-03-08 11:26:47 +01:00
parent 125caa7e4e
commit 9a3534ea2b
3 changed files with 38 additions and 0 deletions

View File

@ -29,6 +29,11 @@ class AuthenticationForm extends ApiForm {
*/ */
public $password; public $password;
/**
* @var string
*/
public $totp;
/** /**
* @var string * @var string
*/ */
@ -42,6 +47,7 @@ class AuthenticationForm extends ApiForm {
public function rules(): array { public function rules(): array {
return [ return [
[['username', 'password', 'clientToken'], RequiredValidator::class], [['username', 'password', 'clientToken'], RequiredValidator::class],
[['totp'], 'string'],
[['clientToken'], ClientTokenValidator::class], [['clientToken'], ClientTokenValidator::class],
[['requestUser'], 'boolean'], [['requestUser'], 'boolean'],
]; ];
@ -65,6 +71,7 @@ class AuthenticationForm extends ApiForm {
$loginForm = new LoginForm(); $loginForm = new LoginForm();
$loginForm->login = $this->username; $loginForm->login = $this->username;
$loginForm->password = $this->password; $loginForm->password = $this->password;
$loginForm->totp = $this->totp;
if (!$loginForm->validate() || $loginForm->getAccount()->status === Account::STATUS_DELETED) { if (!$loginForm->validate() || $loginForm->getAccount()->status === Account::STATUS_DELETED) {
$errors = $loginForm->getFirstErrors(); $errors = $loginForm->getFirstErrors();
if (isset($errors['totp'])) { if (isset($errors['totp'])) {

View File

@ -5,6 +5,7 @@ namespace api\tests\functional\authserver;
use api\tests\FunctionalTester; use api\tests\FunctionalTester;
use Codeception\Example; use Codeception\Example;
use OTPHP\TOTP;
use Ramsey\Uuid\Uuid; use Ramsey\Uuid\Uuid;
class AuthorizationCest { class AuthorizationCest {
@ -91,6 +92,22 @@ class AuthorizationCest {
]); ]);
} }
public function byEmailWithEnabledTwoFactorAuthAndCorrectToken(FunctionalTester $I) {
$I->sendPOST('/api/authserver/authentication/authenticate', [
'username' => 'otp@gmail.com',
'password' => 'password_0',
'totp' => TOTP::create('BBBB')->now(),
'clientToken' => Uuid::uuid4()->toString(),
]);
$I->canSeeResponseCodeIs(200);
$I->canSeeResponseContainsJson([
'selectedProfile' => [
'id' => '15d0afa7a2bb44d39f31964cbccc6043',
'name' => 'AccountWithEnabledOtp',
],
]);
}
public function tooLongClientToken(FunctionalTester $I) { public function tooLongClientToken(FunctionalTester $I) {
$I->wantTo('send non uuid clientToken with more then 255 characters length'); $I->wantTo('send non uuid clientToken with more then 255 characters length');
$I->sendPOST('/api/authserver/authentication/authenticate', [ $I->sendPOST('/api/authserver/authentication/authenticate', [

View File

@ -10,6 +10,7 @@ use common\models\OauthClient;
use common\models\OauthSession; use common\models\OauthSession;
use common\tests\fixtures\AccountFixture; use common\tests\fixtures\AccountFixture;
use common\tests\fixtures\OauthClientFixture; use common\tests\fixtures\OauthClientFixture;
use OTPHP\TOTP;
use Ramsey\Uuid\Uuid; use Ramsey\Uuid\Uuid;
class AuthenticationFormTest extends TestCase { class AuthenticationFormTest extends TestCase {
@ -51,6 +52,19 @@ class AuthenticationFormTest extends TestCase {
], $result['user']); ], $result['user']);
} }
public function testAuthenticateByValidCredentialsWith2FA() {
$authForm = new AuthenticationForm();
$authForm->username = 'otp@gmail.com';
$authForm->password = 'password_0';
$authForm->totp = TOTP::create('BBBB')->now();
$authForm->clientToken = Uuid::uuid4()->toString();
// Just ensure that there is no exception
$this->expectNotToPerformAssertions();
$authForm->authenticate();
}
/** /**
* @dataProvider getInvalidCredentialsCases * @dataProvider getInvalidCredentialsCases
*/ */