Skip to content

Commit 94d1154

Browse files
committed
Filter document security cache hits
1 parent b9c2e46 commit 94d1154

2 files changed

Lines changed: 57 additions & 0 deletions

File tree

src/Database/Database.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8659,6 +8659,17 @@ public function withCache(
86598659
break;
86608660
}
86618661

8662+
if (!$skipAuth && $documentSecurity && $collection->getId() !== self::METADATA) {
8663+
if (!$this->authorization->isValid(new Input(self::PERMISSION_READ, $document->getRead()))) {
8664+
if (($cached['type'] ?? null) === 'document') {
8665+
$decoded = false;
8666+
break;
8667+
}
8668+
8669+
continue;
8670+
}
8671+
}
8672+
86628673
$documents[] = $document;
86638674
}
86648675

tests/unit/QueryCacheTest.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,52 @@ public function testQueryCacheReliesOnPurgeForDocumentSecurityCollections(): voi
665665
$this->assertSame([], $fresh);
666666
}
667667

668+
public function testQueryCacheFiltersDocumentSecurityPayloadsOnHit(): void
669+
{
670+
$cache = new HashMemoryCache();
671+
$database = $this->createDatabase($cache);
672+
$database->getAuthorization()->skip(function () use ($database): void {
673+
$database->createCollection('secureRules', permissions: [
674+
Permission::create(Role::any()),
675+
], documentSecurity: true);
676+
});
677+
678+
$database->getAuthorization()->addRole(Role::user('user-1')->toString());
679+
680+
$collection = $database->getCollection('secureRules');
681+
$key = $database->getQueryCacheKey($collection->getId(), '_39');
682+
$hash = $database->getQueryCacheField($collection);
683+
$database->getCache()->save($key, [
684+
'collection' => $collection->getId(),
685+
'type' => 'documents',
686+
'value' => [
687+
[
688+
'$id' => 'rule-a',
689+
'$permissions' => [
690+
Permission::read(Role::user('user-2')),
691+
],
692+
],
693+
],
694+
], $hash);
695+
696+
$callbackCalls = 0;
697+
$documents = $database->withCache(
698+
key: $key,
699+
callback: function () use (&$callbackCalls): array {
700+
$callbackCalls++;
701+
return [
702+
new Document([
703+
'$id' => 'fresh',
704+
]),
705+
];
706+
},
707+
hash: $hash,
708+
);
709+
710+
$this->assertSame([], $documents);
711+
$this->assertSame(0, $callbackCalls);
712+
}
713+
668714
public function testQueryCacheRehydratesNestedDocumentPayloads(): void
669715
{
670716
$cache = new HashMemoryCache();

0 commit comments

Comments
 (0)