diff options
author | Thomas Citharel <tcit@tcit.fr> | 2022-12-02 17:46:37 +0100 |
---|---|---|
committer | Julius Härtl (Rebase PR Action) <github@juliushaertl.de> | 2023-03-15 11:07:07 +0000 |
commit | f7e65b17513303bd16308107d252682ac3c56359 (patch) | |
tree | 5971ea0bfdd8a2c4364d5d70f16dc7aa85e8bf5c | |
parent | 8568c11d24736d4df1b9781c4121cf7165f40f65 (diff) | |
download | nextcloud-server-f7e65b17513303bd16308107d252682ac3c56359.tar.gz nextcloud-server-f7e65b17513303bd16308107d252682ac3c56359.zip |
Create the database user in a transaction
In OC\User\Manager::createUserFromBackend the newly created user is read
using getUserObject($uid, $backend) but that can cause causal read
issues (wrote in DB primary, not yet in secondary).
In OC\User\Database user backend the user cache is unset after the
insert, so it can't be used by getRealUID() (which is called by
getUserObject()).
To avoid that we make sure the user cache is repopulated in a
transaction.
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
-rw-r--r-- | lib/private/User/Database.php | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/lib/private/User/Database.php b/lib/private/User/Database.php index 8bbbccd4540..944202f244e 100644 --- a/lib/private/User/Database.php +++ b/lib/private/User/Database.php @@ -45,6 +45,7 @@ declare(strict_types=1); */ namespace OC\User; +use OCP\AppFramework\Db\TTransactional; use OCP\Cache\CappedMemoryCache; use OCP\EventDispatcher\IEventDispatcher; use OCP\IDBConnection; @@ -85,6 +86,8 @@ class Database extends ABackend implements /** @var string */ private $table; + use TTransactional; + /** * \OC\User\Database constructor. * @@ -122,20 +125,24 @@ class Database extends ABackend implements if (!$this->userExists($uid)) { $this->eventDispatcher->dispatchTyped(new ValidatePasswordPolicyEvent($password)); - $qb = $this->dbConn->getQueryBuilder(); - $qb->insert($this->table) - ->values([ - 'uid' => $qb->createNamedParameter($uid), - 'password' => $qb->createNamedParameter(\OC::$server->getHasher()->hash($password)), - 'uid_lower' => $qb->createNamedParameter(mb_strtolower($uid)), - ]); + return $this->atomic(function () use ($uid, $password) { + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert($this->table) + ->values([ + 'uid' => $qb->createNamedParameter($uid), + 'password' => $qb->createNamedParameter(\OC::$server->getHasher()->hash($password)), + 'uid_lower' => $qb->createNamedParameter(mb_strtolower($uid)), + ]); - $result = $qb->execute(); + $result = $qb->executeStatement(); - // Clear cache - unset($this->cache[$uid]); + // Clear cache + unset($this->cache[$uid]); + // Repopulate the cache + $this->loadUser($uid); - return $result ? true : false; + return (bool) $result; + }, $this->dbConn); } return false; |