diff --git a/phpunit-mysql.xml b/phpunit-mysql.xml index 8f900663..d62d51a3 100644 --- a/phpunit-mysql.xml +++ b/phpunit-mysql.xml @@ -16,6 +16,9 @@ app + + app/Protobuf + diff --git a/phpunit.xml b/phpunit.xml index 53844474..4cc4c0ea 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -16,6 +16,9 @@ app + + app/Protobuf + diff --git a/tests/Classes/OtpTestData.php b/tests/Classes/OtpTestData.php index 5aab0bc8..71980d3d 100644 --- a/tests/Classes/OtpTestData.php +++ b/tests/Classes/OtpTestData.php @@ -6,11 +6,14 @@ class OtpTestData { const ACCOUNT = 'account'; const SERVICE = 'service'; + const STEAM = 'Steam'; const SECRET = 'A4GRFHVVRBGY7UIW'; + const STEAM_SECRET = 'XJGTDRUUKZH3X7TQN2QZUGCGXZCC5LXE'; const ALGORITHM_DEFAULT = 'sha1'; const ALGORITHM_CUSTOM = 'sha256'; const DIGITS_DEFAULT = 6; const DIGITS_CUSTOM = 7; + const DIGITS_STEAM = 5; const PERIOD_DEFAULT = 30; const PERIOD_CUSTOM = 40; const COUNTER_DEFAULT = 0; @@ -23,6 +26,7 @@ class OtpTestData const HOTP_SHORT_URI = 'otpauth://hotp/'.self::ACCOUNT.'?secret='.self::SECRET; const TOTP_URI_WITH_UNREACHABLE_IMAGE = 'otpauth://totp/service:account?secret=A4GRFHVVRBGY7UIW&image=https%3A%2F%2Fen.opensuse.org%2Fimage.png'; const INVALID_OTPAUTH_URI = 'otpauth://Xotp/'.self::ACCOUNT.'?secret='.self::SECRET; + const STEAM_TOTP_URI = 'otpauth://totp/'.self::STEAM.':'.self::ACCOUNT.'?secret='.self::STEAM_SECRET.'&issuer='.self::STEAM.'&digits='.self::DIGITS_STEAM.'&period=30&algorithm='.self::ALGORITHM_DEFAULT; const ARRAY_OF_FULL_VALID_PARAMETERS_FOR_CUSTOM_TOTP = [ 'service' => self::SERVICE, @@ -66,6 +70,16 @@ class OtpTestData 'otp_type' => 'hotp', 'secret' => self::SECRET, ]; + const ARRAY_OF_FULL_VALID_PARAMETERS_FOR_STEAM_TOTP = [ + 'service' => self::STEAM, + 'account' => self::ACCOUNT, + 'otp_type' => 'steamtotp', + 'secret' => self::STEAM_SECRET, + 'digits' => self::DIGITS_STEAM, + 'algorithm' => self::ALGORITHM_DEFAULT, + 'period' => self::PERIOD_DEFAULT, + 'counter' => null, + ]; const GOOGLE_AUTH_MIGRATION_URI = 'otpauth-migration://offline?data=CiQKCgcNEp61iE2P0RYSB2FjY291bnQaB3NlcnZpY2UgASgBMAIKLAoKBw0SnrWITY/RFhILYWNjb3VudF9iaXMaC3NlcnZpY2VfYmlzIAEoATACEAEYASAA'; const INVALID_GOOGLE_AUTH_MIGRATION_URI = 'otpauthmigration://offline?data=CiQKCgcNEp61iE2P0RYSB2FjY291bnQaB3NlcnZpY2UgASgBMAIKLAoKBw0SnrWITY/RFhILYWNjb3VudF9iaXMaC3NlcnZpY2VfYmlzIAEoATACEAEYASAA'; diff --git a/tests/Feature/Console/ResetTestingTest.php b/tests/Feature/Console/ResetTestingTest.php new file mode 100644 index 00000000..ab668924 --- /dev/null +++ b/tests/Feature/Console/ResetTestingTest.php @@ -0,0 +1,166 @@ +artisan('2fauth:reset-testing') + ->expectsOutput('2fauth:reset-testing can only run when isTestingApp option is On') + ->assertExitCode(0); + } + + /** + * @test + */ + public function test_reset_testing_succeeded() + { + Config::set('2fauth.config.isTestingApp', true); + + $this->artisan('2fauth:reset-testing') + ->expectsOutput('This will reset the app in order to run a clean and fresh testing app.') + ->expectsQuestion('To prevent any mistake please type the word "testing" to go on', 'testing') + ->expectsOutput('Testing app refreshed') + ->assertExitCode(0); + + $this->assertDatabaseCount('twofaccounts', 9); + + $this->assertDatabaseHas('twofaccounts', [ + 'otp_type' => 'totp', + 'account' => 'johndoe@facebook.com', + 'service' => 'Facebook', + 'secret' => 'A4GRFTVVRBGY7UIW', + 'algorithm' => 'sha1', + 'digits' => 6, + 'period' => 30, + 'icon' => 'facebook.png', + 'legacy_uri' => 'otpauth://totp/Facebook:johndoe@facebook.com?secret=A4GRFTVVRBGY7UIW', + ]); + $this->assertDatabaseHas('twofaccounts', [ + 'otp_type' => 'totp', + 'service' => 'Twitter', + 'account' => '@john', + 'secret' => 'A2GRFTVVRBGY7UIW', + 'algorithm' => 'sha1', + 'digits' => 6, + 'period' => 30, + 'icon' => 'twitter.png', + 'legacy_uri' => 'otpauth://totp/Twitter:@john?secret=A2GRFTVVRBGY7UIW', + ]); + $this->assertDatabaseHas('twofaccounts', [ + 'otp_type' => 'totp', + 'service' => 'Instagram', + 'account' => '@johndoe', + 'secret' => 'A6GRFTVVRBGY7UIW', + 'algorithm' => 'sha1', + 'digits' => 6, + 'period' => 30, + 'icon' => 'instagram.png', + 'legacy_uri' => 'otpauth://totp/Instagram:@johndoe?secret=A6GRFTVVRBGY7UIW', + ]); + $this->assertDatabaseHas('twofaccounts', [ + 'otp_type' => 'totp', + 'service' => 'LinkedIn', + 'account' => '@johndoe', + 'secret' => 'A7GRFTVVRBGY7UIW', + 'algorithm' => 'sha1', + 'digits' => 6, + 'period' => 30, + 'icon' => 'linkedin.png', + 'legacy_uri' => 'otpauth://totp/LinkedIn:@johndoe?secret=A7GRFTVVRBGY7UIW', + ]); + $this->assertDatabaseHas('twofaccounts', [ + 'otp_type' => 'totp', + 'account' => 'johndoe', + 'service' => 'Amazon', + 'secret' => 'A7GRFTVVRBGY7UIW', + 'algorithm' => 'sha1', + 'digits' => 6, + 'period' => 30, + 'icon' => 'amazon.png', + 'legacy_uri' => 'otpauth://totp/Amazon:johndoe?secret=A7GRFTVVRBGY7UIW', + ]); + $this->assertDatabaseHas('twofaccounts', [ + 'otp_type' => 'totp', + 'account' => 'john.doe@icloud.com', + 'service' => 'Apple', + 'secret' => 'A2GRFTVVRBGY7UIW', + 'algorithm' => 'sha1', + 'digits' => 6, + 'period' => 30, + 'icon' => 'apple.png', + 'legacy_uri' => 'otpauth://totp/Apple:john.doe@icloud.com?secret=A2GRFTVVRBGY7UIW', + ]); + $this->assertDatabaseHas('twofaccounts', [ + 'otp_type' => 'totp', + 'account' => 'john.doe', + 'service' => 'Dropbox', + 'secret' => 'A3GRFTVVRBGY7UIW', + 'algorithm' => 'sha1', + 'digits' => 6, + 'period' => 30, + 'icon' => 'dropbox.png', + 'legacy_uri' => 'otpauth://totp/Dropbox:john.doe?secret=A3GRFTVVRBGY7UIW', + ]); + $this->assertDatabaseHas('twofaccounts', [ + 'otp_type' => 'totp', + 'account' => '@john', + 'service' => 'Github', + 'secret' => 'A2GRFTVVRBGY7UIW', + 'algorithm' => 'sha1', + 'digits' => 6, + 'period' => 30, + 'icon' => 'github.png', + 'legacy_uri' => 'otpauth://totp/Github:@john?secret=A2GRFTVVRBGY7UIW', + ]); + $this->assertDatabaseHas('twofaccounts', [ + 'otp_type' => 'totp', + 'service' => 'Google', + 'account' => 'john.doe@gmail.com', + 'secret' => 'A5GRFTVVRBGY7UIW', + 'algorithm' => 'sha1', + 'digits' => 6, + 'period' => 30, + 'icon' => 'google.png', + 'legacy_uri' => 'otpauth://totp/Google:john.doe@gmail.com?secret=A5GRFTVVRBGY7UIW', + ]); + + } + + + /** + * @test + */ + public function test_reset_testing_with_invalid_confirmation_succeeded() + { + Config::set('2fauth.config.isTestingApp', true); + + $this->artisan('2fauth:reset-testing') + ->expectsQuestion('To prevent any mistake please type the word "testing" to go on', 'null') + ->expectsOutput('Bad confirmation word, nothing appened') + ->assertExitCode(0); + } + + + /** + * @test + */ + public function test_reset_testing_with_no_confirm_option_succeeded() + { + Config::set('2fauth.config.isTestingApp', true); + + $this->artisan('2fauth:reset-testing --no-confirm') + ->expectsOutput('Testing app refreshed') + ->assertExitCode(0); + } + +} \ No newline at end of file diff --git a/tests/Feature/Http/Auth/LoginTest.php b/tests/Feature/Http/Auth/LoginTest.php index e24f557b..32763d4f 100644 --- a/tests/Feature/Http/Auth/LoginTest.php +++ b/tests/Feature/Http/Auth/LoginTest.php @@ -58,9 +58,10 @@ class LoginTest extends FeatureTestCase 'email' => $this->user->email, 'password' => self::PASSWORD ]) - ->assertStatus(400) + ->assertStatus(200) ->assertJson([ - 'message' => __('auth.already_authenticated') + 'message' => 'authenticated', + 'name' => $this->user->name, ]); } diff --git a/tests/Feature/Models/TwoFAccountModelTest.php b/tests/Feature/Models/TwoFAccountModelTest.php index a23f843d..242e5469 100644 --- a/tests/Feature/Models/TwoFAccountModelTest.php +++ b/tests/Feature/Models/TwoFAccountModelTest.php @@ -30,8 +30,6 @@ class TwoFAccountModelTest extends FeatureTestCase { parent::setUp(); - // $this->twofaccountService = $this->app->make('App\Services\TwoFAccountService'); - $this->customTotpTwofaccount = new TwoFAccount; $this->customTotpTwofaccount->legacy_uri = OtpTestData::TOTP_FULL_CUSTOM_URI; $this->customTotpTwofaccount->service = OtpTestData::SERVICE; @@ -58,10 +56,17 @@ class TwoFAccountModelTest extends FeatureTestCase $this->customHotpTwofaccount->counter = OtpTestData::COUNTER_CUSTOM; $this->customHotpTwofaccount->save(); - - // $this->group = new Group; - // $this->group->name = 'MyGroup'; - // $this->group->save(); + $this->customSteamTotpTwofaccount = new TwoFAccount; + $this->customSteamTotpTwofaccount->legacy_uri = OtpTestData::STEAM_TOTP_URI; + $this->customSteamTotpTwofaccount->service = OtpTestData::STEAM; + $this->customSteamTotpTwofaccount->account = OtpTestData::ACCOUNT; + $this->customSteamTotpTwofaccount->otp_type = 'steamtotp'; + $this->customSteamTotpTwofaccount->secret = OtpTestData::STEAM_SECRET; + $this->customSteamTotpTwofaccount->digits = OtpTestData::DIGITS_STEAM; + $this->customSteamTotpTwofaccount->algorithm = OtpTestData::ALGORITHM_DEFAULT; + $this->customSteamTotpTwofaccount->period = OtpTestData::PERIOD_DEFAULT; + $this->customSteamTotpTwofaccount->counter = null; + $this->customSteamTotpTwofaccount->save(); } @@ -446,6 +451,29 @@ class TwoFAccountModelTest extends FeatureTestCase } + /** + * @test + */ + public function test_getOTP_for_steamtotp_returns_the_same_password() + { + $twofaccount = new TwoFAccount; + + $otp_from_model = $this->customSteamTotpTwofaccount->getOTP(); + $otp_from_uri = $twofaccount->fillWithURI(OtpTestData::STEAM_TOTP_URI)->getOTP(); + + if ($otp_from_model->generated_at === $otp_from_uri->generated_at) { + $this->assertEquals($otp_from_model, $otp_from_uri); + } + + $otp_from_model = $this->customSteamTotpTwofaccount->getOTP(); + $otp_from_parameters = $twofaccount->fillWithOtpParameters(OtpTestData::ARRAY_OF_FULL_VALID_PARAMETERS_FOR_STEAM_TOTP)->getOTP(); + + if ($otp_from_model->generated_at === $otp_from_parameters->generated_at) { + $this->assertEquals($otp_from_model, $otp_from_parameters); + } + } + + /** * @test */