Skip to content

Commit f0ac90c

Browse files
committed
joinsCollectionsIds
1 parent 63487e3 commit f0ac90c

3 files changed

Lines changed: 57 additions & 12 deletions

File tree

src/Database/Database.php

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,11 @@ class Database
442442
*/
443443
protected array $documentTypes = [];
444444

445+
/**
446+
* List of collections allowed to join
447+
* @var array<string>
448+
*/
449+
protected array $joinsCollectionsIds = [];
445450

446451
/**
447452
* @var Authorization
@@ -5794,7 +5799,7 @@ public function updateDocuments(
57945799
minAllowedDate: $this->adapter->getMinDateTime(),
57955800
maxAllowedDate: $this->adapter->getMaxDateTime(),
57965801
supportForAttributes: $this->adapter->getSupportForAttributes(),
5797-
maxUIDLength: $this->adapter->getMaxUIDLength()
5802+
maxUIDLength: $this->adapter->getMaxUIDLength(),
57985803
);
57995804

58005805
if (!$validator->isValid($queries)) {
@@ -7513,7 +7518,7 @@ public function deleteDocuments(
75137518
minAllowedDate: $this->adapter->getMinDateTime(),
75147519
maxAllowedDate: $this->adapter->getMaxDateTime(),
75157520
supportForAttributes: $this->adapter->getSupportForAttributes(),
7516-
maxUIDLength: $this->adapter->getMaxUIDLength()
7521+
maxUIDLength: $this->adapter->getMaxUIDLength(),
75177522
);
75187523

75197524
if (!$validator->isValid($queries)) {
@@ -7763,7 +7768,8 @@ public function find(string $collection, array $queries = [], string $forPermiss
77637768
minAllowedDate: $this->adapter->getMinDateTime(),
77647769
maxAllowedDate: $this->adapter->getMaxDateTime(),
77657770
supportForAttributes: $this->adapter->getSupportForAttributes(),
7766-
maxUIDLength: $this->adapter->getMaxUIDLength()
7771+
maxUIDLength: $this->adapter->getMaxUIDLength(),
7772+
joinsCollectionsIds: $this->joinsCollectionsIds,
77677773
);
77687774
if (!$validator->isValid($queries)) {
77697775
throw new QueryException($validator->getDescription());
@@ -8017,7 +8023,8 @@ public function count(string $collection, array $queries = [], ?int $max = null)
80178023
minAllowedDate: $this->adapter->getMinDateTime(),
80188024
maxAllowedDate: $this->adapter->getMaxDateTime(),
80198025
supportForAttributes: $this->adapter->getSupportForAttributes(),
8020-
maxUIDLength: $this->adapter->getMaxUIDLength()
8026+
maxUIDLength: $this->adapter->getMaxUIDLength(),
8027+
joinsCollectionsIds: $this->joinsCollectionsIds,
80218028
);
80228029
if (!$validator->isValid($queries)) {
80238030
throw new QueryException($validator->getDescription());
@@ -8082,7 +8089,8 @@ public function sum(string $collection, string $attribute, array $queries = [],
80828089
minAllowedDate: $this->adapter->getMinDateTime(),
80838090
maxAllowedDate: $this->adapter->getMaxDateTime(),
80848091
supportForAttributes: $this->adapter->getSupportForAttributes(),
8085-
maxUIDLength: $this->adapter->getMaxUIDLength()
8092+
maxUIDLength: $this->adapter->getMaxUIDLength(),
8093+
joinsCollectionsIds: $this->joinsCollectionsIds,
80868094
);
80878095
if (!$validator->isValid($queries)) {
80888096
throw new QueryException($validator->getDescription());
@@ -9428,4 +9436,15 @@ private function rollbackAttributeMetadata(Document $collection, array $attribut
94289436
);
94299437
$collection->setAttribute('attributes', \array_values($filteredAttributes));
94309438
}
9439+
9440+
/**
9441+
* Add Join Collection
9442+
*
9443+
* @param string $collectionId
9444+
* @return void
9445+
*/
9446+
public function addJoinCollection(string $collectionId): void
9447+
{
9448+
$this->joinsCollectionsIds[$collectionId] = true;
9449+
}
94319450
}

src/Database/Validator/Queries/V2.php

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ public function __construct(
6363
int $maxLimit = PHP_INT_MAX,
6464
int $maxOffset = PHP_INT_MAX,
6565
protected bool $supportForAttributes = true,
66-
protected int $maxUIDLength = Database::MAX_UID_DEFAULT_LENGTH
66+
protected int $maxUIDLength = Database::MAX_UID_DEFAULT_LENGTH,
67+
protected array $joinsCollectionsIds = []
6768
) {
6869
$this->context = $context;
6970
$this->idAttributeType = $idAttributeType;
@@ -304,6 +305,10 @@ public function isValid($value, string $scope = ''): bool
304305
case Query::TYPE_INNER_JOIN:
305306
case Query::TYPE_LEFT_JOIN:
306307
case Query::TYPE_RIGHT_JOIN:
308+
if (($this->joinsCollectionsIds[$query->getCollection()] ?? false) !== true) {
309+
throw new \Exception('Invalid query: Cannot ' . ucfirst($method) . ' this table.');
310+
}
311+
307312
$this->joinsAliasOrder[] = $query->getAlias();
308313

309314
$this->validateFilterQueries($query);
@@ -481,14 +486,18 @@ protected function validateAttributeExist(string $attributeId, string $alias, st
481486
*/
482487
protected function validateAlias(Query $query): void
483488
{
484-
$validator = new AliasValidator();
485-
486-
if (! $validator->isValid($query->getAlias())) {
487-
throw new \Exception('Query '.\ucfirst($query->getMethod()).': '.$validator->getDescription());
489+
if ($query->getAlias() !== '') {
490+
$validator = new AliasValidator();
491+
if (! $validator->isValid($query->getAlias())) {
492+
throw new \Exception('Query '.\ucfirst($query->getMethod()).': '.$validator->getDescription());
493+
}
488494
}
489495

490-
if (! $validator->isValid($query->getRightAlias())) {
491-
throw new \Exception('Query '.\ucfirst($query->getMethod()).': '.$validator->getDescription());
496+
if ($query->getRightAlias() !== '') {
497+
$validator = new AliasValidator();
498+
if (! $validator->isValid($query->getRightAlias())) {
499+
throw new \Exception('Query '.\ucfirst($query->getMethod()).': '.$validator->getDescription());
500+
}
492501
}
493502
}
494503

tests/e2e/Adapter/Scopes/JoinsTests.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,23 @@ public function testJoin(): void
8080
'$permissions' => [],
8181
]));
8282

83+
/**
84+
* Test collection not whitelist
85+
*/
86+
try {
87+
$database->find('__users', [
88+
Query::join('__sessions', 'B', [])
89+
]);
90+
$this->fail('Failed to throw exception');
91+
} catch (\Throwable $e) {
92+
$this->assertTrue($e instanceof QueryException);
93+
$this->assertEquals('Invalid query: Cannot InnerJoin this table.', $e->getMessage());
94+
}
95+
96+
$database->addJoinCollection('__users');
97+
$database->addJoinCollection('__sessions');
98+
$database->addJoinCollection('__banks');
99+
83100
/**
84101
* Test $session1 does not have read permissions
85102
* Test right attribute is internal attribute

0 commit comments

Comments
 (0)