summaryrefslogtreecommitdiffstats
path: root/apps/twofactor_backupcodes/lib/Service/BackupCodeStorage.php
diff options
context:
space:
mode:
authorMarius Blüm <marius@lineone.io>2016-09-05 12:17:29 +0200
committerGitHub <noreply@github.com>2016-09-05 12:17:29 +0200
commitf8eb7be7b1b0e1052e56b35e7bb450ad5ac68547 (patch)
tree612fe8a3b1ee8a40dbd58a4ecc4c7af633321b5d /apps/twofactor_backupcodes/lib/Service/BackupCodeStorage.php
parente3a5767a29e75ea360dcadba6bc342720ed44133 (diff)
parent581a83c2a18a50eb93216813f3591fc940ad914c (diff)
downloadnextcloud-server-f8eb7be7b1b0e1052e56b35e7bb450ad5ac68547.tar.gz
nextcloud-server-f8eb7be7b1b0e1052e56b35e7bb450ad5ac68547.zip
Merge pull request #1171 from nextcloud/2fa-backup-codes
add 2fa backup codes app
Diffstat (limited to 'apps/twofactor_backupcodes/lib/Service/BackupCodeStorage.php')
-rw-r--r--apps/twofactor_backupcodes/lib/Service/BackupCodeStorage.php121
1 files changed, 121 insertions, 0 deletions
diff --git a/apps/twofactor_backupcodes/lib/Service/BackupCodeStorage.php b/apps/twofactor_backupcodes/lib/Service/BackupCodeStorage.php
new file mode 100644
index 00000000000..9c78581255f
--- /dev/null
+++ b/apps/twofactor_backupcodes/lib/Service/BackupCodeStorage.php
@@ -0,0 +1,121 @@
+<?php
+
+/**
+ * @author Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\TwoFactor_BackupCodes\Service;
+
+use OCA\TwoFactor_BackupCodes\Db\BackupCode;
+use OCA\TwoFactor_BackupCodes\Db\BackupCodeMapper;
+use OCP\IUser;
+use OCP\Security\IHasher;
+use OCP\Security\ISecureRandom;
+
+class BackupCodeStorage {
+
+ /** @var BackupCodeMapper */
+ private $mapper;
+
+ /** @var IHasher */
+ private $hasher;
+
+ /** @var ISecureRandom */
+ private $random;
+
+ public function __construct(BackupCodeMapper $mapper, ISecureRandom $random, IHasher $hasher) {
+ $this->mapper = $mapper;
+ $this->hasher = $hasher;
+ $this->random = $random;
+ }
+
+ /**
+ * @param IUser $user
+ * @return string[]
+ */
+ public function createCodes(IUser $user, $number = 10) {
+ $result = [];
+
+ // Delete existing ones
+ $this->mapper->deleteCodes($user);
+
+ $uid = $user->getUID();
+ foreach (range(1, min([$number, 20])) as $i) {
+ $code = $this->random->generate(10, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789');
+
+ $dbCode = new BackupCode();
+ $dbCode->setUserId($uid);
+ $dbCode->setCode($this->hasher->hash($code));
+ $dbCode->setUsed(0);
+ $this->mapper->insert($dbCode);
+
+ array_push($result, $code);
+ }
+
+ return $result;
+ }
+
+ /**
+ * @param IUser $user
+ * @return bool
+ */
+ public function hasBackupCodes(IUser $user) {
+ $codes = $this->mapper->getBackupCodes($user);
+ return count($codes) > 0;
+ }
+
+ /**
+ * @param IUser $user
+ * @return array
+ */
+ public function getBackupCodesState(IUser $user) {
+ $codes = $this->mapper->getBackupCodes($user);
+ $total = count($codes);
+ $used = 0;
+ array_walk($codes, function (BackupCode $code) use (&$used) {
+ if (1 === (int) $code->getUsed()) {
+ $used++;
+ }
+ });
+ return [
+ 'enabled' => $total > 0,
+ 'total' => $total,
+ 'used' => $used,
+ ];
+ }
+
+ /**
+ * @param IUser $user
+ * @param string $code
+ * @return bool
+ */
+ public function validateCode(IUser $user, $code) {
+ $dbCodes = $this->mapper->getBackupCodes($user);
+
+ foreach ($dbCodes as $dbCode) {
+ if (0 === (int) $dbCode->getUsed() && $this->hasher->verify($code, $dbCode->getCode())) {
+ $dbCode->setUsed(1);
+ $this->mapper->update($dbCode);
+ return true;
+ }
+ }
+ return false;
+ }
+
+}