* * @author Christoph Wurst * * @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 . * */ namespace OC\Authentication\TwoFactorAuth\Db; use OCP\IDBConnection; use function array_map; /** * Data access object to query and assign (provider_id, uid, enabled) tuples of * 2FA providers */ class ProviderUserAssignmentDao { public const TABLE_NAME = 'twofactor_providers'; /** @var IDBConnection */ private $conn; public function __construct(IDBConnection $dbConn) { $this->conn = $dbConn; } /** * Get all assigned provider IDs for the given user ID * * @return array where the array key is the provider ID (string) and the * value is the enabled state (bool) */ public function getState(string $uid): array { $qb = $this->conn->getQueryBuilder(); $query = $qb->select('provider_id', 'enabled') ->from(self::TABLE_NAME) ->where($qb->expr()->eq('uid', $qb->createNamedParameter($uid))); $result = $query->execute(); $providers = []; foreach ($result->fetchAll() as $row) { $providers[(string)$row['provider_id']] = (int)$row['enabled'] === 1; } $result->closeCursor(); return $providers; } /** * Persist a new/updated (provider_id, uid, enabled) tuple */ public function persist(string $providerId, string $uid, int $enabled): void { $conn = $this->conn; // Insert a new entry if ($conn->insertIgnoreConflict(self::TABLE_NAME, [ 'provider_id' => $providerId, 'uid' => $uid, 'enabled' => $enabled, ])) { return; } // There is already an entry -> update it $qb = $conn->getQueryBuilder(); $updateQuery = $qb->update(self::TABLE_NAME) ->set('enabled', $qb->createNamedParameter($enabled)) ->where($qb->expr()->eq('provider_id', $qb->createNamedParameter($providerId))) ->andWhere($qb->expr()->eq('uid', $qb->createNamedParameter($uid))); $updateQuery->executeStatement(); } /** * Delete all provider states of a user and return the provider IDs * * @param string $uid * * @return list */ public function deleteByUser(string $uid): array { $qb1 = $this->conn->getQueryBuilder(); $selectQuery = $qb1->select('*') ->from(self::TABLE_NAME) ->where($qb1->expr()->eq('uid', $qb1->createNamedParameter($uid))); $selectResult = $selectQuery->execute(); $rows = $selectResult->fetchAll(); $selectResult->closeCursor(); $qb2 = $this->conn->getQueryBuilder(); $deleteQuery = $qb2 ->delete(self::TABLE_NAME) ->where($qb2->expr()->eq('uid', $qb2->createNamedParameter($uid))); $deleteQuery->execute(); return array_map(function (array $row) { return [ 'provider_id' => (string) $row['provider_id'], 'uid' => (string) $row['uid'], 'enabled' => (int) $row['enabled'] === 1, ]; }, $rows); } public function deleteAll(string $providerId): void { $qb = $this->conn->getQueryBuilder(); $deleteQuery = $qb->delete(self::TABLE_NAME) ->where($qb->expr()->eq('provider_id', $qb->createNamedParameter($providerId))); $deleteQuery->execute(); } }