Skip to content

Commit 0ba3e5c

Browse files
tcitworldjuliusknorr
authored andcommitted
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>
1 parent 19e521e commit 0ba3e5c

File tree

1 file changed

+18
-11
lines changed

1 file changed

+18
-11
lines changed

lib/private/User/Database.php

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
*/
4646
namespace OC\User;
4747

48+
use OCP\AppFramework\Db\TTransactional;
4849
use OCP\Cache\CappedMemoryCache;
4950
use OCP\EventDispatcher\IEventDispatcher;
5051
use OCP\IDBConnection;
@@ -85,6 +86,8 @@ class Database extends ABackend implements
8586
/** @var string */
8687
private $table;
8788

89+
use TTransactional;
90+
8891
/**
8992
* \OC\User\Database constructor.
9093
*
@@ -122,20 +125,24 @@ public function createUser(string $uid, string $password): bool {
122125
if (!$this->userExists($uid)) {
123126
$this->eventDispatcher->dispatchTyped(new ValidatePasswordPolicyEvent($password));
124127

125-
$qb = $this->dbConn->getQueryBuilder();
126-
$qb->insert($this->table)
127-
->values([
128-
'uid' => $qb->createNamedParameter($uid),
129-
'password' => $qb->createNamedParameter(\OC::$server->getHasher()->hash($password)),
130-
'uid_lower' => $qb->createNamedParameter(mb_strtolower($uid)),
131-
]);
128+
return $this->atomic(function () use ($uid, $password) {
129+
$qb = $this->dbConn->getQueryBuilder();
130+
$qb->insert($this->table)
131+
->values([
132+
'uid' => $qb->createNamedParameter($uid),
133+
'password' => $qb->createNamedParameter(\OC::$server->getHasher()->hash($password)),
134+
'uid_lower' => $qb->createNamedParameter(mb_strtolower($uid)),
135+
]);
132136

133-
$result = $qb->execute();
137+
$result = $qb->execute();
134138

135-
// Clear cache
136-
unset($this->cache[$uid]);
139+
// Clear cache
140+
unset($this->cache[$uid]);
141+
// Repopulate the cache
142+
$this->loadUser($uid);
137143

138-
return $result ? true : false;
144+
return (bool) $result;
145+
}, $this->dbConn);
139146
}
140147

141148
return false;

0 commit comments

Comments
 (0)