summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Support/Str.php6
-rw-r--r--tests/spec/Google2FASpec.php107
2 files changed, 110 insertions, 3 deletions
diff --git a/src/Support/Str.php b/src/Support/Str.php
index 32ada68..6225f7b 100644
--- a/src/Support/Str.php
+++ b/src/Support/Str.php
@@ -4,13 +4,13 @@ namespace PragmaRX\Google2FA\Support;
class Str
{
- /**
+ /**
* Compares two strings using a constant-time algorithm.
*
* Note: This method will leak length information.
*
- * Note: Extracted from Illuminate\Support\Str.
- *
+ * Note: Extracted from Illuminate\Support\Str.
+ *
* Note: Adapted from Symfony\Component\Security\Core\Util\StringUtils.
*
* @param string $knownString
diff --git a/tests/spec/Google2FASpec.php b/tests/spec/Google2FASpec.php
new file mode 100644
index 0000000..2a5e391
--- /dev/null
+++ b/tests/spec/Google2FASpec.php
@@ -0,0 +1,107 @@
+<?php
+
+namespace spec\PragmaRX\Google2FA;
+
+use Prophecy\Argument;
+use PhpSpec\ObjectBehavior;
+use PragmaRX\Google2FA\Google2FA;
+
+class Google2FASpec extends ObjectBehavior
+{
+ public $secret = 'ADUMJO5634NPDEKW';
+
+ public $url = 'https://chart.googleapis.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth%3A%2F%2Ftotp%2FPragmaRX%3Aacr%2Bpragmarx%40antoniocarlosribeiro.com%3Fsecret%3DADUMJO5634NPDEKW%26issuer%3DPragmaRX';
+
+ function it_is_initializable()
+ {
+ $this->shouldHaveType('PragmaRX\Google2FA\Google2FA');
+ }
+
+ function it_generates_a_valid_secret_key()
+ {
+ $this->generateSecretKey()->shouldHaveLength(16);
+
+ $this->generateSecretKey(17)->shouldHaveLength(17);
+
+ $this->generateSecretKey(17, 'antoniocarlos')->shouldStartWith('MFXHI33ONFXWGYLSNRXXG');
+
+ $this->generateSecretKey()->shouldBeAmongst(Google2FA::VALID_FOR_B32);
+ }
+
+ function it_gets_valid_timestamps()
+ {
+ $this->getTimestamp()->shouldBeValidTimestamp();
+ }
+
+ function it_decodes_base32_strings()
+ {
+ $this->base32Decode($this->secret)->shouldBe(
+ chr(0)
+ . chr(232)
+ . chr(196)
+ . chr(187)
+ . chr(190)
+ . chr(223)
+ . chr(26)
+ . chr(241)
+ . chr(145)
+ . chr(86)
+ );
+ }
+
+ function it_creates_a_one_time_password()
+ {
+ $this->getCurrentOtp($this->secret)->shouldHaveLength(6);
+ }
+
+ function it_verifies_a_key()
+ {
+ // 26213400 = Human time (GMT): Sat, 31 Oct 1970 09:30:00 GMT
+
+ $this->verifyKey($this->secret, '410272', 4, 26213400)->shouldBe(true);
+ }
+
+ function it_removes_invalid_chars_from_secret()
+ {
+ $this->removeInvalidChars($this->secret . '!1-@@@')->shouldBe($this->secret);
+ }
+
+ function it_creates_a_qr_code()
+ {
+ $this->getQRCodeGoogleUrl('PragmaRX', 'acr+pragmarx@antoniocarlosribeiro.com', $this->secret)->shouldBe($this->url);
+ }
+
+ function it_converts_to_base32()
+ {
+ $this->toBase32('PragmaRX')->shouldBe('KBZGCZ3NMFJFQ');
+ }
+
+ public function getMatchers()
+ {
+ return [
+ 'haveLength' => function($subject, $key)
+ {
+ return strlen($subject) == $key;
+ },
+
+ 'shouldStartWith' => function($subject, $key)
+ {
+ return substr($key, 0, strlen($subject)) == $subject;
+ },
+
+ 'beAmongst' => function($subject, $key)
+ {
+ return preg_replace('/[^'.$key.']/', '', $subject) === $subject;
+ },
+
+ 'beValidTimestamp' => function($timestamp)
+ {
+ return is_double($timestamp)
+ && ($timestamp <= PHP_INT_MAX)
+ && ($timestamp >= ~PHP_INT_MAX);
+ },
+
+ ];
+ }
+
+}