From fb98db7da7c30890ea0298ded185829bb543d86c Mon Sep 17 00:00:00 2001 From: Christoph Wurst Date: Fri, 31 Aug 2018 11:46:00 +0200 Subject: [PATCH] Fix handlng of concurrent inserts of the 2FA provider registry DAO Signed-off-by: Christoph Wurst --- .../Db/ProviderUserAssignmentDao.php | 29 ++++++------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/lib/private/Authentication/TwoFactorAuth/Db/ProviderUserAssignmentDao.php b/lib/private/Authentication/TwoFactorAuth/Db/ProviderUserAssignmentDao.php index e04512b8575eb..ce03eb096612f 100644 --- a/lib/private/Authentication/TwoFactorAuth/Db/ProviderUserAssignmentDao.php +++ b/lib/private/Authentication/TwoFactorAuth/Db/ProviderUserAssignmentDao.php @@ -26,6 +26,7 @@ namespace OC\Authentication\TwoFactorAuth\Db; +use Doctrine\DBAL\Exception\UniqueConstraintViolationException; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\IDBConnection; @@ -72,25 +73,7 @@ public function getState(string $uid): array { public function persist(string $providerId, string $uid, int $enabled) { $qb = $this->conn->getQueryBuilder(); - $this->conn->beginTransaction(); - // To prevent duplicate primary key, we have to first check if an INSERT - // or UPDATE is required - $query = $qb->select('*') - ->from(self::TABLE_NAME) - ->where($qb->expr()->eq('provider_id', $qb->createNamedParameter($providerId))) - ->andWhere($qb->expr()->eq('uid', $qb->createNamedParameter($uid))); - $result = $query->execute(); - $rowCount = count($result->fetchAll()); - $result->closeCursor(); - - if ($rowCount > 0) { - // There is an entry -> update it - $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->execute(); - } else { + try { // Insert a new entry $insertQuery = $qb->insert(self::TABLE_NAME)->values([ 'provider_id' => $qb->createNamedParameter($providerId), @@ -99,8 +82,14 @@ public function persist(string $providerId, string $uid, int $enabled) { ]); $insertQuery->execute(); + } catch (UniqueConstraintViolationException $ex) { + // There is already an entry -> update it + $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->execute(); } - $this->conn->commit(); }