aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoas Schilling <213943+nickvergessen@users.noreply.github.com>2024-09-16 09:11:59 +0200
committerGitHub <noreply@github.com>2024-09-16 09:11:59 +0200
commit1e87c3f17de14ee9a53d0db5212ebc9442d39b6c (patch)
treee8072ac822fdffcabbd80f086abdb1b146fcbf36
parent3abf9581dddae1de097080de9a5fa856e5cd1e5b (diff)
parent25d70bf77fd98a1f1c55ca7e55872d2ca73617f6 (diff)
downloadnextcloud-server-1e87c3f17de14ee9a53d0db5212ebc9442d39b6c.tar.gz
nextcloud-server-1e87c3f17de14ee9a53d0db5212ebc9442d39b6c.zip
Merge pull request #47942 from nextcloud/backport/47933/stable28
[stable28] fix(config): Throw PreconditionException always when it didn't match
-rw-r--r--lib/private/AllConfig.php6
-rw-r--r--tests/lib/AllConfigTest.php36
2 files changed, 39 insertions, 3 deletions
diff --git a/lib/private/AllConfig.php b/lib/private/AllConfig.php
index 7a54de2b7bb..558b181050d 100644
--- a/lib/private/AllConfig.php
+++ b/lib/private/AllConfig.php
@@ -264,10 +264,10 @@ class AllConfig implements IConfig {
$prevValue = $this->getUserValue($userId, $appName, $key, null);
if ($prevValue !== null) {
- if ($prevValue === (string)$value) {
- return;
- } elseif ($preCondition !== null && $prevValue !== (string)$preCondition) {
+ if ($preCondition !== null && $prevValue !== (string)$preCondition) {
throw new PreConditionNotMetException();
+ } elseif ($prevValue === (string)$value) {
+ return;
} else {
$qb = $this->connection->getQueryBuilder();
$qb->update('preferences')
diff --git a/tests/lib/AllConfigTest.php b/tests/lib/AllConfigTest.php
index 540eff42e51..79599866fe2 100644
--- a/tests/lib/AllConfigTest.php
+++ b/tests/lib/AllConfigTest.php
@@ -183,6 +183,42 @@ class AllConfigTest extends \Test\TestCase {
$config->deleteUserValue('userPreCond1', 'appPreCond', 'keyPreCond');
}
+ public function testSetUserValueWithPreConditionFailureWhenResultStillMatches(): void {
+ $this->expectException(\OCP\PreConditionNotMetException::class);
+
+ $config = $this->getConfig();
+
+ $selectAllSQL = 'SELECT `userid`, `appid`, `configkey`, `configvalue` FROM `*PREFIX*preferences` WHERE `userid` = ?';
+
+ $config->setUserValue('userPreCond1', 'appPreCond', 'keyPreCond', 'valuePreCond');
+
+ $result = $this->connection->executeQuery($selectAllSQL, ['userPreCond1'])->fetchAll();
+
+ $this->assertCount(1, $result);
+ $this->assertEquals([
+ 'userid' => 'userPreCond1',
+ 'appid' => 'appPreCond',
+ 'configkey' => 'keyPreCond',
+ 'configvalue' => 'valuePreCond'
+ ], $result[0]);
+
+ // test if the method throws with invalid precondition when the value is the same
+ $config->setUserValue('userPreCond1', 'appPreCond', 'keyPreCond', 'valuePreCond', 'valuePreCond3');
+
+ $result = $this->connection->executeQuery($selectAllSQL, ['userPreCond1'])->fetchAll();
+
+ $this->assertCount(1, $result);
+ $this->assertEquals([
+ 'userid' => 'userPreCond1',
+ 'appid' => 'appPreCond',
+ 'configkey' => 'keyPreCond',
+ 'configvalue' => 'valuePreCond'
+ ], $result[0]);
+
+ // cleanup
+ $config->deleteUserValue('userPreCond1', 'appPreCond', 'keyPreCond');
+ }
+
public function testSetUserValueUnchanged() {
// TODO - FIXME until the dependency injection is handled properly (in AllConfig)
$this->markTestSkipped('Skipped because this is just testable if database connection can be injected');