diff options
author | Roeland Jago Douma <roeland@famdouma.nl> | 2019-03-05 00:31:02 +0300 |
---|---|---|
committer | Roeland Jago Douma <roeland@famdouma.nl> | 2019-03-11 12:14:55 +0300 |
commit | a657501d5264541c0a78623263f3973d75165fac (patch) | |
tree | 931beffbc2a4e55eecb2173f382fc0052cf99cc0 /lib | |
parent | 0704478af5cafdfad7257f54bb96f61f2c97f5e5 (diff) |
Move to rullzer/easytotp
Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Db/TotpSecret.php | 12 | ||||
-rw-r--r-- | lib/Db/TotpSecretMapper.php | 2 | ||||
-rw-r--r-- | lib/Migration/Version030000Date20190305114917.php | 32 | ||||
-rw-r--r-- | lib/Service/Totp.php | 22 |
4 files changed, 64 insertions, 4 deletions
diff --git a/lib/Db/TotpSecret.php b/lib/Db/TotpSecret.php index 9425d67..9a4c9c9 100644 --- a/lib/Db/TotpSecret.php +++ b/lib/Db/TotpSecret.php @@ -32,6 +32,8 @@ use OCP\AppFramework\Db\Entity; * @method void setSecret(string $secret) * @method int getState() * @method void setState(int $state) + * @method int getLastCounter(); + * @method void setLastCounter(int $counter) */ class TotpSecret extends Entity { @@ -44,4 +46,14 @@ class TotpSecret extends Entity { /** @var int */ protected $state; + /** @var int */ + protected $lastCounter; + + public function __construct() { + $this->addType('userId', 'string'); + $this->addType('secret', 'string'); + $this->addType('state', 'int'); + $this->addType('lastCounter', 'int'); + } + } diff --git a/lib/Db/TotpSecretMapper.php b/lib/Db/TotpSecretMapper.php index 6878a66..567d61d 100644 --- a/lib/Db/TotpSecretMapper.php +++ b/lib/Db/TotpSecretMapper.php @@ -44,7 +44,7 @@ class TotpSecretMapper extends QBMapper { /* @var $qb IQueryBuilder */ $qb = $this->db->getQueryBuilder(); - $qb->select('id', 'user_id', 'secret', 'state') + $qb->select('id', 'user_id', 'secret', 'state', 'last_counter') ->from($this->getTableName()) ->from('twofactor_totp_secrets') ->where($qb->expr()->eq('user_id', $qb->createNamedParameter($user->getUID()))); diff --git a/lib/Migration/Version030000Date20190305114917.php b/lib/Migration/Version030000Date20190305114917.php new file mode 100644 index 0000000..3f71e6e --- /dev/null +++ b/lib/Migration/Version030000Date20190305114917.php @@ -0,0 +1,32 @@ +<?php +declare(strict_types=1); + +namespace OCA\TwoFactorTOTP\Migration; + +use Closure; +use Doctrine\DBAL\Types\Type; +use OCP\DB\ISchemaWrapper; +use OCP\Migration\SimpleMigrationStep; +use OCP\Migration\IOutput; + +class Version030000Date20190305114917 extends SimpleMigrationStep { + + /** + * @param IOutput $output + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + * @return null|ISchemaWrapper + */ + public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) { + /** @var ISchemaWrapper $schema */ + $schema = $schemaClosure(); + + $table = $schema->getTable('twofactor_totp_secrets'); + $table->addColumn('last_counter', Type::BIGINT, [ + 'notnull' => true, + 'default' => -1, + ]); + + return $schema; + } +} diff --git a/lib/Service/Totp.php b/lib/Service/Totp.php index 678797b..2a69057 100644 --- a/lib/Service/Totp.php +++ b/lib/Service/Totp.php @@ -25,6 +25,9 @@ declare(strict_types=1); namespace OCA\TwoFactorTOTP\Service; use Base32\Base32; +use EasyTOTP\Factory; +use EasyTOTP\TOTPInvalidResultInterface; +use EasyTOTP\TOTPValidResultInterface; use OCA\TwoFactorTOTP\Db\TotpSecret; use OCA\TwoFactorTOTP\Db\TotpSecretMapper; use OCA\TwoFactorTOTP\Event\DisabledByAdmin; @@ -34,7 +37,6 @@ use OCP\AppFramework\Db\DoesNotExistException; use OCP\IUser; use OCP\Security\ICrypto; use Otp\GoogleAuthenticator; -use Otp\Otp; use Symfony\Component\EventDispatcher\EventDispatcherInterface; class Totp implements ITotp { @@ -126,9 +128,23 @@ class Totp implements ITotp { } $secret = $this->crypto->decrypt($dbSecret->getSecret()); + $otp = Factory::getTOTP(Base32::decode($secret), 30, 6); - $otp = new Otp(); - return $otp->checkTotp(Base32::decode($secret), $key, 3); + $counter = null; + $lastCounter = $dbSecret->getLastCounter(); + if ($lastCounter !== -1) { + $counter = $lastCounter; + } + + $result = $otp->verify($key, 3, $counter); + if ($result instanceof TOTPValidResultInterface) { + $dbSecret->setLastCounter($result->getCounter()); + $this->secretMapper->update($dbSecret); + + return true; + } + + return false; } } |