mirror of
https://github.com/appwrite/appwrite
synced 2026-05-22 00:18:25 +00:00
Throw appropriate 400s from request filters
This commit is contained in:
parent
64bb1efc44
commit
081e2aeb6e
3 changed files with 59 additions and 32 deletions
|
|
@ -11,8 +11,6 @@ class V16 extends Filter
|
|||
{
|
||||
switch ($model) {
|
||||
case 'functions.create':
|
||||
$content['commands'] = $this->getCommands($content['runtime'] ?? '');
|
||||
break;
|
||||
case 'functions.update':
|
||||
$content['commands'] = $this->getCommands($content['runtime'] ?? '');
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Appwrite\Utopia\Request\Filters;
|
||||
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Utopia\Request\Filter;
|
||||
use Utopia\Database\Query;
|
||||
|
||||
|
|
@ -67,9 +68,9 @@ class V17 extends Filter
|
|||
foreach ($content['queries'] as $query) {
|
||||
try {
|
||||
$query = $this->parseQuery($query);
|
||||
$parsed[] = json_encode(array_filter($query->toArray()));
|
||||
$parsed[] = \json_encode(\array_filter($query->toArray()));
|
||||
} catch (\Throwable $th) {
|
||||
throw new \Exception("Invalid query: {$query}", previous: $th);
|
||||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $th->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -83,6 +84,7 @@ class V17 extends Filter
|
|||
{
|
||||
// Init empty vars we fill later
|
||||
$method = '';
|
||||
$attribute = null;
|
||||
$params = [];
|
||||
|
||||
// Separate method from filter
|
||||
|
|
@ -92,7 +94,7 @@ class V17 extends Filter
|
|||
throw new \Exception('Invalid query');
|
||||
}
|
||||
|
||||
$method = mb_substr($filter, 0, $paramsStart);
|
||||
$method = \mb_substr($filter, 0, $paramsStart);
|
||||
|
||||
// Separate params from filter
|
||||
$paramsEnd = \strlen($filter) - 1; // -1 to ignore )
|
||||
|
|
@ -103,14 +105,13 @@ class V17 extends Filter
|
|||
throw new \Exception('Invalid query method');
|
||||
}
|
||||
|
||||
$currentParam = ""; // We build param here before pushing when it's ended
|
||||
$currentParam = ''; // We build param here before pushing when it's ended
|
||||
$currentArrayParam = []; // We build array param here before pushing when it's ended
|
||||
|
||||
$stack = []; // State for stack of parentheses
|
||||
$stackCount = 0; // Length of stack array. Kept as variable to improve performance
|
||||
$stringStackState = null; // State for string support
|
||||
|
||||
|
||||
// Loop thorough all characters
|
||||
for ($i = $parametersStart; $i < $paramsEnd; $i++) {
|
||||
$char = $filter[$i];
|
||||
|
|
@ -135,20 +136,25 @@ class V17 extends Filter
|
|||
($filter[$i - 1] !== static::CHAR_BACKSLASH || $filter[$i - 2] === static::CHAR_BACKSLASH) // Must not be escaped;
|
||||
) {
|
||||
if ($isStringStack) {
|
||||
// Dont mix-up string symbols. Only allow the same as on start
|
||||
// Don't mix up string symbols. Only allow the same as on start
|
||||
if ($char === $stringStackState) {
|
||||
// End of string
|
||||
$stringStackState = null;
|
||||
}
|
||||
|
||||
// Either way, add symbol to builder
|
||||
static::appendSymbol($isStringStack, $char, $i, $filter, $currentParam);
|
||||
} else {
|
||||
// Start of string
|
||||
$stringStackState = $char;
|
||||
static::appendSymbol($isStringStack, $char, $i, $filter, $currentParam);
|
||||
}
|
||||
|
||||
// Either way, add symbol to builder
|
||||
static::appendSymbol(
|
||||
$isStringStack,
|
||||
$char,
|
||||
$i,
|
||||
$filter,
|
||||
$currentParam,
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -174,12 +180,12 @@ class V17 extends Filter
|
|||
|
||||
continue;
|
||||
} elseif ($char === static::CHAR_COMMA) { // Params separation support
|
||||
// If in array stack, dont merge yet, just mark it in array param builder
|
||||
// If in array stack, don't merge yet, just mark it in array param builder
|
||||
if ($isArrayStack) {
|
||||
$currentArrayParam[] = $currentParam;
|
||||
$currentParam = "";
|
||||
} else {
|
||||
// Append from parap builder. Either value, or array
|
||||
// Append from param builder. Either value, or array
|
||||
if (empty($currentArrayParam)) {
|
||||
if (strlen($currentParam)) {
|
||||
$params[] = $currentParam;
|
||||
|
|
@ -193,23 +199,28 @@ class V17 extends Filter
|
|||
}
|
||||
|
||||
// Value, not relevant to syntax
|
||||
static::appendSymbol($isStringStack, $char, $i, $filter, $currentParam);
|
||||
static::appendSymbol(
|
||||
$isStringStack,
|
||||
$char,
|
||||
$i,
|
||||
$filter,
|
||||
$currentParam,
|
||||
);
|
||||
}
|
||||
|
||||
if (strlen($currentParam)) {
|
||||
if (\strlen($currentParam)) {
|
||||
$params[] = $currentParam;
|
||||
$currentParam = "";
|
||||
$currentParam = '';
|
||||
}
|
||||
|
||||
$parsedParams = [];
|
||||
|
||||
foreach ($params as $param) {
|
||||
// If array, parse each child separatelly
|
||||
// If array, parse each child separately
|
||||
if (\is_array($param)) {
|
||||
foreach ($param as $element) {
|
||||
$arr[] = self::parseValue($element);
|
||||
}
|
||||
|
||||
$parsedParams[] = $arr ?? [];
|
||||
} else {
|
||||
$parsedParams[] = self::parseValue($param);
|
||||
|
|
@ -295,8 +306,13 @@ class V17 extends Filter
|
|||
* @param string $currentParam
|
||||
* @return void
|
||||
*/
|
||||
private function appendSymbol(bool $isStringStack, string $char, int $index, string $filter, string &$currentParam): void
|
||||
{
|
||||
private function appendSymbol(
|
||||
bool $isStringStack,
|
||||
string $char,
|
||||
int $index,
|
||||
string $filter,
|
||||
string &$currentParam
|
||||
): void {
|
||||
// Ignore spaces and commas outside of string
|
||||
$canBeIgnored = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
|
||||
namespace Appwrite\Utopia\Request\Filters;
|
||||
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Utopia\Request\Filter;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Exception\NotFound;
|
||||
use Utopia\Database\Exception\Query as QueryException;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
|
|
@ -54,8 +56,8 @@ class V20 extends Filter
|
|||
|
||||
try {
|
||||
$parsed = Query::parseQueries($content['queries']);
|
||||
} catch (QueryException) {
|
||||
return $content;
|
||||
} catch (QueryException $e) {
|
||||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
|
||||
}
|
||||
|
||||
$selections = Query::groupByType($parsed)['selections'] ?? [];
|
||||
|
|
@ -136,17 +138,28 @@ class V20 extends Filter
|
|||
return [];
|
||||
}
|
||||
|
||||
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
|
||||
if ($database->isEmpty()) {
|
||||
return [];
|
||||
try {
|
||||
$database = Authorization::skip(fn() => $dbForProject->getDocument(
|
||||
'databases',
|
||||
$databaseId
|
||||
));
|
||||
if ($database->isEmpty()) {
|
||||
return [];
|
||||
}
|
||||
} catch (NotFound) {
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = Authorization::skip(fn () => $dbForProject->getDocument(
|
||||
'database_' . $database->getSequence(),
|
||||
$collectionId
|
||||
));
|
||||
if ($collection->isEmpty()) {
|
||||
return [];
|
||||
try {
|
||||
$collection = Authorization::skip(fn() => $dbForProject->getDocument(
|
||||
'database_' . $database->getSequence(),
|
||||
$collectionId
|
||||
));
|
||||
if ($collection->isEmpty()) {
|
||||
return [];
|
||||
}
|
||||
} catch (NotFound) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$attributes = $collection->getAttribute('attributes', []);
|
||||
|
|
|
|||
Loading…
Reference in a new issue