refactor: replace custom CRM with Monica fork
Some checks failed
Build & Push Monica Image to Gitea Registry / build-and-push (push) Failing after 9s
Some checks failed
Build & Push Monica Image to Gitea Registry / build-and-push (push) Failing after 9s
This commit is contained in:
342
tests/Browser/Settings/MultiFAControllerTest.php
Normal file
342
tests/Browser/Settings/MultiFAControllerTest.php
Normal file
@@ -0,0 +1,342 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Browser\Settings;
|
||||
|
||||
use Zxing\QrReader;
|
||||
use Tests\DuskTestCase;
|
||||
use Laravel\Dusk\Browser;
|
||||
use Illuminate\Console\Application;
|
||||
use Tests\Browser\Pages\SettingsSecurity;
|
||||
use Tests\Browser\Pages\DashboardValidate2fa;
|
||||
|
||||
class MultiFAControllerTest extends DuskTestCase
|
||||
{
|
||||
/**
|
||||
* Cleanup.
|
||||
*/
|
||||
public function cleanup()
|
||||
{
|
||||
exec(Application::formatCommandString('2fa:deactivate --force --email=admin@admin.com'), $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the user has 2fa Enable Link in Security Page.
|
||||
*
|
||||
* @group multifa
|
||||
*/
|
||||
public function testHasSettings2faEnableLink()
|
||||
{
|
||||
$this->browse(function (Browser $browser) {
|
||||
$browser->login()
|
||||
->visit(new SettingsSecurity)
|
||||
->assertSeeLink('Enable Two Factor Authentication');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the user has WebAuthn Enable Link in Security Page.
|
||||
*
|
||||
* @group multifa
|
||||
*/
|
||||
public function testHasSettingsWebAuthnEnableLink()
|
||||
{
|
||||
$this->browse(function (Browser $browser) {
|
||||
$browser->login()
|
||||
->visit(new SettingsSecurity)
|
||||
->assertSeeLink('Add a new security key');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the barcode generated in 2fa Enable Page.
|
||||
*
|
||||
* @group multifa
|
||||
*/
|
||||
public function testHas2faEnableBarCode()
|
||||
{
|
||||
$this->markTestIncomplete('Ignore 2fa tests for now.');
|
||||
|
||||
$this->browse(function (Browser $browser) {
|
||||
$browser->login()
|
||||
->visit(new SettingsSecurity)
|
||||
->scrollTo('two_factor_link')
|
||||
->clickLink('Enable Two Factor Authentication')
|
||||
->waitFor('enableModal')
|
||||
->assertVisible('barcode')
|
||||
->assertVisible('secretkey');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the barcode generated in 2fa Enable Page.
|
||||
*
|
||||
* @group multifa
|
||||
* @group multifabarcode
|
||||
*/
|
||||
public function testBarCodeContent()
|
||||
{
|
||||
$this->markTestIncomplete('Ignore 2fa tests for now.');
|
||||
|
||||
$this->browse(function (Browser $browser) {
|
||||
$browser =
|
||||
$browser->login()
|
||||
->visit(new SettingsSecurity)
|
||||
->scrollTo('two_factor_link')
|
||||
->clickLink('Enable Two Factor Authentication')
|
||||
->waitFor('enableModal');
|
||||
|
||||
// \Facebook\WebDriver\Remote\RemoteWebElement
|
||||
$barcode = $browser->element('barcode');
|
||||
$imgsrc = $barcode->getAttribute('src');
|
||||
|
||||
$key = $this->unparseBarcode($imgsrc);
|
||||
$this->assertEquals(32, strlen($key));
|
||||
|
||||
$this->assertEquals($browser->text('secretkey'), $key);
|
||||
});
|
||||
}
|
||||
|
||||
private function unparseBarcode($imgsrc)
|
||||
{
|
||||
$this->assertStringStartsWith('data:image/png', $imgsrc);
|
||||
|
||||
$imgcode = str_replace('data:image/png;base64,', '', $imgsrc);
|
||||
|
||||
$qrcode = new QrReader(base64_decode($imgcode), QrReader::SOURCE_TYPE_BLOB);
|
||||
$text = $qrcode->text();
|
||||
$this->assertStringStartsWith('otpauth://totp/', $text);
|
||||
|
||||
// unparse $text
|
||||
// See PragmaRX\Google2FA\Support\QRCode getQRCodeUrl
|
||||
// example :
|
||||
//otpauth://totp/monicalocal.test:admin%40admin.com?secret=H25L7JLI7I57KYE7U53BIIOUELWXMRE6&issuer=monicalocal.test
|
||||
|
||||
$ret = preg_match('@^otpauth://totp/([^:]+):([^?]+)\?secret=([^&]+)&issuer=(.+)@i', $text, $matches);
|
||||
$this->assertEquals(1, $ret, 'otp content does not match format');
|
||||
$this->assertCount(5, $matches);
|
||||
|
||||
return $matches[3];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the 2fa Enable Page with wrong code.
|
||||
*
|
||||
* @group multifa
|
||||
*/
|
||||
public function testEnable2faWrongCode()
|
||||
{
|
||||
$this->markTestIncomplete('Ignore 2fa tests for now.');
|
||||
|
||||
$this->browse(function (Browser $browser) {
|
||||
$browser =
|
||||
$browser->login()
|
||||
->visit(new SettingsSecurity)
|
||||
->scrollTo('two_factor_link')
|
||||
->clickLink('Enable Two Factor Authentication')
|
||||
->waitFor('enableModal')
|
||||
->type('otpenable', '000000')
|
||||
->scrollTo('enableVerify')
|
||||
->press('enableVerify')
|
||||
->waitUntilMissing('enableModal');
|
||||
|
||||
$this->assertTrue($this->hasNotification($browser));
|
||||
$notification = $this->getNotification($browser);
|
||||
$this->assertStringContainsString('error', $notification->getAttribute('class'));
|
||||
$this->assertStringContainsString('Two Factor Authentication', $notification->getText());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the 2fa Enable Page.
|
||||
*
|
||||
* @group multifa
|
||||
*/
|
||||
public function testEnable2fa()
|
||||
{
|
||||
$this->markTestIncomplete('Ignore 2fa tests for now.');
|
||||
|
||||
$this->browse(function (Browser $browser) {
|
||||
$browser =
|
||||
$browser->login()
|
||||
->visit(new SettingsSecurity)
|
||||
->scrollTo('two_factor_link')
|
||||
->clickLink('Enable Two Factor Authentication')
|
||||
->waitFor('enableModal');
|
||||
|
||||
$this->enable2fa($browser);
|
||||
});
|
||||
}
|
||||
|
||||
private function enable2fa(Browser $browser)
|
||||
{
|
||||
$secretkey = $browser->waitFor('enableModal')
|
||||
->text('secretkey');
|
||||
|
||||
$google2fa = new \PragmaRX\Google2FA\Google2FA();
|
||||
$one_time_password = $google2fa->getCurrentOtp($secretkey);
|
||||
$browser->type('otpenable', $one_time_password);
|
||||
|
||||
$browser = $browser->scrollTo('enableVerify')
|
||||
->press('enableVerify')
|
||||
->waitUntilMissing('enableModal');
|
||||
|
||||
$this->assertTrue($this->hasNotification($browser));
|
||||
$notification = $this->getNotification($browser);
|
||||
$this->assertStringContainsString('success', $notification->getAttribute('class'));
|
||||
$this->assertStringContainsString('Two Factor Authentication', $notification->getText());
|
||||
|
||||
// TODO: test if user has 2fa enabled actually
|
||||
// TODO: test if session token auth is right
|
||||
|
||||
$browser->assertSeeLink('Disable Two Factor Authentication');
|
||||
|
||||
return $secretkey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the 2fa Enable Page.
|
||||
*
|
||||
* @group multifa
|
||||
*/
|
||||
public function testEnable2faLoginWrongCode()
|
||||
{
|
||||
$this->markTestIncomplete('Ignore 2fa tests for now.');
|
||||
|
||||
$user = call_user_func(Browser::$userResolver);
|
||||
|
||||
$this->browse(function (Browser $browser) use ($user) {
|
||||
$browser =
|
||||
$browser->loginAs($user)
|
||||
->visit(new SettingsSecurity)
|
||||
->scrollTo('two_factor_link')
|
||||
->clickLink('Enable Two Factor Authentication')
|
||||
->waitFor('enableModal');
|
||||
|
||||
$secretkey = $this->enable2fa($browser);
|
||||
|
||||
$browser =
|
||||
$browser->clickLink('Logout')
|
||||
->loginAs($user)
|
||||
->visit(new DashboardValidate2fa)
|
||||
->assertVisible('otp')
|
||||
->type('otp', '000000')
|
||||
->press('verify');
|
||||
|
||||
$this->assertTrue($this->hasDivAlert($browser));
|
||||
$notification = $this->getDivAlert($browser);
|
||||
$this->assertStringContainsString('alert-danger', $notification->getAttribute('class'));
|
||||
$this->assertStringContainsString('The two factor authentication has failed.', $notification->getText());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the 2fa Enable Page.
|
||||
*
|
||||
* @group multifa
|
||||
*/
|
||||
public function testEnable2faLogin()
|
||||
{
|
||||
$this->markTestIncomplete('Ignore 2fa tests for now.');
|
||||
|
||||
$user = call_user_func(Browser::$userResolver);
|
||||
|
||||
$this->browse(function (Browser $browser) use ($user) {
|
||||
$browser =
|
||||
$browser->loginAs($user)
|
||||
->visit(new SettingsSecurity)
|
||||
->scrollTo('two_factor_link')
|
||||
->clickLink('Enable Two Factor Authentication')
|
||||
->waitFor('enableModal');
|
||||
|
||||
$secretkey = $this->enable2fa($browser);
|
||||
$google2fa = new \PragmaRX\Google2FA\Google2FA();
|
||||
$one_time_password = $google2fa->getCurrentOtp($secretkey);
|
||||
|
||||
$browser =
|
||||
$browser->clickLink('Logout')
|
||||
->loginAs($user)
|
||||
->visit(new DashboardValidate2fa)
|
||||
->assertVisible('otp')
|
||||
->type('otp', $one_time_password)
|
||||
->press('verify');
|
||||
|
||||
$this->assertFalse($this->hasDivAlert($browser));
|
||||
$browser->assertPathIs('/dashboard');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test 2fa Enable Page and Disable Page.
|
||||
*
|
||||
* @group multifa
|
||||
*/
|
||||
public function testEnable2faDisable2fa()
|
||||
{
|
||||
$this->markTestIncomplete('Ignore 2fa tests for now.');
|
||||
|
||||
$this->browse(function (Browser $browser) {
|
||||
$browser =
|
||||
$browser->login()
|
||||
->visit(new SettingsSecurity)
|
||||
->scrollTo('two_factor_link')
|
||||
->clickLink('Enable Two Factor Authentication')
|
||||
->waitFor('enableModal');
|
||||
|
||||
$secretkey = $this->enable2fa($browser);
|
||||
$google2fa = new \PragmaRX\Google2FA\Google2FA();
|
||||
$one_time_password = $google2fa->getCurrentOtp($secretkey);
|
||||
|
||||
$browser =
|
||||
$browser->clickLink('Disable Two Factor Authentication')
|
||||
->waitFor('disableModal')
|
||||
->assertVisible('otpdisable')
|
||||
->type('otpdisable', $one_time_password)
|
||||
->scrollTo('disableVerify')
|
||||
->press('disableVerify')
|
||||
->waitUntilMissing('enableModal');
|
||||
|
||||
$this->assertTrue($this->hasNotification($browser));
|
||||
$notification = $this->getNotification($browser);
|
||||
$this->assertStringContainsString('success', $notification->getAttribute('class'));
|
||||
$this->assertStringContainsString('Two Factor Authentication', $notification->getText());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test 2fa Enable Page and Disable Page.
|
||||
*
|
||||
* @group multifa
|
||||
*/
|
||||
public function testEnable2faDisable2faWrongCode()
|
||||
{
|
||||
$this->markTestIncomplete('Ignore 2fa tests for now.');
|
||||
|
||||
$this->browse(function (Browser $browser) {
|
||||
$browser =
|
||||
$browser->login()
|
||||
->visit(new SettingsSecurity)
|
||||
->scrollTo('two_factor_link')
|
||||
->clickLink('Enable Two Factor Authentication')
|
||||
->waitFor('enableModal');
|
||||
|
||||
$this->enable2fa($browser);
|
||||
|
||||
$browser =
|
||||
$browser->clickLink('Disable Two Factor Authentication')
|
||||
->waitFor('disableModal')
|
||||
->assertVisible('otpdisable')
|
||||
->type('otpdisable', '000000')
|
||||
->scrollTo('disableVerify')
|
||||
->press('disableVerify')
|
||||
->waitUntilMissing('disableModal');
|
||||
|
||||
$this->assertTrue($this->hasNotification($browser));
|
||||
|
||||
$res = $browser->elements('.notification');
|
||||
$notification = $res[1];
|
||||
|
||||
$this->assertStringContainsString('error', $notification->getAttribute('class'));
|
||||
$this->assertStringContainsString('Two Factor Authentication', $notification->getText());
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user