mirror of
https://github.com/RobThree/TwoFactorAuth.git
synced 2026-10-09 05:15:41 +00:00
* Implemented ITimeProviders
This commit is contained in:
+48
-2
@@ -3,6 +3,7 @@ namespace RobThree\Auth;
|
||||
|
||||
use RobThree\Auth\Providers\Qr\IQRCodeProvider;
|
||||
use RobThree\Auth\Providers\Rng\IRNGProvider;
|
||||
use RobThree\Auth\Providers\Time\ITimeProvider;
|
||||
|
||||
// Based on / inspired by: https://github.com/PHPGangsta/GoogleAuthenticator
|
||||
// Algorithms, digits, period etc. explained: https://github.com/google/google-authenticator/wiki/Key-Uri-Format
|
||||
@@ -14,12 +15,13 @@ class TwoFactorAuth
|
||||
private $issuer;
|
||||
private $qrcodeprovider = null;
|
||||
private $rngprovider = null;
|
||||
private $timeprovider = null;
|
||||
private static $_base32dict = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=';
|
||||
private static $_base32;
|
||||
private static $_base32lookup = array();
|
||||
private static $_supportedalgos = array('sha1', 'sha256', 'sha512', 'md5');
|
||||
|
||||
function __construct($issuer = null, $digits = 6, $period = 30, $algorithm = 'sha1', IQRCodeProvider $qrcodeprovider = null, IRNGProvider $rngprovider = null)
|
||||
function __construct($issuer = null, $digits = 6, $period = 30, $algorithm = 'sha1', IQRCodeProvider $qrcodeprovider = null, IRNGProvider $rngprovider = null, ITimeProvider $timeprovider = null)
|
||||
{
|
||||
$this->issuer = $issuer;
|
||||
if (!is_int($digits) || $digits <= 0)
|
||||
@@ -36,6 +38,7 @@ class TwoFactorAuth
|
||||
$this->algorithm = $algorithm;
|
||||
$this->qrcodeprovider = $qrcodeprovider;
|
||||
$this->rngprovider = $rngprovider;
|
||||
$this->timeprovider = $timeprovider;
|
||||
|
||||
self::$_base32 = str_split(self::$_base32dict);
|
||||
self::$_base32lookup = array_flip(self::$_base32);
|
||||
@@ -121,9 +124,37 @@ class TwoFactorAuth
|
||||
. base64_encode($qrcodeprovider->getQRCodeImage($this->getQRText($label, $secret), $size));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare default timeprovider with specified timeproviders and ensure the time is within the specified number of seconds (leniency)
|
||||
*/
|
||||
public function ensureCorrectTime(array $timeproviders = null, $leniency = 5)
|
||||
{
|
||||
if ($timeproviders != null && !is_array($timeproviders))
|
||||
throw new TwoFactorAuthException('No timeproviders specified');
|
||||
|
||||
if ($timeproviders == null)
|
||||
$timeproviders = array(
|
||||
new Providers\Time\ConvertUnixTimeDotComTimeProvider(),
|
||||
new Providers\Time\HttpTimeProvider()
|
||||
);
|
||||
|
||||
// Get default time provider
|
||||
$timeprovider = $this->getTimeProvider();
|
||||
|
||||
// Iterate specified time providers
|
||||
foreach ($timeproviders as $t) {
|
||||
if (!($t instanceof ITimeProvider))
|
||||
throw new TwoFactorAuthException('Object does not implement ITimeProvider');
|
||||
|
||||
// Get time from default time provider and compare to specific time provider and throw if time difference is more than specified number of seconds leniency
|
||||
if (abs($timeprovider->getTime() - $t->getTime()) > $leniency)
|
||||
throw new TwoFactorAuthException(sprintf('Time for timeprovider is off by more than %d seconds when compared to %s', $leniency, get_class($t)));
|
||||
}
|
||||
}
|
||||
|
||||
private function getTime($time)
|
||||
{
|
||||
return ($time === null) ? time() : $time;
|
||||
return ($time === null) ? $this->timeprovider->getTime() : $time;
|
||||
}
|
||||
|
||||
private function getTimeSlice($time = null, $offset = 0)
|
||||
@@ -165,6 +196,7 @@ class TwoFactorAuth
|
||||
$output .= chr(bindec(str_pad($block, 8, 0, STR_PAD_RIGHT)));
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return IQRCodeProvider
|
||||
* @throws TwoFactorAuthException
|
||||
@@ -177,6 +209,7 @@ class TwoFactorAuth
|
||||
}
|
||||
return $this->qrcodeprovider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return IRNGProvider
|
||||
* @throws TwoFactorAuthException
|
||||
@@ -200,4 +233,17 @@ class TwoFactorAuth
|
||||
}
|
||||
throw new TwoFactorAuthException('Unable to find a suited RNGProvider');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ITimeProvider
|
||||
* @throws TwoFactorAuthException
|
||||
*/
|
||||
public function getTimeProvider()
|
||||
{
|
||||
// Set default time provider if none was specified
|
||||
if (null === $this->timeprovider) {
|
||||
return $this->timeprovider = new Providers\Time\LocalMachineTimeProvider();
|
||||
}
|
||||
return $this->timeprovider;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user