summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Citharel <tcit@tcit.fr>2022-12-02 17:46:37 +0100
committerJulius Härtl (Rebase PR Action) <github@juliushaertl.de>2023-03-15 11:07:07 +0000
commitf7e65b17513303bd16308107d252682ac3c56359 (patch)
tree5971ea0bfdd8a2c4364d5d70f16dc7aa85e8bf5c
parent8568c11d24736d4df1b9781c4121cf7165f40f65 (diff)
downloadnextcloud-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.php29
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;