git subrepo commit (merge) mailcow/src/mailcow-dockerized

subrepo: subdir:   "mailcow/src/mailcow-dockerized"
  merged:   "02ae5285"
upstream: origin:   "https://github.com/mailcow/mailcow-dockerized.git"
  branch:   "master"
  commit:   "649a5c01"
git-subrepo: version:  "0.4.3"
  origin:   "???"
  commit:   "???"
Change-Id: I870ad468fba026cc5abf3c5699ed1e12ff28b32b
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/MightNotMakeAssertions.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/MightNotMakeAssertions.php
new file mode 100644
index 0000000..a7fbded
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/MightNotMakeAssertions.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace Tests;
+
+trait MightNotMakeAssertions
+{
+    /**
+     * This is a shim to support PHPUnit for php 5.6 and 7.0.
+     *
+     * It has to be named something that doesn't collide with existing
+     * TestCase methods as we can't support PHP return types right now
+     *
+     * @return void
+     */
+    public function noAssertionsMade()
+    {
+        foreach (class_parents($this) as $parent) {
+            if (method_exists($parent, 'expectNotToPerformAssertions')) {
+                parent::expectNotToPerformAssertions();
+                return;
+            }
+        }
+
+        $this->assertTrue(true);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Qr/IQRCodeProviderTest.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Qr/IQRCodeProviderTest.php
new file mode 100644
index 0000000..86dd431
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Qr/IQRCodeProviderTest.php
@@ -0,0 +1,56 @@
+<?php
+
+namespace Tests\Providers\Qr;
+
+use PHPUnit\Framework\TestCase;
+use RobThree\Auth\TwoFactorAuth;
+use RobThree\Auth\TwoFactorAuthException;
+
+class IQRCodeProviderTest extends TestCase
+{
+    /**
+     * @param string $datauri
+     *
+     * @return null|array
+     */
+    private function DecodeDataUri($datauri)
+    {
+        if (preg_match('/data:(?P<mimetype>[\w\.\-\/]+);(?P<encoding>\w+),(?P<data>.*)/', $datauri, $m) === 1) {
+            return array(
+                'mimetype' => $m['mimetype'],
+                'encoding' => $m['encoding'],
+                'data' => base64_decode($m['data'])
+            );
+        }
+
+        return null;
+    }
+
+    /**
+     * @return void
+     */
+    public function testTotpUriIsCorrect()
+    {
+        $qr = new TestQrProvider();
+
+        $tfa = new TwoFactorAuth('Test&Issuer', 6, 30, 'sha1', $qr);
+        $data = $this->DecodeDataUri($tfa->getQRCodeImageAsDataUri('Test&Label', 'VMR466AB62ZBOKHE'));
+        $this->assertEquals('test/test', $data['mimetype']);
+        $this->assertEquals('base64', $data['encoding']);
+        $this->assertEquals('otpauth://totp/Test%26Label?secret=VMR466AB62ZBOKHE&issuer=Test%26Issuer&period=30&algorithm=SHA1&digits=6@200', $data['data']);
+    }
+
+    /**
+     * @return void
+     */
+    public function testGetQRCodeImageAsDataUriThrowsOnInvalidSize()
+    {
+        $qr = new TestQrProvider();
+
+        $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', $qr);
+
+        $this->expectException(TwoFactorAuthException::class);
+
+        $tfa->getQRCodeImageAsDataUri('Test', 'VMR466AB62ZBOKHE', 0);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Qr/TestQrProvider.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Qr/TestQrProvider.php
new file mode 100644
index 0000000..93242c2
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Qr/TestQrProvider.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace Tests\Providers\Qr;
+
+use RobThree\Auth\Providers\Qr\IQRCodeProvider;
+
+class TestQrProvider implements IQRCodeProvider
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function getQRCodeImage($qrtext, $size)
+    {
+        return $qrtext . '@' . $size;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMimeType()
+    {
+        return 'test/test';
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Rng/CSRNGProviderTest.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Rng/CSRNGProviderTest.php
new file mode 100644
index 0000000..e42ccfd
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Rng/CSRNGProviderTest.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Tests\Providers\Rng;
+
+use PHPUnit\Framework\TestCase;
+use Tests\MightNotMakeAssertions;
+use RobThree\Auth\Providers\Rng\CSRNGProvider;
+
+class CSRNGProviderTest extends TestCase
+{
+    use NeedsRngLengths, MightNotMakeAssertions;
+
+    /**
+     * @requires function random_bytes
+     *
+     * @return void
+     */
+    public function testCSRNGProvidersReturnExpectedNumberOfBytes()
+    {
+        if (function_exists('random_bytes')) {
+            $rng = new CSRNGProvider();
+            foreach ($this->rngTestLengths as $l) {
+                $this->assertEquals($l, strlen($rng->getRandomBytes($l)));
+            }
+            $this->assertTrue($rng->isCryptographicallySecure());
+        } else {
+            $this->noAssertionsMade();
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Rng/HashRNGProviderTest.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Rng/HashRNGProviderTest.php
new file mode 100644
index 0000000..c99879d
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Rng/HashRNGProviderTest.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace Tests\Providers\Rng;
+
+use PHPUnit\Framework\TestCase;
+use RobThree\Auth\Providers\Rng\HashRNGProvider;
+
+class HashRNGProviderTest extends TestCase
+{
+    use NeedsRngLengths;
+
+    /**
+     * @return void
+     */
+    public function testHashRNGProvidersReturnExpectedNumberOfBytes()
+    {
+        $rng = new HashRNGProvider();
+        foreach ($this->rngTestLengths as $l) {
+            $this->assertEquals($l, strlen($rng->getRandomBytes($l)));
+        }
+
+        $this->assertFalse($rng->isCryptographicallySecure());
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Rng/IRNGProviderTest.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Rng/IRNGProviderTest.php
new file mode 100644
index 0000000..8897673
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Rng/IRNGProviderTest.php
@@ -0,0 +1,61 @@
+<?php
+
+namespace Tests\Providers\Rng;
+
+use PHPUnit\Framework\TestCase;
+use RobThree\Auth\TwoFactorAuth;
+use RobThree\Auth\TwoFactorAuthException;
+
+class IRNGProviderTest extends TestCase
+{
+    /**
+     * @return void
+     */
+    public function testCreateSecretThrowsOnInsecureRNGProvider()
+    {
+        $rng = new TestRNGProvider();
+
+        $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', null, $rng);
+
+        $this->expectException(TwoFactorAuthException::class);
+        $tfa->createSecret();
+    }
+
+    /**
+     * @return void
+     */
+    public function testCreateSecretOverrideSecureDoesNotThrowOnInsecureRNG()
+    {
+        $rng = new TestRNGProvider();
+
+        $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', null, $rng);
+        $this->assertEquals('ABCDEFGHIJKLMNOP', $tfa->createSecret(80, false));
+    }
+
+    /**
+     * @return void
+     */
+    public function testCreateSecretDoesNotThrowOnSecureRNGProvider()
+    {
+        $rng = new TestRNGProvider(true);
+
+        $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', null, $rng);
+        $this->assertEquals('ABCDEFGHIJKLMNOP', $tfa->createSecret());
+    }
+
+    /**
+     * @return void
+     */
+    public function testCreateSecretGeneratesDesiredAmountOfEntropy()
+    {
+        $rng = new TestRNGProvider(true);
+
+        $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', null, $rng);
+        $this->assertEquals('A', $tfa->createSecret(5));
+        $this->assertEquals('AB', $tfa->createSecret(6));
+        $this->assertEquals('ABCDEFGHIJKLMNOPQRSTUVWXYZ', $tfa->createSecret(128));
+        $this->assertEquals('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', $tfa->createSecret(160));
+        $this->assertEquals('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', $tfa->createSecret(320));
+        $this->assertEquals('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567ABCDEFGHIJKLMNOPQRSTUVWXYZ234567A', $tfa->createSecret(321));
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Rng/MCryptRNGProviderTest.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Rng/MCryptRNGProviderTest.php
new file mode 100644
index 0000000..f6dd91e
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Rng/MCryptRNGProviderTest.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace Tests\Providers\Rng;
+
+use PHPUnit\Framework\TestCase;
+use Tests\MightNotMakeAssertions;
+use RobThree\Auth\Providers\Rng\MCryptRNGProvider;
+
+class MCryptRNGProviderTest extends TestCase
+{
+    use NeedsRngLengths, MightNotMakeAssertions;
+
+    /**
+     * @requires function mcrypt_create_iv
+     *
+     * @return void
+     */
+    public function testMCryptRNGProvidersReturnExpectedNumberOfBytes()
+    {
+        if (function_exists('mcrypt_create_iv')) {
+            $rng = new MCryptRNGProvider();
+
+            foreach ($this->rngTestLengths as $l) {
+                $this->assertEquals($l, strlen($rng->getRandomBytes($l)));
+            }
+
+            $this->assertTrue($rng->isCryptographicallySecure());
+        } else {
+            $this->noAssertionsMade();
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Rng/NeedsRngLengths.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Rng/NeedsRngLengths.php
new file mode 100644
index 0000000..7bbfed9
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Rng/NeedsRngLengths.php
@@ -0,0 +1,9 @@
+<?php
+
+namespace Tests\Providers\Rng;
+
+trait NeedsRngLengths
+{
+    /** @var array */
+    protected $rngTestLengths = array(1, 16, 32, 256);
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Rng/OpenSSLRNGProviderTest.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Rng/OpenSSLRNGProviderTest.php
new file mode 100644
index 0000000..c941fcc
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Rng/OpenSSLRNGProviderTest.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace Tests\Providers\Rng;
+
+use PHPUnit\Framework\TestCase;
+use RobThree\Auth\Providers\Rng\OpenSSLRNGProvider;
+
+class OpenSSLRNGProviderTest extends TestCase
+{
+    use NeedsRngLengths;
+
+    /**
+     * @return void
+     */
+    public function testStrongOpenSSLRNGProvidersReturnExpectedNumberOfBytes()
+    {
+        $rng = new OpenSSLRNGProvider(true);
+        foreach ($this->rngTestLengths as $l) {
+            $this->assertEquals($l, strlen($rng->getRandomBytes($l)));
+        }
+
+        $this->assertTrue($rng->isCryptographicallySecure());
+    }
+
+    /**
+     * @return void
+     */
+    public function testNonStrongOpenSSLRNGProvidersReturnExpectedNumberOfBytes()
+    {
+        $rng = new OpenSSLRNGProvider(false);
+        foreach ($this->rngTestLengths as $l) {
+            $this->assertEquals($l, strlen($rng->getRandomBytes($l)));
+        }
+
+        $this->assertFalse($rng->isCryptographicallySecure());
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Rng/TestRNGProvider.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Rng/TestRNGProvider.php
new file mode 100644
index 0000000..7179521
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Rng/TestRNGProvider.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace Tests\Providers\Rng;
+
+use RobThree\Auth\Providers\Rng\IRNGProvider;
+
+class TestRNGProvider implements IRNGProvider
+{
+    /** @var bool */
+    private $isSecure;
+
+    /**
+     * @param bool $isSecure whether this provider is cryptographically secure
+     */
+    function __construct($isSecure = false)
+    {
+        $this->isSecure = $isSecure;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getRandomBytes($bytecount)
+    {
+        $result = '';
+
+        for ($i = 0; $i < $bytecount; $i++) {
+            $result .= chr($i);
+        }
+
+        return $result;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isCryptographicallySecure()
+    {
+        return $this->isSecure;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Time/ITimeProviderTest.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Time/ITimeProviderTest.php
new file mode 100644
index 0000000..159e0c8
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Time/ITimeProviderTest.php
@@ -0,0 +1,53 @@
+<?php
+
+namespace Tests\Providers\Time;
+
+use PHPUnit\Framework\TestCase;
+use Tests\MightNotMakeAssertions;
+use RobThree\Auth\TwoFactorAuthException;
+use RobThree\Auth\TwoFactorAuth;
+
+class ITimeProviderTest extends TestCase
+{
+    use MightNotMakeAssertions;
+
+    /**
+     * @return void
+     */
+    public function testEnsureCorrectTimeDoesNotThrowForCorrectTime()
+    {
+        $tpr1 = new TestTimeProvider(123);
+        $tpr2 = new TestTimeProvider(128);
+
+        $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', null, null, $tpr1);
+        $tfa->ensureCorrectTime(array($tpr2));   // 128 - 123 = 5 => within default leniency
+
+        $this->noAssertionsMade();
+    }
+
+    /**
+     * @return void
+     */
+    public function testEnsureCorrectTimeThrowsOnIncorrectTime()
+    {
+        $tpr1 = new TestTimeProvider(123);
+        $tpr2 = new TestTimeProvider(124);
+
+        $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', null, null, $tpr1);
+
+        $this->expectException(TwoFactorAuthException::class);
+
+        $tfa->ensureCorrectTime(array($tpr2), 0);    // We force a leniency of 0, 124-123 = 1 so this should throw
+    }
+
+    /**
+     * @return void
+     */
+    public function testEnsureDefaultTimeProviderReturnsCorrectTime()
+    {
+        $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1');
+        $tfa->ensureCorrectTime(array(new TestTimeProvider(time())), 1);    // Use a leniency of 1, should the time change between both time() calls
+
+        $this->noAssertionsMade();
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Time/TestTimeProvider.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Time/TestTimeProvider.php
new file mode 100644
index 0000000..0fc2d12
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/Providers/Time/TestTimeProvider.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Tests\Providers\Time;
+
+use RobThree\Auth\Providers\Time\ITimeProvider;
+
+class TestTimeProvider implements ITimeProvider
+{
+    /** @var int */
+    private $time;
+
+    /**
+     * @param int $time
+     */
+    function __construct($time)
+    {
+        $this->time = $time;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getTime()
+    {
+        return $this->time;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/TwoFactorAuthTest.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/TwoFactorAuthTest.php
index a0f2f67..ca00df9 100644
--- a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/TwoFactorAuthTest.php
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/tests/TwoFactorAuthTest.php
@@ -1,218 +1,151 @@
 <?php
-require_once 'lib/TwoFactorAuth.php';
-require_once 'lib/TwoFactorAuthException.php';
 
-require_once 'lib/Providers/Qr/IQRCodeProvider.php';
-require_once 'lib/Providers/Qr/BaseHTTPQRCodeProvider.php';
-require_once 'lib/Providers/Qr/ImageChartsQRCodeProvider.php';
-require_once 'lib/Providers/Qr/QRException.php';
+namespace Tests;
 
-require_once 'lib/Providers/Rng/IRNGProvider.php';
-require_once 'lib/Providers/Rng/RNGException.php';
-require_once 'lib/Providers/Rng/CSRNGProvider.php';
-require_once 'lib/Providers/Rng/MCryptRNGProvider.php';
-require_once 'lib/Providers/Rng/OpenSSLRNGProvider.php';
-require_once 'lib/Providers/Rng/HashRNGProvider.php';
-require_once 'lib/Providers/Rng/RNGException.php';
-
-require_once 'lib/Providers/Time/ITimeProvider.php';
-require_once 'lib/Providers/Time/LocalMachineTimeProvider.php';
-require_once 'lib/Providers/Time/HttpTimeProvider.php';
-require_once 'lib/Providers/Time/NTPTimeProvider.php';
-require_once 'lib/Providers/Time/TimeException.php';
-
+use PHPUnit\Framework\TestCase;
+use RobThree\Auth\TwoFactorAuthException;
 use RobThree\Auth\TwoFactorAuth;
-use RobThree\Auth\Providers\Qr\IQRCodeProvider;
-use RobThree\Auth\Providers\Rng\IRNGProvider;
-use RobThree\Auth\Providers\Time\ITimeProvider;
 
-
-class TwoFactorAuthTest extends PHPUnit_Framework_TestCase
+class TwoFactorAuthTest extends TestCase
 {
+    use MightNotMakeAssertions;
+
     /**
-     * @expectedException \RobThree\Auth\TwoFactorAuthException
+     * @return void
      */
-    public function testConstructorThrowsOnInvalidDigits() {
+    public function testConstructorThrowsOnInvalidDigits()
+    {
+        $this->expectException(TwoFactorAuthException::class);
 
         new TwoFactorAuth('Test', 0);
     }
 
     /**
-     * @expectedException \RobThree\Auth\TwoFactorAuthException
+     * @return void
      */
-    public function testConstructorThrowsOnInvalidPeriod() {
+    public function testConstructorThrowsOnInvalidPeriod()
+    {
+        $this->expectException(TwoFactorAuthException::class);
 
         new TwoFactorAuth('Test', 6, 0);
     }
 
     /**
-     * @expectedException \RobThree\Auth\TwoFactorAuthException
+     * @return void
      */
-    public function testConstructorThrowsOnInvalidAlgorithm() {
+    public function testConstructorThrowsOnInvalidAlgorithm()
+    {
+        $this->expectException(TwoFactorAuthException::class);
 
         new TwoFactorAuth('Test', 6, 30, 'xxx');
     }
 
-    public function testGetCodeReturnsCorrectResults() {
-
+    /**
+     * @return void
+     */
+    public function testGetCodeReturnsCorrectResults()
+    {
         $tfa = new TwoFactorAuth('Test');
         $this->assertEquals('543160', $tfa->getCode('VMR466AB62ZBOKHE', 1426847216));
         $this->assertEquals('538532', $tfa->getCode('VMR466AB62ZBOKHE', 0));
     }
 
     /**
-     * @expectedException \RobThree\Auth\TwoFactorAuthException
+     * @return void
      */
-    public function testCreateSecretThrowsOnInsecureRNGProvider() {
-        $rng = new TestRNGProvider();
-
-        $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', null, $rng);
-        $tfa->createSecret();
-    }
-
-    public function testCreateSecretOverrideSecureDoesNotThrowOnInsecureRNG() {
-        $rng = new TestRNGProvider();
-
-        $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', null, $rng);
-        $this->assertEquals('ABCDEFGHIJKLMNOP', $tfa->createSecret(80, false));
-    }
-
-    public function testCreateSecretDoesNotThrowOnSecureRNGProvider() {
-        $rng = new TestRNGProvider(true);
-
-        $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', null, $rng);
-        $this->assertEquals('ABCDEFGHIJKLMNOP', $tfa->createSecret());
-    }
-
-    public function testCreateSecretGeneratesDesiredAmountOfEntropy() {
-        $rng = new TestRNGProvider(true);
-
-        $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', null, $rng);
-        $this->assertEquals('A', $tfa->createSecret(5));
-        $this->assertEquals('AB', $tfa->createSecret(6));
-        $this->assertEquals('ABCDEFGHIJKLMNOPQRSTUVWXYZ', $tfa->createSecret(128));
-        $this->assertEquals('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', $tfa->createSecret(160));
-        $this->assertEquals('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', $tfa->createSecret(320));
-        $this->assertEquals('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567ABCDEFGHIJKLMNOPQRSTUVWXYZ234567A', $tfa->createSecret(321));
-    }
-
-    public function testEnsureCorrectTimeDoesNotThrowForCorrectTime() {
-        $tpr1 = new TestTimeProvider(123);
-        $tpr2 = new TestTimeProvider(128);
-
-        $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', null, null, $tpr1);
-        $tfa->ensureCorrectTime(array($tpr2));   // 128 - 123 = 5 => within default leniency
+    public function testEnsureAllTimeProvidersReturnCorrectTime()
+    {
+        $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1');
+        $tfa->ensureCorrectTime(array(
+            new \RobThree\Auth\Providers\Time\NTPTimeProvider(),                         // Uses pool.ntp.org by default
+            //new \RobThree\Auth\Providers\Time\NTPTimeProvider('time.google.com'),      // Somehow time.google.com and time.windows.com make travis timeout??
+            new \RobThree\Auth\Providers\Time\HttpTimeProvider(),                        // Uses google.com by default
+            new \RobThree\Auth\Providers\Time\HttpTimeProvider('https://github.com'),
+            new \RobThree\Auth\Providers\Time\HttpTimeProvider('https://yahoo.com'),
+        ));
+        $this->noAssertionsMade();
     }
 
     /**
-     * @expectedException \RobThree\Auth\TwoFactorAuthException
+     * @return void
      */
-    public function testEnsureCorrectTimeThrowsOnIncorrectTime() {
-        $tpr1 = new TestTimeProvider(123);
-        $tpr2 = new TestTimeProvider(124);
-
-        $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', null, null, $tpr1);
-        $tfa->ensureCorrectTime(array($tpr2), 0);    // We force a leniency of 0, 124-123 = 1 so this should throw
-    }
-
-
-    public function testEnsureDefaultTimeProviderReturnsCorrectTime() {
-        $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1');
-        $tfa->ensureCorrectTime(array(new TestTimeProvider(time())), 1);    // Use a leniency of 1, should the time change between both time() calls
-    }
-
-    public function testEnsureAllTimeProvidersReturnCorrectTime() {
-        $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1');
-        $tfa->ensureCorrectTime(array(
-            new RobThree\Auth\Providers\Time\NTPTimeProvider(),                         // Uses pool.ntp.org by default
-            //new RobThree\Auth\Providers\Time\NTPTimeProvider('time.google.com'),      // Somehow time.google.com and time.windows.com make travis timeout??
-            new RobThree\Auth\Providers\Time\HttpTimeProvider(),                        // Uses google.com by default
-            new RobThree\Auth\Providers\Time\HttpTimeProvider('https://github.com'),
-            new RobThree\Auth\Providers\Time\HttpTimeProvider('https://yahoo.com'),
-        ));
-    }
-
-    public function testVerifyCodeWorksCorrectly() {
-
+    public function testVerifyCodeWorksCorrectly()
+    {
         $tfa = new TwoFactorAuth('Test', 6, 30);
-        $this->assertEquals(true , $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847190));
-        $this->assertEquals(true , $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 0, 1426847190 + 29));	//Test discrepancy
-        $this->assertEquals(false, $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 0, 1426847190 + 30));	//Test discrepancy
-        $this->assertEquals(false, $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 0, 1426847190 - 1));	//Test discrepancy
+        $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847190));
+        $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 0, 1426847190 + 29));	//Test discrepancy
+        $this->assertFalse($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 0, 1426847190 + 30));	//Test discrepancy
+        $this->assertFalse($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 0, 1426847190 - 1));	//Test discrepancy
 
-        $this->assertEquals(true , $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 + 0));	//Test discrepancy
-        $this->assertEquals(true , $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 + 35));	//Test discrepancy
-        $this->assertEquals(true , $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 - 35));	//Test discrepancy
+        $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 + 0));	//Test discrepancy
+        $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 + 35));	//Test discrepancy
+        $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 - 35));	//Test discrepancy
 
-        $this->assertEquals(false, $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 + 65));	//Test discrepancy
-        $this->assertEquals(false, $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 - 65));	//Test discrepancy
+        $this->assertFalse($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 + 65));	//Test discrepancy
+        $this->assertFalse($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 - 65));	//Test discrepancy
 
-        $this->assertEquals(true , $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 2, 1426847205 + 65));	//Test discrepancy
-        $this->assertEquals(true , $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 2, 1426847205 - 65));	//Test discrepancy
+        $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 2, 1426847205 + 65));	//Test discrepancy
+        $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 2, 1426847205 - 65));	//Test discrepancy
     }
 
-    public function testVerifyCorrectTimeSliceIsReturned() {
+    /**
+     * @return void
+     */
+    public function testVerifyCorrectTimeSliceIsReturned()
+    {
         $tfa = new TwoFactorAuth('Test', 6, 30);
 
         // We test with discrepancy 3 (so total of 7 codes: c-3, c-2, c-1, c, c+1, c+2, c+3
         // Ensure each corresponding timeslice is returned correctly
-        $this->assertEquals(true, $tfa->verifyCode('VMR466AB62ZBOKHE', '534113', 3, 1426847190, $timeslice1));
+        $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '534113', 3, 1426847190, $timeslice1));
         $this->assertEquals(47561570, $timeslice1);
-        $this->assertEquals(true, $tfa->verifyCode('VMR466AB62ZBOKHE', '819652', 3, 1426847190, $timeslice2));
+        $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '819652', 3, 1426847190, $timeslice2));
         $this->assertEquals(47561571, $timeslice2);
-        $this->assertEquals(true, $tfa->verifyCode('VMR466AB62ZBOKHE', '915954', 3, 1426847190, $timeslice3));
+        $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '915954', 3, 1426847190, $timeslice3));
         $this->assertEquals(47561572, $timeslice3);
-        $this->assertEquals(true, $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 3, 1426847190, $timeslice4));
+        $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 3, 1426847190, $timeslice4));
         $this->assertEquals(47561573, $timeslice4);
-        $this->assertEquals(true, $tfa->verifyCode('VMR466AB62ZBOKHE', '348401', 3, 1426847190, $timeslice5));
+        $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '348401', 3, 1426847190, $timeslice5));
         $this->assertEquals(47561574, $timeslice5);
-        $this->assertEquals(true, $tfa->verifyCode('VMR466AB62ZBOKHE', '648525', 3, 1426847190, $timeslice6));
+        $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '648525', 3, 1426847190, $timeslice6));
         $this->assertEquals(47561575, $timeslice6);
-        $this->assertEquals(true, $tfa->verifyCode('VMR466AB62ZBOKHE', '170645', 3, 1426847190, $timeslice7));
+        $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '170645', 3, 1426847190, $timeslice7));
         $this->assertEquals(47561576, $timeslice7);
 
         // Incorrect code should return false and a 0 timeslice
-        $this->assertEquals(false, $tfa->verifyCode('VMR466AB62ZBOKHE', '111111', 3, 1426847190, $timeslice8));
+        $this->assertFalse($tfa->verifyCode('VMR466AB62ZBOKHE', '111111', 3, 1426847190, $timeslice8));
         $this->assertEquals(0, $timeslice8);
     }
 
-    public function testTotpUriIsCorrect() {
-        $qr = new TestQrProvider();
-
-        $tfa = new TwoFactorAuth('Test&Issuer', 6, 30, 'sha1', $qr);
-        $data = $this->DecodeDataUri($tfa->getQRCodeImageAsDataUri('Test&Label', 'VMR466AB62ZBOKHE'));
-        $this->assertEquals('test/test', $data['mimetype']);
-        $this->assertEquals('base64', $data['encoding']);
-        $this->assertEquals('otpauth://totp/Test%26Label?secret=VMR466AB62ZBOKHE&issuer=Test%26Issuer&period=30&algorithm=SHA1&digits=6@200', $data['data']);
-    }
-
     /**
-     * @expectedException \RobThree\Auth\TwoFactorAuthException
+     * @return void
      */
-    public function testGetQRCodeImageAsDataUriThrowsOnInvalidSize() {
-        $qr = new TestQrProvider();
-
-        $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', $qr);
-        $tfa->getQRCodeImageAsDataUri('Test', 'VMR466AB62ZBOKHE', 0);
-    }
-
-    /**
-     * @expectedException \RobThree\Auth\TwoFactorAuthException
-     */
-    public function testGetCodeThrowsOnInvalidBase32String1() {
+    public function testGetCodeThrowsOnInvalidBase32String1()
+    {
         $tfa = new TwoFactorAuth('Test');
+
+        $this->expectException(TwoFactorAuthException::class);
+
         $tfa->getCode('FOO1BAR8BAZ9');    //1, 8 & 9 are invalid chars
     }
 
     /**
-     * @expectedException \RobThree\Auth\TwoFactorAuthException
+     * @return void
      */
-    public function testGetCodeThrowsOnInvalidBase32String2() {
+    public function testGetCodeThrowsOnInvalidBase32String2()
+    {
         $tfa = new TwoFactorAuth('Test');
+
+        $this->expectException(TwoFactorAuthException::class);
+
         $tfa->getCode('mzxw6===');        //Lowercase
     }
 
-    public function testKnownBase32DecodeTestVectors() {
+    /**
+     * @return void
+     */
+    public function testKnownBase32DecodeTestVectors()
+    {
         // We usually don't test internals (e.g. privates) but since we rely heavily on base32 decoding and don't want
         // to expose this method nor do we want to give people the possibility of implementing / providing their own base32
         // decoding/decoder (as we do with Rng/QR providers for example) we simply test the private base32Decode() method
@@ -226,7 +159,7 @@
         //                                                           Dave Thomas and Andy Hunt -- "Pragmatic Unit Testing
         $tfa = new TwoFactorAuth('Test');
 
-        $method = new ReflectionMethod('RobThree\Auth\TwoFactorAuth', 'base32Decode');
+        $method = new \ReflectionMethod(TwoFactorAuth::class, 'base32Decode');
         $method->setAccessible(true);
 
         // Test vectors from: https://tools.ietf.org/html/rfc4648#page-12
@@ -239,14 +172,18 @@
         $this->assertEquals('foobar', $method->invoke($tfa, 'MZXW6YTBOI======'));
     }
 
-    public function testKnownBase32DecodeUnpaddedTestVectors() {
+    /**
+     * @return void
+     */
+    public function testKnownBase32DecodeUnpaddedTestVectors()
+    {
         // See testKnownBase32DecodeTestVectors() for the rationale behind testing the private base32Decode() method.
         // This test ensures that strings without the padding-char ('=') are also decoded correctly.
         // https://tools.ietf.org/html/rfc4648#page-4:
         //   "In some circumstances, the use of padding ("=") in base-encoded data is not required or used."
         $tfa = new TwoFactorAuth('Test');
 
-        $method = new ReflectionMethod('RobThree\Auth\TwoFactorAuth', 'base32Decode');
+        $method = new \ReflectionMethod(TwoFactorAuth::class, 'base32Decode');
         $method->setAccessible(true);
 
         // Test vectors from: https://tools.ietf.org/html/rfc4648#page-12
@@ -259,8 +196,11 @@
         $this->assertEquals('foobar', $method->invoke($tfa, 'MZXW6YTBOI'));
     }
 
-
-    public function testKnownTestVectors_sha1() {
+    /**
+     * @return void
+     */
+    public function testKnownTestVectors_sha1()
+    {
         //Known test vectors for SHA1: https://tools.ietf.org/html/rfc6238#page-15
         $secret = 'GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ';   //== base32encode('12345678901234567890')
         $tfa = new TwoFactorAuth('Test', 8, 30, 'sha1');
@@ -272,7 +212,11 @@
         $this->assertEquals('65353130', $tfa->getCode($secret, 20000000000));
     }
 
-    public function testKnownTestVectors_sha256() {
+    /**
+     * @return void
+     */
+    public function testKnownTestVectors_sha256()
+    {
         //Known test vectors for SHA256: https://tools.ietf.org/html/rfc6238#page-15
         $secret = 'GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZA';   //== base32encode('12345678901234567890123456789012')
         $tfa = new TwoFactorAuth('Test', 8, 30, 'sha256');
@@ -284,7 +228,11 @@
         $this->assertEquals('77737706', $tfa->getCode($secret, 20000000000));
     }
 
-    public function testKnownTestVectors_sha512() {
+    /**
+     * @return void
+     */
+    public function testKnownTestVectors_sha512()
+    {
         //Known test vectors for SHA512: https://tools.ietf.org/html/rfc6238#page-15
         $secret = 'GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZDGNA';   //== base32encode('1234567890123456789012345678901234567890123456789012345678901234')
         $tfa = new TwoFactorAuth('Test', 8, 30, 'sha512');
@@ -295,115 +243,4 @@
         $this->assertEquals('38618901', $tfa->getCode($secret, 2000000000));
         $this->assertEquals('47863826', $tfa->getCode($secret, 20000000000));
     }
-
-    /**
-     * @requires function random_bytes
-     */
-    public function testCSRNGProvidersReturnExpectedNumberOfBytes() {
-        $rng = new \RobThree\Auth\Providers\Rng\CSRNGProvider();
-        foreach ($this->getRngTestLengths() as $l)
-            $this->assertEquals($l, strlen($rng->getRandomBytes($l)));
-        $this->assertEquals(true, $rng->isCryptographicallySecure());
-    }
-
-    /**
-     * @requires function hash_algos
-     * @requires function hash
-     */
-    public function testHashRNGProvidersReturnExpectedNumberOfBytes() {
-        $rng = new \RobThree\Auth\Providers\Rng\HashRNGProvider();
-        foreach ($this->getRngTestLengths() as $l)
-            $this->assertEquals($l, strlen($rng->getRandomBytes($l)));
-        $this->assertEquals(false, $rng->isCryptographicallySecure());
-    }
-
-    /**
-     * @requires function mcrypt_create_iv
-     */
-    public function testMCryptRNGProvidersReturnExpectedNumberOfBytes() {
-        if (function_exists('mcrypt_create_iv')) {
-            $rng = new \RobThree\Auth\Providers\Rng\MCryptRNGProvider();
-            foreach ($this->getRngTestLengths() as $l)
-                $this->assertEquals($l, strlen($rng->getRandomBytes($l)));
-            $this->assertEquals(true, $rng->isCryptographicallySecure());
-        }
-    }
-
-    /**
-     * @requires function openssl_random_pseudo_bytes
-     */
-    public function testStrongOpenSSLRNGProvidersReturnExpectedNumberOfBytes() {
-        $rng = new \RobThree\Auth\Providers\Rng\OpenSSLRNGProvider(true);
-        foreach ($this->getRngTestLengths() as $l)
-            $this->assertEquals($l, strlen($rng->getRandomBytes($l)));
-        $this->assertEquals(true, $rng->isCryptographicallySecure());
-    }
-
-    /**
-     * @requires function openssl_random_pseudo_bytes
-     */
-    public function testNonStrongOpenSSLRNGProvidersReturnExpectedNumberOfBytes() {
-        $rng = new \RobThree\Auth\Providers\Rng\OpenSSLRNGProvider(false);
-        foreach ($this->getRngTestLengths() as $l)
-            $this->assertEquals($l, strlen($rng->getRandomBytes($l)));
-        $this->assertEquals(false, $rng->isCryptographicallySecure());
-    }
-
-
-    private function getRngTestLengths() {
-        return array(1, 16, 32, 256);
-    }
-
-    private function DecodeDataUri($datauri) {
-        if (preg_match('/data:(?P<mimetype>[\w\.\-\/]+);(?P<encoding>\w+),(?P<data>.*)/', $datauri, $m) === 1) {
-            return array(
-                'mimetype' => $m['mimetype'],
-                'encoding' => $m['encoding'],
-                'data' => base64_decode($m['data'])
-            );
-        }
-        return null;
-    }
 }
-
-class TestRNGProvider implements IRNGProvider {
-    private $isSecure;
-
-    function __construct($isSecure = false) {
-        $this->isSecure = $isSecure;
-    }
-
-    public function getRandomBytes($bytecount) {
-        $result = '';
-        for ($i=0; $i<$bytecount; $i++)
-            $result.=chr($i);
-        return $result;
-
-    }
-
-    public function isCryptographicallySecure() {
-        return $this->isSecure;
-    }
-}
-
-class TestQrProvider implements IQRCodeProvider {
-    public function getQRCodeImage($qrtext, $size) {
-        return $qrtext . '@' . $size;
-    }
-
-    public function getMimeType() {
-        return 'test/test';
-    }
-}
-
-class TestTimeProvider implements ITimeProvider {
-    private $time;
-
-    function __construct($time) {
-        $this->time = $time;
-    }
-
-    public function getTime() {
-        return $this->time;
-    }
-}
\ No newline at end of file